diff options
author | Carl Schwan <carl@carlschwan.eu> | 2022-06-22 12:09:06 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-06-22 12:09:06 +0300 |
commit | 14a16320ecdbd07faadaaa91c997f968e009dfbf (patch) | |
tree | 05f2bc1c95c1a6d91a3dc0f150767103f57bdfd1 /apps/dav | |
parent | a4647bbf6ef2535f51ee92115d75581313e4a3d4 (diff) | |
parent | 3598ec40285b88d4f8f03a4db8d3a085a521d2df (diff) |
Merge pull request #32884 from nextcloud/typing/dav-sharing
Add typing to Sharing Backend
Diffstat (limited to 'apps/dav')
-rw-r--r-- | apps/dav/lib/CalDAV/CalDavBackend.php | 58 | ||||
-rw-r--r-- | apps/dav/lib/CalDAV/Calendar.php | 62 | ||||
-rw-r--r-- | apps/dav/lib/CardDAV/AddressBook.php | 24 | ||||
-rw-r--r-- | apps/dav/lib/CardDAV/CardDavBackend.php | 59 | ||||
-rw-r--r-- | apps/dav/lib/Command/MoveCalendar.php | 44 | ||||
-rw-r--r-- | apps/dav/lib/DAV/Sharing/Backend.php | 80 | ||||
-rw-r--r-- | apps/dav/lib/DAV/Sharing/IShareable.php | 20 | ||||
-rw-r--r-- | apps/dav/lib/Events/CalendarShareUpdatedEvent.php | 39 | ||||
-rw-r--r-- | apps/dav/tests/unit/BackgroundJob/CleanupInvitationTokenJobTest.php | 6 | ||||
-rw-r--r-- | apps/dav/tests/unit/Controller/InvitationResponseControllerTest.php | 6 |
10 files changed, 154 insertions, 244 deletions
diff --git a/apps/dav/lib/CalDAV/CalDavBackend.php b/apps/dav/lib/CalDAV/CalDavBackend.php index 3ab047d5183..7e13b3ba8fd 100644 --- a/apps/dav/lib/CalDAV/CalDavBackend.php +++ b/apps/dav/lib/CalDAV/CalDavBackend.php @@ -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 * diff --git a/apps/dav/lib/CalDAV/Calendar.php b/apps/dav/lib/CalDAV/Calendar.php index 806e99d8a05..92ad3242d78 100644 --- a/apps/dav/lib/CalDAV/Calendar.php +++ b/apps/dav/lib/CalDAV/Calendar.php @@ -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']; } diff --git a/apps/dav/lib/CardDAV/AddressBook.php b/apps/dav/lib/CardDAV/AddressBook.php index 9bd24bedbac..bca478feec1 100644 --- a/apps/dav/lib/CardDAV/AddressBook.php +++ b/apps/dav/lib/CardDAV/AddressBook.php @@ -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']; } diff --git a/apps/dav/lib/CardDAV/CardDavBackend.php b/apps/dav/lib/CardDAV/CardDavBackend.php index 745ca7801b7..2c99e6084c1 100644 --- a/apps/dav/lib/CardDAV/CardDavBackend.php +++ b/apps/dav/lib/CardDAV/CardDavBackend.php @@ -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(); diff --git a/apps/dav/lib/Command/MoveCalendar.php b/apps/dav/lib/Command/MoveCalendar.php index 320fe8aeac6..9272b20b10d 100644 --- a/apps/dav/lib/Command/MoveCalendar.php +++ b/apps/dav/lib/Command/MoveCalendar.php @@ -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."); } diff --git a/apps/dav/lib/DAV/Sharing/Backend.php b/apps/dav/lib/DAV/Sharing/Backend.php index 544a38cfbe6..92971992c20 100644 --- a/apps/dav/lib/DAV/Sharing/Backend.php +++ b/apps/dav/lib/DAV/Sharing/Backend.php @@ -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[] = [ diff --git a/apps/dav/lib/DAV/Sharing/IShareable.php b/apps/dav/lib/DAV/Sharing/IShareable.php index 3833e026696..759981af078 100644 --- a/apps/dav/lib/DAV/Sharing/IShareable.php +++ b/apps/dav/lib/DAV/Sharing/IShareable.php @@ -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(); } diff --git a/apps/dav/lib/Events/CalendarShareUpdatedEvent.php b/apps/dav/lib/Events/CalendarShareUpdatedEvent.php index a9011bc0273..d5a568d149b 100644 --- a/apps/dav/lib/Events/CalendarShareUpdatedEvent.php +++ b/apps/dav/lib/Events/CalendarShareUpdatedEvent.php @@ -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 { diff --git a/apps/dav/tests/unit/BackgroundJob/CleanupInvitationTokenJobTest.php b/apps/dav/tests/unit/BackgroundJob/CleanupInvitationTokenJobTest.php index 6233980edbb..8f1a2a1378f 100644 --- a/apps/dav/tests/unit/BackgroundJob/CleanupInvitationTokenJobTest.php +++ b/apps/dav/tests/unit/BackgroundJob/CleanupInvitationTokenJobTest.php @@ -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') diff --git a/apps/dav/tests/unit/Controller/InvitationResponseControllerTest.php b/apps/dav/tests/unit/Controller/InvitationResponseControllerTest.php index cd3269d657c..576fde2d4af 100644 --- a/apps/dav/tests/unit/Controller/InvitationResponseControllerTest.php +++ b/apps/dav/tests/unit/Controller/InvitationResponseControllerTest.php @@ -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') |