]> source.dussan.org Git - nextcloud-server.git/commitdiff
Add typing to Sharing Backend 32884/head
authorCarl Schwan <carl@carlschwan.eu>
Tue, 14 Jun 2022 13:26:15 +0000 (15:26 +0200)
committerCarl Schwan <carl@carlschwan.eu>
Wed, 22 Jun 2022 08:25:17 +0000 (10:25 +0200)
Signed-off-by: Carl Schwan <carl@carlschwan.eu>
apps/dav/lib/CalDAV/CalDavBackend.php
apps/dav/lib/CalDAV/Calendar.php
apps/dav/lib/CardDAV/AddressBook.php
apps/dav/lib/CardDAV/CardDavBackend.php
apps/dav/lib/Command/MoveCalendar.php
apps/dav/lib/DAV/Sharing/Backend.php
apps/dav/lib/DAV/Sharing/IShareable.php
apps/dav/lib/Events/CalendarShareUpdatedEvent.php
apps/dav/tests/unit/BackgroundJob/CleanupInvitationTokenJobTest.php
apps/dav/tests/unit/Controller/InvitationResponseControllerTest.php
build/psalm-baseline.xml

index 3ab047d5183831d5b9c110bb2131eee2787aeec2..7e13b3ba8fdf57f5719b2af3e86a298c6cf0c38c 100644 (file)
@@ -674,10 +674,9 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
        }
 
        /**
-        * @param $calendarId
-        * @return array|null
+        * @return array{id: int, uri: string, '{http://calendarserver.org/ns/}getctag': string, '{http://sabredav.org/ns}sync-token': int, '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set': SupportedCalendarComponentSet, '{urn:ietf:params:xml:ns:caldav}schedule-calendar-transp': ScheduleCalendarTransp }|null
         */
-       public function getCalendarById($calendarId) {
+       public function getCalendarById(int $calendarId): ?array {
                $fields = array_column($this->propertyMap, 0);
                $fields[] = 'id';
                $fields[] = 'uri';
@@ -710,7 +709,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
                        'uri' => $row['uri'],
                        'principaluri' => $this->convertPrincipal($row['principaluri'], !$this->legacyEndpoint),
                        '{' . Plugin::NS_CALENDARSERVER . '}getctag' => 'http://sabre.io/ns/sync/' . ($row['synctoken']?$row['synctoken']:'0'),
-                       '{http://sabredav.org/ns}sync-token' => $row['synctoken']?$row['synctoken']:'0',
+                       '{http://sabredav.org/ns}sync-token' => $row['synctoken'] ?? 0,
                        '{' . Plugin::NS_CALDAV . '}supported-calendar-component-set' => new SupportedCalendarComponentSet($components),
                        '{' . Plugin::NS_CALDAV . '}schedule-calendar-transp' => new ScheduleCalendarTransp($row['transparent']?'transparent':'opaque'),
                ];
@@ -866,7 +865,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
 
                        $calendarData = $this->getCalendarById($calendarId);
                        $shares = $this->getShares($calendarId);
-                       $this->dispatcher->dispatchTyped(new CalendarUpdatedEvent((int)$calendarId, $calendarData, $shares, $mutations));
+                       $this->dispatcher->dispatchTyped(new CalendarUpdatedEvent($calendarId, $calendarData, $shares, $mutations));
 
                        return true;
                });
@@ -916,7 +915,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
 
                        // Only dispatch if we actually deleted anything
                        if ($calendarData) {
-                               $this->dispatcher->dispatchTyped(new CalendarDeletedEvent((int)$calendarId, $calendarData, $shares));
+                               $this->dispatcher->dispatchTyped(new CalendarDeletedEvent($calendarId, $calendarData, $shares));
                        }
                } else {
                        $qbMarkCalendarDeleted = $this->db->getQueryBuilder();
@@ -929,7 +928,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
                        $shares = $this->getShares($calendarId);
                        if ($calendarData) {
                                $this->dispatcher->dispatchTyped(new CalendarMovedToTrashEvent(
-                                       (int)$calendarId,
+                                       $calendarId,
                                        $calendarData,
                                        $shares
                                ));
@@ -1265,15 +1264,17 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
                $this->addChange($calendarId, $objectUri, 1, $calendarType);
 
                $objectRow = $this->getCalendarObject($calendarId, $objectUri, $calendarType);
+               assert($objectRow !== null);
+
                if ($calendarType === self::CALENDAR_TYPE_CALENDAR) {
                        $calendarRow = $this->getCalendarById($calendarId);
                        $shares = $this->getShares($calendarId);
 
-                       $this->dispatcher->dispatchTyped(new CalendarObjectCreatedEvent((int)$calendarId, $calendarRow, $shares, $objectRow));
+                       $this->dispatcher->dispatchTyped(new CalendarObjectCreatedEvent($calendarId, $calendarRow, $shares, $objectRow));
                } else {
                        $subscriptionRow = $this->getSubscriptionById($calendarId);
 
-                       $this->dispatcher->dispatchTyped(new CachedCalendarObjectCreatedEvent((int)$calendarId, $subscriptionRow, [], $objectRow));
+                       $this->dispatcher->dispatchTyped(new CachedCalendarObjectCreatedEvent($calendarId, $subscriptionRow, [], $objectRow));
                }
 
                return '"' . $extraData['etag'] . '"';
@@ -1325,11 +1326,11 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
                                $calendarRow = $this->getCalendarById($calendarId);
                                $shares = $this->getShares($calendarId);
 
-                               $this->dispatcher->dispatchTyped(new CalendarObjectUpdatedEvent((int)$calendarId, $calendarRow, $shares, $objectRow));
+                               $this->dispatcher->dispatchTyped(new CalendarObjectUpdatedEvent($calendarId, $calendarRow, $shares, $objectRow));
                        } else {
                                $subscriptionRow = $this->getSubscriptionById($calendarId);
 
-                               $this->dispatcher->dispatchTyped(new CachedCalendarObjectUpdatedEvent((int)$calendarId, $subscriptionRow, [], $objectRow));
+                               $this->dispatcher->dispatchTyped(new CachedCalendarObjectUpdatedEvent($calendarId, $subscriptionRow, [], $objectRow));
                        }
                }
 
