Skip to content

Commit

Permalink
enh(contacts): show/hide addressbooks for all
Browse files Browse the repository at this point in the history
Signed-off-by: Johannes Merkel <[email protected]>
  • Loading branch information
JohannesGGE authored and backportbot-nextcloud[bot] committed Aug 16, 2023
1 parent 5af9b6c commit 8dae579
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 14 deletions.
24 changes: 14 additions & 10 deletions apps/dav/lib/CardDAV/AddressBook.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@
* @property CardDavBackend $carddavBackend
*/
class AddressBook extends \Sabre\CardDAV\AddressBook implements IShareable, IMoveTarget {

/**
* AddressBook constructor.
*
Expand Down Expand Up @@ -116,7 +115,12 @@ public function getACL() {
'privilege' => '{DAV:}write',
'principal' => $this->getOwner(),
'protected' => true,
]
],
[
'privilege' => '{DAV:}write-properties',
'principal' => '{DAV:}authenticated',
'protected' => true,
],
];

if ($this->getOwner() === 'principals/system/system') {
Expand Down Expand Up @@ -147,7 +151,7 @@ public function getACL() {
}

$acl = $this->carddavBackend->applyShareAcl($this->getResourceId(), $acl);
$allowedPrincipals = [$this->getOwner(), parent::getOwner(), 'principals/system/system'];
$allowedPrincipals = [$this->getOwner(), parent::getOwner(), 'principals/system/system', '{DAV:}authenticated'];
return array_filter($acl, function ($rule) use ($allowedPrincipals) {
return \in_array($rule['principal'], $allowedPrincipals, true);
});
Expand All @@ -166,8 +170,7 @@ public function getChild($name) {
return new Card($this->carddavBackend, $this->addressBookInfo, $obj);
}

public function getChildren()
{
public function getChildren() {
$objs = $this->carddavBackend->getCards($this->addressBookInfo['id']);
$children = [];
foreach ($objs as $obj) {
Expand All @@ -178,8 +181,7 @@ public function getChildren()
return $children;
}

public function getMultipleChildren(array $paths)
{
public function getMultipleChildren(array $paths) {
$objs = $this->carddavBackend->getMultipleCards($this->addressBookInfo['id'], $paths);
$children = [];
foreach ($objs as $obj) {
Expand Down Expand Up @@ -221,10 +223,12 @@ public function delete() {
}

public function propPatch(PropPatch $propPatch) {
if (isset($this->addressBookInfo['{http://owncloud.org/ns}owner-principal'])) {
throw new Forbidden();
// shared address books will be handled by
// \OCA\DAV\DAV\CustomPropertiesBackend::propPatch
// to save values in db table instead of dav object
if (!$this->isShared()) {
parent::propPatch($propPatch);
}
parent::propPatch($propPatch);
}

public function getContactsGroups() {
Expand Down
15 changes: 15 additions & 0 deletions apps/dav/lib/DAV/CustomPropertiesBackend.php
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,21 @@ public function propFind($path, PropFind $propFind) {
}
}

// substr of addressbooks/ => path is inside the CardDAV component
// three '/' => this a addressbook (no addressbook-home nor contact object)
if (str_starts_with($path, 'addressbooks/') && substr_count($path, '/') === 3) {
$allRequestedProps = $propFind->getRequestedProperties();
$customPropertiesForShares = [
'{DAV:}displayname',
];

foreach ($customPropertiesForShares as $customPropertyForShares) {
if (in_array($customPropertyForShares, $allRequestedProps, true)) {
$requestedProps[] = $customPropertyForShares;
}
}
}

if (empty($requestedProps)) {
return;
}
Expand Down
29 changes: 25 additions & 4 deletions apps/dav/tests/unit/CardDAV/AddressBookTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
use OCA\DAV\CardDAV\AddressBook;
use OCA\DAV\CardDAV\Card;
use OCA\DAV\CardDAV\CardDavBackend;
use OCA\DAV\DAV\CustomPropertiesBackend;
use OCP\IL10N;
use PHPUnit\Framework\MockObject\MockObject;
use Psr\Log\LoggerInterface;
Expand Down Expand Up @@ -101,11 +102,10 @@ public function testDeleteFromGroup(): void {
}


public function testPropPatch(): void {
$this->expectException(Forbidden::class);

public function testPropPatchShared(): void {
/** @var MockObject | CardDavBackend $backend */
$backend = $this->getMockBuilder(CardDavBackend::class)->disableOriginalConstructor()->getMock();
$backend->expects($this->never())->method('updateAddressBook');
$addressBookInfo = [
'{http://owncloud.org/ns}owner-principal' => 'user1',
'{DAV:}displayname' => 'Test address book',
Expand All @@ -116,7 +116,24 @@ public function testPropPatch(): void {
$l10n = $this->createMock(IL10N::class);
$logger = $this->createMock(LoggerInterface::class);
$addressBook = new AddressBook($backend, $addressBookInfo, $l10n, $logger);
$addressBook->propPatch(new PropPatch([]));
$addressBook->propPatch(new PropPatch(['{DAV:}displayname' => 'Test address book']));
}

public function testPropPatchNotShared(): void {
/** @var MockObject | CardDavBackend $backend */
$backend = $this->getMockBuilder(CardDavBackend::class)->disableOriginalConstructor()->getMock();
$backend->expects($this->atLeast(1))->method('updateAddressBook');
$addressBookInfo = [
'{http://owncloud.org/ns}owner-principal' => 'user1',
'{DAV:}displayname' => 'Test address book',
'principaluri' => 'user1',
'id' => 666,
'uri' => 'default',
];
$l10n = $this->createMock(IL10N::class);
$logger = $this->createMock(LoggerInterface::class);
$addressBook = new AddressBook($backend, $addressBookInfo, $l10n, $logger);
$addressBook->propPatch(new PropPatch(['{DAV:}displayname' => 'Test address book']));
}

/**
Expand Down Expand Up @@ -152,6 +169,10 @@ public function testAcl($expectsWrite, $readOnlyValue, $hasOwnerSet): void {
'privilege' => '{DAV:}write',
'principal' => $hasOwnerSet ? 'user1' : 'user2',
'protected' => true
], [
'privilege' => '{DAV:}write-properties',
'principal' => '{DAV:}authenticated',
'protected' => true
]];
if ($hasOwnerSet) {
$expectedAcl[] = [
Expand Down

0 comments on commit 8dae579

Please sign in to comment.