]> source.dussan.org Git - nextcloud-server.git/commitdiff
enh(contacts): show/hide addressbooks for all 38397/head
authorJohannes Merkel <mail@johannesgge.de>
Mon, 22 May 2023 13:25:16 +0000 (15:25 +0200)
committerJohannes <74607597+JohannesGGE@users.noreply.github.com>
Mon, 10 Jul 2023 11:39:15 +0000 (13:39 +0200)
Signed-off-by: Johannes Merkel <mail@johannesgge.de>
apps/dav/lib/CardDAV/AddressBook.php
apps/dav/lib/DAV/CustomPropertiesBackend.php
apps/dav/tests/unit/CardDAV/AddressBookTest.php

index e9eec4161cb81e0a554253d7a2427c9ac9083638..b0fb8c8ee5c4b1bc17584cd76a9aeda558448c51 100644 (file)
@@ -46,7 +46,6 @@ use Sabre\DAV\PropPatch;
  * @property CardDavBackend $carddavBackend
  */
 class AddressBook extends \Sabre\CardDAV\AddressBook implements IShareable, IMoveTarget {
-
        /**
         * AddressBook constructor.
         *
@@ -116,7 +115,12 @@ class AddressBook extends \Sabre\CardDAV\AddressBook implements IShareable, IMov
                                'privilege' => '{DAV:}write',
                                'principal' => $this->getOwner(),
                                'protected' => true,
-                       ]
+                       ],
+                       [
+                               'privilege' => '{DAV:}write-properties',
+                               'principal' => '{DAV:}authenticated',
+                               'protected' => true,
+                       ],
                ];
 
                if ($this->getOwner() === 'principals/system/system') {
@@ -147,7 +151,7 @@ class AddressBook extends \Sabre\CardDAV\AddressBook implements IShareable, IMov
                }
 
                $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);
                });
@@ -166,8 +170,7 @@ class AddressBook extends \Sabre\CardDAV\AddressBook implements IShareable, IMov
                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) {
@@ -178,8 +181,7 @@ class AddressBook extends \Sabre\CardDAV\AddressBook implements IShareable, IMov
                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) {
@@ -221,10 +223,12 @@ class AddressBook extends \Sabre\CardDAV\AddressBook implements IShareable, IMov
        }
 
        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() {
index 3bc3ba33173a0df07e3653f51b0c27e84f614fd9..9de06334611aae296131bf6d15ee70f3d6ff29bc 100644 (file)
@@ -176,6 +176,21 @@ class CustomPropertiesBackend implements BackendInterface {
                        }
                }
 
+               // 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;
                }
index 81361d02068ee4245cb036b4c93af28bcfc1dce7..9aa7eb14fff13dcbb2248c6af1c43daae1c6fe03 100644 (file)
@@ -29,6 +29,7 @@ namespace OCA\DAV\Tests\unit\CardDAV;
 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;
@@ -101,11 +102,10 @@ class AddressBookTest extends TestCase {
        }
 
 
-       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',
@@ -116,7 +116,24 @@ class AddressBookTest extends TestCase {
                $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']));
        }
 
        /**
@@ -152,6 +169,10 @@ class AddressBookTest extends TestCase {
                        'privilege' => '{DAV:}write',
                        'principal' => $hasOwnerSet ? 'user1' : 'user2',
                        'protected' => true
+               ], [
+                       'privilege' => '{DAV:}write-properties',
+                       'principal' => '{DAV:}authenticated',
+                       'protected' => true
                ]];
                if ($hasOwnerSet) {
                        $expectedAcl[] = [