@@ -1435,11 +1436,11 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
                                $calendarRow = $this->getCalendarById($calendarId);
                                $shares = $this->getShares($calendarId);
 
-                               $this->dispatcher->dispatchTyped(new CalendarObjectDeletedEvent((int)$calendarId, $calendarRow, $shares, $data));
+                               $this->dispatcher->dispatchTyped(new CalendarObjectDeletedEvent($calendarId, $calendarRow, $shares, $data));
                        } else {
                                $subscriptionRow = $this->getSubscriptionById($calendarId);
 
-                               $this->dispatcher->dispatchTyped(new CachedCalendarObjectDeletedEvent((int)$calendarId, $subscriptionRow, [], $data));
+                               $this->dispatcher->dispatchTyped(new CachedCalendarObjectDeletedEvent($calendarId, $subscriptionRow, [], $data));
                        }
                } else {
                        $pathInfo = pathinfo($data['uri']);
@@ -1479,7 +1480,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
                        if ($calendarData !== null) {
                                $this->dispatcher->dispatchTyped(
                                        new CalendarObjectMovedToTrashEvent(
-                                               (int)$calendarId,
+                                               $calendarId,
                                                $calendarData,
                                                $this->getShares($calendarId),
                                                $data
@@ -2799,25 +2800,26 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
        }
 
        /**
-        * @param IShareable $shareable
-        * @param array $add
-        * @param array $remove
+        * @param list<array{href: string, commonName: string, readOnly: bool}> $add
+        * @param list<string> $remove
         */
-       public function updateShares($shareable, $add, $remove) {
+       public function updateShares(IShareable $shareable, array $add, array $remove): void {
                $calendarId = $shareable->getResourceId();
                $calendarRow = $this->getCalendarById($calendarId);
+               if ($calendarRow === null) {
+                       throw new \RuntimeException('Trying to update shares for innexistant calendar: ' . $calendarId);
+               }
                $oldShares = $this->getShares($calendarId);
 
                $this->calendarSharingBackend->updateShares($shareable, $add, $remove);
 
-               $this->dispatcher->dispatchTyped(new CalendarShareUpdatedEvent((int)$calendarId, $calendarRow, $oldShares, $add, $remove));
+               $this->dispatcher->dispatchTyped(new CalendarShareUpdatedEvent($calendarId, $calendarRow, $oldShares, $add, $remove));
        }
 
        /**
-        * @param int $resourceId
-        * @return array
+        * @return list<array{href: string, commonName: string, status: int, readOnly: bool, '{http://owncloud.org/ns}principal': string, '{http://owncloud.org/ns}group-share': bool}>
         */
-       public function getShares($resourceId) {
+       public function getShares(int $resourceId): array {
                return $this->calendarSharingBackend->getShares($resourceId);
        }
 
@@ -2843,7 +2845,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
                                ]);
                        $query->executeStatement();
 
-                       $this->dispatcher->dispatchTyped(new CalendarPublishedEvent((int)$calendarId, $calendarData, $publicUri));
+                       $this->dispatcher->dispatchTyped(new CalendarPublishedEvent($calendarId, $calendarData, $publicUri));
                        return $publicUri;
                }
                $query->delete('dav_shares')
@@ -2851,7 +2853,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
                        ->andWhere($query->expr()->eq('access', $query->createNamedParameter(self::ACCESS_PUBLIC)));
                $query->executeStatement();
 
-               $this->dispatcher->dispatchTyped(new CalendarUnpublishedEvent((int)$calendarId, $calendarData));
+               $this->dispatcher->dispatchTyped(new CalendarUnpublishedEvent($calendarId, $calendarData));
                return null;
        }
 
@@ -2874,15 +2876,13 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription
 
        /**
         * @param int $resourceId
-        * @param array $acl
-        * @return array
+        * @param list<array{privilege: string, principal: string, protected: bool}> $acl
+        * @return list<array{privilege: string, principal: string, protected: bool}>
         */
-       public function applyShareAcl($resourceId, $acl) {
+       public function applyShareAcl(int $resourceId, array $acl): array {
                return $this->calendarSharingBackend->applyShareAcl($resourceId, $acl);
        }
 
-
-
        /**
         * update properties table
         *
index 806e99d8a05eabc33d62f2b5a9e48c5acb42ec87..92ad3242d783e09cc9a69c92d70b0523c6290c8b 100644 (file)
@@ -51,27 +51,11 @@ use Sabre\DAV\PropPatch;
  * @property CalDavBackend $caldavBackend
  */
 class Calendar extends \Sabre\CalDAV\Calendar implements IRestorable, IShareable, IMoveTarget {
+       private IConfig $config;
+       protected IL10N $l10n;
+       private bool $useTrashbin = true;
+       private LoggerInterface $logger;
 
-       /** @var IConfig */
-       private $config;
-
-       /** @var IL10N */
-       protected $l10n;
-
-       /** @var bool */
-       private $useTrashbin = true;
-
-       /** @var LoggerInterface */
-       private $logger;
-
-       /**
-        * Calendar constructor.
-        *
-        * @param BackendInterface $caldavBackend
-        * @param $calendarInfo
-        * @param IL10N $l10n
-        * @param IConfig $config
-        */
        public function __construct(BackendInterface $caldavBackend, $calendarInfo, IL10N $l10n, IConfig $config, LoggerInterface $logger) {
                // Convert deletion date to ISO8601 string
                if (isset($calendarInfo[TrashbinPlugin::PROPERTY_DELETED_AT])) {
@@ -96,25 +80,10 @@ class Calendar extends \Sabre\CalDAV\Calendar implements IRestorable, IShareable
        }
 
        /**
-        * Updates the list of shares.
-        *
-        * The first array is a list of people that are to be added to the
-        * resource.
-        *
-        * Every element in the add array has the following properties:
-        *   * href - A url. Usually a mailto: address
-        *   * commonName - Usually a first and last name, or false
-        *   * summary - A description of the share, can also be false
-        *   * readOnly - A boolean value
-        *
-        * Every element in the remove array is just the address string.
-        *
-        * @param array $add
-        * @param array $remove
-        * @return void
+        * {@inheritdoc}
         * @throws Forbidden
         */
-       public function updateShares(array $add, array $remove) {
+       public function updateShares(array $add, array $remove): void {
                if ($this->isShared()) {
                        throw new Forbidden();
                }
@@ -131,19 +100,16 @@ class Calendar extends \Sabre\CalDAV\Calendar implements IRestorable, IShareable
         *   * readOnly - boolean
         *   * summary - Optional, a description for the share
         *
-        * @return array
+        * @return list<array{href: string, commonName: string, status: int, readOnly: bool, '{http://owncloud.org/ns}principal': string, '{http://owncloud.org/ns}group-share': bool}>
         */
-       public function getShares() {
+       public function getShares(): array {
                if ($this->isShared()) {
                        return [];
                }
                return $this->caldavBackend->getShares($this->getResourceId());
        }
 
-       /**
-        * @return int
-        */
-       public function getResourceId() {
+       public function getResourceId(): int {
                return $this->calendarInfo['id'];
        }
 
@@ -155,7 +121,9 @@ class Calendar extends \Sabre\CalDAV\Calendar implements IRestorable, IShareable
        }
 
        /**
-        * @return array
+        * @param int $resourceId
+        * @param list<array{privilege: string, principal: string, protected: bool}> $acl
+        * @return list<array{privilege: string, principal: ?string, protected: bool}>
         */
        public function getACL() {
                $acl = [
@@ -246,16 +214,18 @@ class Calendar extends \Sabre\CalDAV\Calendar implements IRestorable, IShareable
                        parent::getOwner(),
                        'principals/system/public'
                ];
-               return array_filter($acl, function ($rule) use ($allowedPrincipals) {
+               /** @var list<array{privilege: string, principal: string, protected: bool}> $acl */
+               $acl = array_filter($acl, function (array $rule) use ($allowedPrincipals): bool {
                        return \in_array($rule['principal'], $allowedPrincipals, true);
                });
+               return $acl;
        }
 
        public function getChildACL() {
                return $this->getACL();
        }
 
-       public function getOwner() {
+       public function getOwner(): ?string {
                if (isset($this->calendarInfo['{http://owncloud.org/ns}owner-principal'])) {
                        return $this->calendarInfo['{http://owncloud.org/ns}owner-principal'];
                }
index 9bd24bedbac62a683c6c7acb2f4b04a85edd0622..bca478feec12d2fd1f9a0b83812f31d7dd96e422 100644 (file)
@@ -67,17 +67,15 @@ class AddressBook extends \Sabre\CardDAV\AddressBook implements IShareable {
         * Every element in the add array has the following properties:
         *   * href - A url. Usually a mailto: address
         *   * commonName - Usually a first and last name, or false
-        *   * summary - A description of the share, can also be false
         *   * readOnly - A boolean value
         *
         * Every element in the remove array is just the address string.
         *
-        * @param array $add
-        * @param array $remove
-        * @return void
+        * @param list<array{href: string, commonName: string, readOnly: bool}> $add
+        * @param list<string> $remove
         * @throws Forbidden
         */
-       public function updateShares(array $add, array $remove) {
+       public function updateShares(array $add, array $remove): void {
                if ($this->isShared()) {
                        throw new Forbidden();
                }
@@ -92,11 +90,10 @@ class AddressBook extends \Sabre\CardDAV\AddressBook implements IShareable {
         *   * commonName - Optional, for example a first + last name
         *   * status - See the Sabre\CalDAV\SharingPlugin::STATUS_ constants.
         *   * readOnly - boolean
-        *   * summary - Optional, a description for the share
         *
-        * @return array
+        * @return list<array{href: string, commonName: string, status: int, readOnly: bool, '{http://owncloud.org/ns}principal': string, '{http://owncloud.org/ns}group-share': bool}>
         */
-       public function getShares() {
+       public function getShares(): array {
                if ($this->isShared()) {
                        return [];
                }
@@ -163,14 +160,11 @@ class AddressBook extends \Sabre\CardDAV\AddressBook implements IShareable {
                return new Card($this->carddavBackend, $this->addressBookInfo, $obj);
        }
 
-       /**
-        * @return int
-        */
-       public function getResourceId() {
+       public function getResourceId(): int {
                return $this->addressBookInfo['id'];
        }
 
-       public function getOwner() {
+       public function getOwner(): ?string {
                if (isset($this->addressBookInfo['{http://owncloud.org/ns}owner-principal'])) {
                        return $this->addressBookInfo['{http://owncloud.org/ns}owner-principal'];
                }
@@ -207,7 +201,7 @@ class AddressBook extends \Sabre\CardDAV\AddressBook implements IShareable {
                return $this->carddavBackend->collectCardProperties($this->getResourceId(), 'CATEGORIES');
        }
 
-       private function isShared() {
+       private function isShared(): bool {
                if (!isset($this->addressBookInfo['{http://owncloud.org/ns}owner-principal'])) {
                        return false;
                }
@@ -215,7 +209,7 @@ class AddressBook extends \Sabre\CardDAV\AddressBook implements IShareable {
                return $this->addressBookInfo['{http://owncloud.org/ns}owner-principal'] !== $this->addressBookInfo['principaluri'];
        }
 
-       private function canWrite() {
+       private function canWrite(): bool {
                if (isset($this->addressBookInfo['{http://owncloud.org/ns}read-only'])) {
                        return !$this->addressBookInfo['{http://owncloud.org/ns}read-only'];
                }
index 745ca7801b754541b95e70bf13f3ecb4b055f041..2c99e6084c1a28d0d58dd420c4a0b7880e857798 100644 (file)
@@ -371,12 +371,12 @@ class CardDavBackend implements BackendInterface, SyncSupport {
                                $query->set($key, $query->createNamedParameter($value));
                        }
                        $query->where($query->expr()->eq('id', $query->createNamedParameter($addressBookId)))
-                               ->execute();
+                               ->executeStatement();
 
                        $this->addChange($addressBookId, "", 2);
 
                        $addressBookRow = $this->getAddressBookById((int)$addressBookId);
-                       $shares = $this->getShares($addressBookId);
+                       $shares = $this->getShares((int)$addressBookId);
                        $this->dispatcher->dispatchTyped(new AddressBookUpdatedEvent((int)$addressBookId, $addressBookRow, $shares, $mutations));
 
                        return true;
@@ -446,30 +446,31 @@ class CardDavBackend implements BackendInterface, SyncSupport {
         * @return void
         */
        public function deleteAddressBook($addressBookId) {
+               $addressBookId = (int)$addressBookId;
                $addressBookData = $this->getAddressBookById($addressBookId);
                $shares = $this->getShares($addressBookId);
 
                $query = $this->db->getQueryBuilder();
                $query->delete($this->dbCardsTable)
                        ->where($query->expr()->eq('addressbookid', $query->createParameter('addressbookid')))
-                       ->setParameter('addressbookid', $addressBookId)
-                       ->execute();
+                       ->setParameter('addressbookid', $addressBookId, IQueryBuilder::PARAM_INT)
+                       ->executeStatement();
 
                $query->delete('addressbookchanges')
                        ->where($query->expr()->eq('addressbookid', $query->createParameter('addressbookid')))
-                       ->setParameter('addressbookid', $addressBookId)
-                       ->execute();
+                       ->setParameter('addressbookid', $addressBookId, IQueryBuilder::PARAM_INT)
+                       ->executeStatement();
 
                $query->delete('addressbooks')
                        ->where($query->expr()->eq('id', $query->createParameter('id')))
-                       ->setParameter('id', $addressBookId)
-                       ->execute();
+                       ->setParameter('id', $addressBookId, IQueryBuilder::PARAM_INT)
+                       ->executeStatement();
 
                $this->sharingBackend->deleteAllShares($addressBookId);
 
                $query->delete($this->dbCardsPropertiesTable)
-                       ->where($query->expr()->eq('addressbookid', $query->createNamedParameter($addressBookId)))
-                       ->execute();
+                       ->where($query->expr()->eq('addressbookid', $query->createNamedParameter($addressBookId, IQueryBuilder::PARAM_INT)))
+                       ->executeStatement();
 
                if ($addressBookData) {
                        $this->dispatcher->dispatchTyped(new AddressBookDeletedEvent($addressBookId, $addressBookData, $shares));
@@ -964,11 +965,10 @@ class CardDavBackend implements BackendInterface, SyncSupport {
        }
 
        /**
-        * @param IShareable $shareable
-        * @param string[] $add
-        * @param string[] $remove
+        * @param list<array{href: string, commonName: string, readOnly: bool}> $add
+        * @param list<string> $remove
         */
-       public function updateShares(IShareable $shareable, $add, $remove) {
+       public function updateShares(IShareable $shareable, array $add, array $remove): void {
                $addressBookId = $shareable->getResourceId();
                $addressBookData = $this->getAddressBookById($addressBookId);
                $oldShares = $this->getShares($addressBookId);
@@ -1199,11 +1199,10 @@ class CardDavBackend implements BackendInterface, SyncSupport {
         *   * commonName - Optional, for example a first + last name
         *   * status - See the Sabre\CalDAV\SharingPlugin::STATUS_ constants.
         *   * readOnly - boolean
-        *   * summary - Optional, a description for the share
         *
-        * @return array
+        * @return list<array{href: string, commonName: string, status: int, readOnly: bool, '{http://owncloud.org/ns}principal': string, '{http://owncloud.org/ns}group-share': bool}>
         */
-       public function getShares($addressBookId) {
+       public function getShares(int $addressBookId): array {
                return $this->sharingBackend->getShares($addressBookId);
        }
 
@@ -1283,13 +1282,9 @@ class CardDavBackend implements BackendInterface, SyncSupport {
        }
 
        /**
-        * get ID from a given contact
-        *
-        * @param int $addressBookId
-        * @param string $uri
-        * @return int
+        * Get ID from a given contact
         */
-       protected function getCardId($addressBookId, $uri) {
+       protected function getCardId(int $addressBookId, string $uri): int {
                $query = $this->db->getQueryBuilder();
                $query->select('id')->from($this->dbCardsTable)
                        ->where($query->expr()->eq('uri', $query->createNamedParameter($uri)))
@@ -1309,15 +1304,15 @@ class CardDavBackend implements BackendInterface, SyncSupport {
        /**
         * For shared address books the sharee is set in the ACL of the address book
         *
-        * @param $addressBookId
-        * @param $acl
-        * @return array
+        * @param int $addressBookId
+        * @param list<array{privilege: string, principal: string, protected: bool}> $acl
+        * @return list<array{privilege: string, principal: string, protected: bool}>
         */
-       public function applyShareAcl($addressBookId, $acl) {
+       public function applyShareAcl(int $addressBookId, array $acl): array {
                return $this->sharingBackend->applyShareAcl($addressBookId, $acl);
        }
 
-       private function convertPrincipal($principalUri, $toV2) {
+       private function convertPrincipal(string $principalUri, bool $toV2): string {
                if ($this->principalBackend->getPrincipalPrefix() === 'principals') {
                        [, $name] = \Sabre\Uri\split($principalUri);
                        if ($toV2 === true) {
@@ -1328,7 +1323,7 @@ class CardDavBackend implements BackendInterface, SyncSupport {
                return $principalUri;
        }
 
-       private function addOwnerPrincipal(&$addressbookInfo) {
+       private function addOwnerPrincipal(array &$addressbookInfo): void {
                $ownerPrincipalKey = '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_OWNCLOUD . '}owner-principal';
                $displaynameKey = '{' . \OCA\DAV\DAV\Sharing\Plugin::NS_NEXTCLOUD . '}owner-displayname';
                if (isset($addressbookInfo[$ownerPrincipalKey])) {
@@ -1348,10 +1343,10 @@ class CardDavBackend implements BackendInterface, SyncSupport {
         *
         * @param string $cardData the vcard raw data
         * @return string the uid
-        * @throws BadRequest if no UID is available
+        * @throws BadRequest if no UID is available or vcard is empty
         */
-       private function getUID($cardData) {
-               if ($cardData != '') {
+       private function getUID(string $cardData): string {
+               if ($cardData !== '') {
                        $vCard = Reader::read($cardData);
                        if ($vCard->UID) {
                                $uid = $vCard->UID->getValue();
index 320fe8aeac699024e93856dc142fc4af7fa303ff..9272b20b10dc39f34081521a55c65854b38d7b97 100644 (file)
@@ -42,41 +42,17 @@ use Symfony\Component\Console\Output\OutputInterface;
 use Symfony\Component\Console\Style\SymfonyStyle;
 
 class MoveCalendar extends Command {
-
-       /** @var IUserManager */
-       private $userManager;
-
-       /** @var IGroupManager */
-       private $groupManager;
-
-       /** @var IShareManager */
-       private $shareManager;
-
-       /** @var IConfig $config */
-       private $config;
-
-       /** @var IL10N */
-       private $l10n;
-
-       /** @var SymfonyStyle */
-       private $io;
-
-       /** @var CalDavBackend */
-       private $calDav;
-
-       /** @var LoggerInterface */
-       private $logger;
+       private IUserManager $userManager;
+       private IGroupManager $groupManager;
+       private IShareManager $shareManager;
+       private IConfig $config;
+       private IL10N $l10n;
+       private ?SymfonyStyle $io = null;
+       private CalDavBackend $calDav;
+       private LoggerInterface $logger;
 
        public const URI_USERS = 'principals/users/';
 
-       /**
-        * @param IUserManager $userManager
-        * @param IGroupManager $groupManager
-        * @param IShareManager $shareManager
-        * @param IConfig $config
-        * @param IL10N $l10n
-        * @param CalDavBackend $calDav
-        */
        public function __construct(
                IUserManager $userManager,
                IGroupManager $groupManager,
@@ -224,7 +200,7 @@ class MoveCalendar extends Command {
                         */
                        if ($this->shareManager->shareWithGroupMembersOnly() === true && 'groups' === $prefix && !$this->groupManager->isInGroup($userDestination, $userOrGroup)) {
                                if ($force) {
-                                       $this->calDav->updateShares(new Calendar($this->calDav, $calendar, $this->l10n, $this->config, $this->logger), [], ['href' => 'principal:principals/groups/' . $userOrGroup]);
+                                       $this->calDav->updateShares(new Calendar($this->calDav, $calendar, $this->l10n, $this->config, $this->logger), [], ['principal:principals/groups/' . $userOrGroup]);
                                } else {
                                        throw new \InvalidArgumentException("User <$userDestination> is not part of the group <$userOrGroup> with whom the calendar <" . $calendar['uri'] . "> was shared. You may use -f to move the calendar while deleting this share.");
                                }
@@ -235,7 +211,7 @@ class MoveCalendar extends Command {
                         */
                        if ($userOrGroup === $userDestination) {
                                if ($force) {
-                                       $this->calDav->updateShares(new Calendar($this->calDav, $calendar, $this->l10n, $this->config, $this->logger), [], ['href' => 'principal:principals/users/' . $userOrGroup]);
+                                       $this->calDav->updateShares(new Calendar($this->calDav, $calendar, $this->l10n, $this->config, $this->logger), [], ['principal:principals/users/' . $userOrGroup]);
                                } else {
                                        throw new \InvalidArgumentException("The calendar <" . $calendar['uri'] . "> is already shared to user <$userDestination>.You may use -f to move the calendar while deleting this share.");
                                }
index 544a38cfbe695b7ce76f93cbada30a35a783bcd0..92971992c202649a3d86ef087b6731e786663559 100644 (file)
@@ -32,32 +32,20 @@ use OCA\DAV\Connector\Sabre\Principal;
 use OCP\IDBConnection;
 use OCP\IGroupManager;
 use OCP\IUserManager;
+use OCP\DB\QueryBuilder\IQueryBuilder;
 
 class Backend {
-
-       /** @var IDBConnection */
-       private $db;
-       /** @var IUserManager */
-       private $userManager;
-       /** @var IGroupManager */
-       private $groupManager;
-       /** @var Principal */
-       private $principalBackend;
-       /** @var string */
-       private $resourceType;
+       private IDBConnection $db;
+       private IUserManager $userManager;
+       private IGroupManager $groupManager;
+       private Principal $principalBackend;
+       private string $resourceType;
 
        public const ACCESS_OWNER = 1;
        public const ACCESS_READ_WRITE = 2;
        public const ACCESS_READ = 3;
 
-       /**
-        * @param IDBConnection $db
-        * @param IUserManager $userManager
-        * @param IGroupManager $groupManager
-        * @param Principal $principalBackend
-        * @param string $resourceType
-        */
-       public function __construct(IDBConnection $db, IUserManager $userManager, IGroupManager $groupManager, Principal $principalBackend, $resourceType) {
+       public function __construct(IDBConnection $db, IUserManager $userManager, IGroupManager $groupManager, Principal $principalBackend, string $resourceType) {
                $this->db = $db;
                $this->userManager = $userManager;
                $this->groupManager = $groupManager;
@@ -66,11 +54,10 @@ class Backend {
        }
 
        /**
-        * @param IShareable $shareable
-        * @param string[] $add
-        * @param string[] $remove
+        * @param list<array{href: string, commonName: string, readOnly: bool}> $add
+        * @param list<string> $remove
         */
-       public function updateShares(IShareable $shareable, array $add, array $remove) {
+       public function updateShares(IShareable $shareable, array $add, array $remove): void {
                foreach ($add as $element) {
                        $principal = $this->principalBackend->findByUri($element['href'], '');
                        if ($principal !== '') {
@@ -86,10 +73,9 @@ class Backend {
        }
 
        /**
-        * @param IShareable $shareable
-        * @param string $element
+        * @param array{href: string, commonName: string, readOnly: bool} $element
         */
-       private function shareWith($shareable, $element) {
+       private function shareWith(IShareable $shareable, array $element): void {
                $user = $element['href'];
                $parts = explode(':', $user, 2);
                if ($parts[0] !== 'principal') {
@@ -129,33 +115,26 @@ class Backend {
                                'access' => $query->createNamedParameter($access),
                                'resourceid' => $query->createNamedParameter($shareable->getResourceId())
                        ]);
-               $query->execute();
+               $query->executeStatement();
        }
 
-       /**
-        * @param $resourceId
-        */
-       public function deleteAllShares($resourceId) {
+       public function deleteAllShares(int $resourceId): void {
                $query = $this->db->getQueryBuilder();
                $query->delete('dav_shares')
                        ->where($query->expr()->eq('resourceid', $query->createNamedParameter($resourceId)))
                        ->andWhere($query->expr()->eq('type', $query->createNamedParameter($this->resourceType)))
-                       ->execute();
+                       ->executeStatement();
        }
 
-       public function deleteAllSharesByUser($principaluri) {
+       public function deleteAllSharesByUser(string $principaluri): void {
                $query = $this->db->getQueryBuilder();
                $query->delete('dav_shares')
                        ->where($query->expr()->eq('principaluri', $query->createNamedParameter($principaluri)))
                        ->andWhere($query->expr()->eq('type', $query->createNamedParameter($this->resourceType)))
-                       ->execute();
+                       ->executeStatement();
        }
 
-       /**
-        * @param IShareable $shareable
-        * @param string $element
-        */
-       private function unshare($shareable, $element) {
+       private function unshare(IShareable $shareable, string $element): void {
                $parts = explode(':', $element, 2);
                if ($parts[0] !== 'principal') {
                        return;
@@ -172,7 +151,7 @@ class Backend {
                        ->andWhere($query->expr()->eq('type', $query->createNamedParameter($this->resourceType)))
                        ->andWhere($query->expr()->eq('principaluri', $query->createNamedParameter($parts[1])))
                ;
-               $query->execute();
+               $query->executeStatement();
        }
 
        /**
@@ -183,29 +162,28 @@ class Backend {
         *   * commonName - Optional, for example a first + last name
         *   * status - See the Sabre\CalDAV\SharingPlugin::STATUS_ constants.
         *   * readOnly - boolean
-        *   * summary - Optional, a description for the share
         *
         * @param int $resourceId
-        * @return array
+        * @return list<array{href: string, commonName: string, status: int, readOnly: bool, '{http://owncloud.org/ns}principal': string, '{http://owncloud.org/ns}group-share': bool}>
         */
-       public function getShares($resourceId) {
+       public function getShares(int $resourceId): array {
                $query = $this->db->getQueryBuilder();
                $result = $query->select(['principaluri', 'access'])
                        ->from('dav_shares')
-                       ->where($query->expr()->eq('resourceid', $query->createNamedParameter($resourceId)))
+                       ->where($query->expr()->eq('resourceid', $query->createNamedParameter($resourceId, IQueryBuilder::PARAM_INT)))
                        ->andWhere($query->expr()->eq('type', $query->createNamedParameter($this->resourceType)))
                        ->groupBy(['principaluri', 'access'])
-                       ->execute();
+                       ->executeQuery();
 
                $shares = [];
                while ($row = $result->fetch()) {
                        $p = $this->principalBackend->getPrincipalByPath($row['principaluri']);
                        $shares[] = [
-                               'href' => "principal:{$row['principaluri']}",
-                               'commonName' => isset($p['{DAV:}displayname']) ? $p['{DAV:}displayname'] : '',
+                               'href' => "principal:${row['principaluri']}",
+                               'commonName' => isset($p['{DAV:}displayname']) ? (string)$p['{DAV:}displayname'] : '',
                                'status' => 1,
                                'readOnly' => (int) $row['access'] === self::ACCESS_READ,
-                               '{http://owncloud.org/ns}principal' => $row['principaluri'],
+                               '{http://owncloud.org/ns}principal' => (string)$row['principaluri'],
                                '{http://owncloud.org/ns}group-share' => is_null($p)
                        ];
                }
@@ -217,10 +195,10 @@ class Backend {
         * For shared resources the sharee is set in the ACL of the resource
         *
         * @param int $resourceId
-        * @param array $acl
-        * @return array
+        * @param list<array{privilege: string, principal: string, protected: bool}> $acl
+        * @return list<array{privilege: string, principal: string, protected: bool}>
         */
-       public function applyShareAcl($resourceId, $acl) {
+       public function applyShareAcl(int $resourceId, array $acl): array {
                $shares = $this->getShares($resourceId);
                foreach ($shares as $share) {
                        $acl[] = [
index 3833e026696c7b2ba5b26bbbee9bff012a2b9571..759981af0784e5b992d939195e0f7f0360a8eb02 100644 (file)
@@ -40,16 +40,14 @@ interface IShareable extends INode {
         * Every element in the add array has the following properties:
         *   * href - A url. Usually a mailto: address
         *   * commonName - Usually a first and last name, or false
-        *   * summary - A description of the share, can also be false
         *   * readOnly - A boolean value
         *
         * Every element in the remove array is just the address string.
         *
-        * @param array $add
-        * @param array $remove
-        * @return void
+        * @param list<array{href: string, commonName: string, readOnly: bool}> $add
+        * @param list<string> $remove
         */
-       public function updateShares(array $add, array $remove);
+       public function updateShares(array $add, array $remove): void;
 
        /**
         * Returns the list of people whom this resource is shared with.
@@ -59,19 +57,15 @@ interface IShareable extends INode {
         *   * commonName - Optional, for example a first + last name
         *   * status - See the Sabre\CalDAV\SharingPlugin::STATUS_ constants.
         *   * readOnly - boolean
-        *   * summary - Optional, a description for the share
         *
-        * @return array
+        * @return list<array{href: string, commonName: string, status: int, readOnly: bool, '{http://owncloud.org/ns}principal': string, '{http://owncloud.org/ns}group-share': bool}>
         */
-       public function getShares();
+       public function getShares(): array;
 
-       /**
-        * @return int
-        */
-       public function getResourceId();
+       public function getResourceId(): int;
 
        /**
-        * @return string
+        * @return ?string
         */
        public function getOwner();
 }
index a9011bc02735b9033c5fa33204e3355ab6d9ab37..d5a568d149bf6576abce992308da98dffde7403a 100644 (file)
@@ -26,6 +26,8 @@ declare(strict_types=1);
 namespace OCA\DAV\Events;
 
 use OCP\EventDispatcher\Event;
+use Sabre\CalDAV\Xml\Property\ScheduleCalendarTransp;
+use Sabre\CalDAV\Xml\Property\SupportedCalendarComponentSet;
 
 /**
  * Class CalendarShareUpdatedEvent
@@ -34,30 +36,28 @@ use OCP\EventDispatcher\Event;
  * @since 20.0.0
  */
 class CalendarShareUpdatedEvent extends Event {
+       private int $calendarId;
 
-       /** @var int */
-       private $calendarId;
+       /** @var array{id: int, uri: string, '{http://calendarserver.org/ns/}getctag': string, '{http://sabredav.org/ns}sync-token': int, '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set': SupportedCalendarComponentSet, '{urn:ietf:params:xml:ns:caldav}schedule-calendar-transp': ScheduleCalendarTransp } */
+       private array $calendarData;
 
-       /** @var array */
-       private $calendarData;
+       /** @var list<array{href: string, commonName: string, status: int, readOnly: bool, '{http://owncloud.org/ns}principal': string, '{http://owncloud.org/ns}group-share': bool}> */
+       private array $oldShares;
 
-       /** @var array */
-       private $oldShares;
+       /** @var list<array{href: string, commonName: string, readOnly: bool}> */
+       private array $added;
 
-       /** @var array */
-       private $added;
-
-       /** @var array */
-       private $removed;
+       /** @var list<string> */
+       private array $removed;
 
        /**
         * CalendarShareUpdatedEvent constructor.
         *
         * @param int $calendarId
-        * @param array $calendarData
-        * @param array $oldShares
-        * @param array $added
-        * @param array $removed
+        * @param array{id: int, uri: string, '{http://calendarserver.org/ns/}getctag': string, '{http://sabredav.org/ns}sync-token': int, '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set': SupportedCalendarComponentSet, '{urn:ietf:params:xml:ns:caldav}schedule-calendar-transp': ScheduleCalendarTransp } $calendarData
+        * @param list<array{href: string, commonName: string, status: int, readOnly: bool, '{http://owncloud.org/ns}principal': string, '{http://owncloud.org/ns}group-share': bool}> $oldShares
+        * @param list<array{href: string, commonName: string, readOnly: bool}> $added
+        * @param list<string> $removed
         * @since 20.0.0
         */
        public function __construct(int $calendarId,
@@ -74,7 +74,6 @@ class CalendarShareUpdatedEvent extends Event {
        }
 
        /**
-        * @return int
         * @since 20.0.0
         */
        public function getCalendarId(): int {
@@ -82,7 +81,7 @@ class CalendarShareUpdatedEvent extends Event {
        }
 
        /**
-        * @return array
+        * @return array{id: int, uri: string, '{http://calendarserver.org/ns/}getctag': string, '{http://sabredav.org/ns}sync-token': int, '{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set': SupportedCalendarComponentSet, '{urn:ietf:params:xml:ns:caldav}schedule-calendar-transp': ScheduleCalendarTransp }
         * @since 20.0.0
         */
        public function getCalendarData(): array {
@@ -90,7 +89,7 @@ class CalendarShareUpdatedEvent extends Event {
        }
 
        /**
-        * @return array
+        * @return list<array{href: string, commonName: string, status: int, readOnly: bool, '{http://owncloud.org/ns}principal': string, '{http://owncloud.org/ns}group-share': bool}>
         * @since 20.0.0
         */
        public function getOldShares(): array {
@@ -98,7 +97,7 @@ class CalendarShareUpdatedEvent extends Event {
        }
 
        /**
-        * @return array
+        * @return list<array{href: string, commonName: string, readOnly: bool}>
         * @since 20.0.0
         */
        public function getAdded(): array {
@@ -106,7 +105,7 @@ class CalendarShareUpdatedEvent extends Event {
        }
 
        /**
-        * @return array
+        * @return list<string>
         * @since 20.0.0
         */
        public function getRemoved(): array {
index 6233980edbbe74e56fd758c3863bcd5b4bc8a05e..8f1a2a1378f547028e33415b787087411fed1479 100644 (file)
@@ -32,6 +32,7 @@ namespace OCA\DAV\Tests\unit\BackgroundJob;
 use OCA\DAV\BackgroundJob\CleanupInvitationTokenJob;
 use OCP\AppFramework\Utility\ITimeFactory;
 use OCP\DB\QueryBuilder\IQueryBuilder;
+use OCP\DB\QueryBuilder\IQueryFunction;
 use OCP\IDBConnection;
 use Test\TestCase;
 
@@ -77,10 +78,11 @@ class CleanupInvitationTokenJobTest extends TestCase {
                                [1337, \PDO::PARAM_STR, null, 'namedParameter1337']
                        ]);
 
+               $function = $this->createMock(IQueryFunction::class);
                $expr->expects($this->once())
                        ->method('lt')
                        ->with('expiration', 'namedParameter1337')
-                       ->willReturn('LT STATEMENT');
+                       ->willReturn($function);
 
                $this->dbConnection->expects($this->once())
                        ->method('getQueryBuilder')
@@ -93,7 +95,7 @@ class CleanupInvitationTokenJobTest extends TestCase {
                        ->willReturn($queryBuilder);
                $queryBuilder->expects($this->at(3))
                        ->method('where')
-                       ->with('LT STATEMENT')
+                       ->with($function)
                        ->willReturn($queryBuilder);
                $queryBuilder->expects($this->at(4))
                        ->method('execute')
index cd3269d657c9c3f538dfb3f42b1c523c0662f586..576fde2d4af281ab746814e4417af5ef828eca9f 100644 (file)
@@ -37,6 +37,7 @@ use OCP\AppFramework\Utility\ITimeFactory;
 use OCP\DB\IResult;
 use OCP\DB\QueryBuilder\IExpressionBuilder;
 use OCP\DB\QueryBuilder\IQueryBuilder;
+use OCP\DB\QueryBuilder\IQueryFunction;
 use OCP\IDBConnection;
 use OCP\IRequest;
 use Sabre\VObject\ITip\Message;
@@ -477,10 +478,11 @@ EOF;
                        ->with(\PDO::FETCH_ASSOC)
                        ->willReturn($return);
 
+               $function = $this->createMock(IQueryFunction::class);
                $expr->expects($this->once())
                        ->method('eq')
                        ->with('token', 'namedParameterToken')
-                       ->willReturn('EQ STATEMENT');
+                       ->willReturn($function);
 
                $this->dbConnection->expects($this->once())
                        ->method('getQueryBuilder')
@@ -497,7 +499,7 @@ EOF;
                        ->willReturn($queryBuilder);
                $queryBuilder->expects($this->at(4))
                        ->method('where')
-                       ->with('EQ STATEMENT')
+                       ->with($function)
                        ->willReturn($queryBuilder);
                $queryBuilder->expects($this->at(5))
                        ->method('execute')
index 1e27a2496c712dfef8e92f61e28b177f973ec5ab..e89253b8870d4d1542a4da67b86dcf36daa81b08 100644 (file)
     </ParamNameMismatch>
   </file>
   <file src="apps/dav/lib/CalDAV/CalDavBackend.php">
-    <InvalidArgument occurrences="8">
-      <code>'\OCA\DAV\CalDAV\CalDavBackend::createCachedCalendarObject'</code>
-      <code>'\OCA\DAV\CalDAV\CalDavBackend::createSubscription'</code>
-      <code>'\OCA\DAV\CalDAV\CalDavBackend::deleteCachedCalendarObject'</code>
-      <code>'\OCA\DAV\CalDAV\CalDavBackend::deleteSubscription'</code>
-      <code>'\OCA\DAV\CalDAV\CalDavBackend::publishCalendar'</code>
-      <code>'\OCA\DAV\CalDAV\CalDavBackend::updateCachedCalendarObject'</code>
-      <code>'\OCA\DAV\CalDAV\CalDavBackend::updateShares'</code>
-      <code>'\OCA\DAV\CalDAV\CalDavBackend::updateSubscription'</code>
-    </InvalidArgument>
     <InvalidNullableReturnType occurrences="2">
       <code>array</code>
       <code>array</code>
     <RedundantCast occurrences="1">
       <code>(int)$calendarId</code>
     </RedundantCast>
-    <TooManyArguments occurrences="8">
-      <code>dispatch</code>
-      <code>dispatch</code>
-      <code>dispatch</code>
-      <code>dispatch</code>
-      <code>dispatch</code>
-      <code>dispatch</code>
-      <code>dispatch</code>
-      <code>dispatch</code>
-    </TooManyArguments>
     <UndefinedFunction occurrences="4">
       <code>Uri\split($principalUri)</code>
       <code>Uri\split($row['principaluri'])</code>
     </InvalidArgument>
   </file>
   <file src="apps/dav/lib/CardDAV/AddressBookImpl.php">
-    <InvalidArgument occurrences="1">
-      <code>$id</code>
-    </InvalidArgument>
     <InvalidScalarArgument occurrences="2">
       <code>$this-&gt;getKey()</code>
       <code>$this-&gt;getKey()</code>
     <FalsableReturnStatement occurrences="1">
       <code>false</code>
     </FalsableReturnStatement>
-    <InvalidArgument occurrences="3">
-      <code>'\OCA\DAV\CardDAV\CardDavBackend::createCard'</code>
-      <code>'\OCA\DAV\CardDAV\CardDavBackend::deleteCard'</code>
-      <code>'\OCA\DAV\CardDAV\CardDavBackend::updateCard'</code>
-    </InvalidArgument>
-    <TooManyArguments occurrences="3">
-      <code>dispatch</code>
-      <code>dispatch</code>
-      <code>dispatch</code>
-    </TooManyArguments>
     <TypeDoesNotContainType occurrences="1">
       <code>$addressBooks[$row['id']][$readOnlyPropertyName] === 0</code>
     </TypeDoesNotContainType>
       <code>null</code>
     </NullableReturnStatement>
   </file>
-  <file src="apps/dav/lib/DAV/Sharing/Backend.php">
-    <InvalidArrayOffset occurrences="4">
-      <code>$element['href']</code>
-      <code>$element['href']</code>
-      <code>$element['href']</code>
-      <code>$element['readOnly']</code>
-    </InvalidArrayOffset>
-  </file>
   <file src="apps/dav/lib/DAV/SystemPrincipalBackend.php">
     <InvalidNullableReturnType occurrences="1">
       <code>array</code>
     </RedundantCondition>
     <TypeDoesNotContainType occurrences="2">
       <code>get_class($res) === 'OpenSSLAsymmetricKey'</code>
-      <code>is_object($res)</code>
     </TypeDoesNotContainType>
   </file>
   <file src="apps/encryption/lib/Crypto/EncryptAll.php">
       <code>0</code>
     </InvalidScalarArgument>
   </file>
-  <file src="apps/updatenotification/lib/ResetTokenBackgroundJob.php">
-    <InvalidOperand occurrences="1">
-      <code>$this-&gt;config-&gt;getAppValue('core', 'updater.secret.created', $this-&gt;timeFactory-&gt;getTime())</code>
-    </InvalidOperand>
-    <InvalidScalarArgument occurrences="1">
-      <code>$this-&gt;timeFactory-&gt;getTime()</code>
-    </InvalidScalarArgument>
-  </file>
   <file src="apps/updatenotification/lib/Settings/Admin.php">
     <InvalidScalarArgument occurrences="1">
       <code>$lastUpdateCheckTimestamp</code>
       <code>$result</code>
       <code>$this-&gt;copyFromStorage($sourceStorage, $sourceInternalPath . '/' . $file, $targetInternalPath . '/' . $file, false, $isRename)</code>
     </InvalidOperand>
-    <InvalidReturnStatement occurrences="6">
+    <InvalidReturnStatement occurrences="4">
       <code>$newUnencryptedSize</code>
       <code>$result</code>
-      <code>$stat</code>
       <code>$this-&gt;storage-&gt;file_get_contents($path)</code>
       <code>$this-&gt;storage-&gt;filesize($path)</code>
-      <code>$this-&gt;storage-&gt;getLocalFile($path)</code>
     </InvalidReturnStatement>
-    <InvalidReturnType occurrences="5">
-      <code>array</code>
+    <InvalidReturnType occurrences="3">
       <code>bool</code>
       <code>int</code>
       <code>string</code>