From 55e1270b94aa0f4ea003e2cbc87a8ea56bcae96d Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Tue, 11 Aug 2026 01:28:35 +0200 Subject: [PATCH] refactor: use Share for most SharingManager parameters instead of just the id Signed-off-by: Robin Appelman # Conflicts: # tests/lib/Sharing/AbstractSharingManagerTests.php # Conflicts: # apps/sharing/tests/Controller/ApiV1ControllerTest.php # tests/lib/Sharing/AbstractSharingManagerTests.php --- .../Source/NodeShareSourceTypeTest.php | 8 +- .../sharing/lib/Command/AddShareRecipient.php | 7 +- apps/sharing/lib/Command/AddShareSource.php | 7 +- apps/sharing/lib/Command/CreateShare.php | 3 +- apps/sharing/lib/Command/DeleteShare.php | 3 +- apps/sharing/lib/Command/GetShare.php | 3 +- .../lib/Command/RemoveShareRecipient.php | 7 +- .../sharing/lib/Command/RemoveShareSource.php | 7 +- .../Command/SelectSharePermissionPreset.php | 7 +- apps/sharing/lib/Command/SharingBase.php | 6 +- .../lib/Command/UpdateSharePermission.php | 7 +- .../lib/Command/UpdateShareProperty.php | 7 +- .../Command/UpdateShareRecipientSecret.php | 7 +- apps/sharing/lib/Command/UpdateShareState.php | 7 +- .../lib/Controller/ApiV1Controller.php | 28 +- apps/sharing/tests/Command/CommandTest.php | 44 +- .../tests/Controller/ApiV1ControllerTest.php | 44 +- lib/private/Sharing/SharingBackend.php | 193 +-- lib/private/Sharing/SharingManager.php | 387 ++++-- lib/private/Sharing/SharingRegistry.php | 44 + .../Sharing/Event/SharesDefaultSetEvent.php | 6 +- lib/unstable/Sharing/ISharingBackend.php | 9 + lib/unstable/Sharing/ISharingManager.php | 26 +- lib/unstable/Sharing/ISharingRegistry.php | 15 + .../Sharing/Recipient/ShareRecipient.php | 7 + lib/unstable/Sharing/Source/ShareSource.php | 7 + .../Recipient/GroupShareRecipientTypeTest.php | 8 +- .../Recipient/TeamShareRecipientTypeTest.php | 8 +- .../Recipient/UserShareRecipientTypeTest.php | 8 +- .../Sharing/AbstractSharingManagerTests.php | 1105 +++++++++-------- tests/lib/Sharing/SharingManagerTest.php | 113 +- 31 files changed, 1248 insertions(+), 890 deletions(-) diff --git a/apps/files/tests/Sharing/Source/NodeShareSourceTypeTest.php b/apps/files/tests/Sharing/Source/NodeShareSourceTypeTest.php index 61bb51e01bd1e..bb04d80af93a3 100644 --- a/apps/files/tests/Sharing/Source/NodeShareSourceTypeTest.php +++ b/apps/files/tests/Sharing/Source/NodeShareSourceTypeTest.php @@ -108,8 +108,8 @@ public function testDelete(): void { $accessContext = new ShareAccessContext(currentUser: $this->user1); $this->dbConnection->beginTransaction(); - $id = $this->manager->createShare($accessContext); - $this->manager->addShareSource($accessContext, $id, new ShareSource($this->sourceType::class, (string)$this->node->getId())); + $share = $this->manager->createShare($accessContext); + $this->manager->addShareSource($accessContext, $share, new ShareSource($this->sourceType::class, (string)$this->node->getId())); $this->dbConnection->commit(); $before = $this->manager->getTime(); @@ -117,12 +117,12 @@ public function testDelete(): void { $after = $this->manager->getTime(); $this->dbConnection->beginTransaction(); - $share = $this->manager->getShare($accessContext, $id); + $share = $this->manager->getShare($accessContext, $share->id); $this->assertGreaterThanOrEqual(SharingManager::timeToMs($before), SharingManager::timeToMs($share->lastUpdated)); $this->assertLessThanOrEqual(SharingManager::timeToMs($after), SharingManager::timeToMs($share->lastUpdated)); $this->assertEquals([], $share->sources); - $this->manager->deleteShare($accessContext, $id); + $this->manager->deleteShare($accessContext, $share); $this->dbConnection->commit(); $registry->clear(); } diff --git a/apps/sharing/lib/Command/AddShareRecipient.php b/apps/sharing/lib/Command/AddShareRecipient.php index 061103416b6d7..7fe76f5ae3dd2 100644 --- a/apps/sharing/lib/Command/AddShareRecipient.php +++ b/apps/sharing/lib/Command/AddShareRecipient.php @@ -11,6 +11,7 @@ use NCU\Sharing\Recipient\IShareRecipientType; use NCU\Sharing\Recipient\ShareRecipient; +use NCU\Sharing\Share; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -39,9 +40,9 @@ public function execute(InputInterface $input, OutputInterface $output): int { /** @var ?non-empty-string $instance */ $instance = $input->getArgument('instance'); - return $this->wrapExecution($output, function () use ($id, $class, $value, $instance): string { - $this->manager->addShareRecipient($this->accessContext, $id, new ShareRecipient($class, $value, $instance)); - return $id; + return $this->wrapExecution($output, function () use ($id, $class, $value, $instance): Share { + $share = $this->manager->getShare($this->accessContext, $id); + return $this->manager->addShareRecipient($this->accessContext, $share, new ShareRecipient($class, $value, $instance)); }); } } diff --git a/apps/sharing/lib/Command/AddShareSource.php b/apps/sharing/lib/Command/AddShareSource.php index d236c747eb774..ddd1e0aebc485 100644 --- a/apps/sharing/lib/Command/AddShareSource.php +++ b/apps/sharing/lib/Command/AddShareSource.php @@ -9,6 +9,7 @@ namespace OCA\Sharing\Command; +use NCU\Sharing\Share; use NCU\Sharing\Source\IShareSourceType; use NCU\Sharing\Source\ShareSource; use Symfony\Component\Console\Input\InputArgument; @@ -35,9 +36,9 @@ public function execute(InputInterface $input, OutputInterface $output): int { /** @var non-empty-string $value */ $value = $input->getArgument('value'); - return $this->wrapExecution($output, function () use ($id, $class, $value): string { - $this->manager->addShareSource($this->accessContext, $id, new ShareSource($class, $value)); - return $id; + return $this->wrapExecution($output, function () use ($id, $class, $value): Share { + $share = $this->manager->getShare($this->accessContext, $id); + return $this->manager->addShareSource($this->accessContext, $share, new ShareSource($class, $value)); }); } } diff --git a/apps/sharing/lib/Command/CreateShare.php b/apps/sharing/lib/Command/CreateShare.php index 013543f5bcc5c..620916b178054 100644 --- a/apps/sharing/lib/Command/CreateShare.php +++ b/apps/sharing/lib/Command/CreateShare.php @@ -10,6 +10,7 @@ namespace OCA\Sharing\Command; use NCU\Sharing\Exception\ShareInvalidException; +use NCU\Sharing\Share; use NCU\Sharing\ShareAccessContext; use OCP\IUserManager; use OCP\L10N\IFactory; @@ -36,6 +37,6 @@ public function execute(InputInterface $input, OutputInterface $output): int { throw new ShareInvalidException('The owner does not exist: ' . $ownerUid, Server::get(IFactory::class)->get('sharing')->t('The owner does not exist: %s', [$ownerUid])); } - return $this->wrapExecution($output, fn (): string => $this->manager->createShare(new ShareAccessContext($owner))); + return $this->wrapExecution($output, fn (): Share => $this->manager->createShare(new ShareAccessContext($owner))); } } diff --git a/apps/sharing/lib/Command/DeleteShare.php b/apps/sharing/lib/Command/DeleteShare.php index ee99de6b01880..f5e330624e233 100644 --- a/apps/sharing/lib/Command/DeleteShare.php +++ b/apps/sharing/lib/Command/DeleteShare.php @@ -35,7 +35,8 @@ public function execute(InputInterface $input, OutputInterface $output): int { try { $this->dbConnection->beginTransaction(); - $this->manager->deleteShare($this->accessContext, $id); + $share = $this->manager->getShare($this->accessContext, $id); + $this->manager->deleteShare($this->accessContext, $share); $this->dbConnection->commit(); return Base::SUCCESS; } catch (Exception $exception) { diff --git a/apps/sharing/lib/Command/GetShare.php b/apps/sharing/lib/Command/GetShare.php index 53f1555308880..d150d0406924f 100644 --- a/apps/sharing/lib/Command/GetShare.php +++ b/apps/sharing/lib/Command/GetShare.php @@ -9,6 +9,7 @@ namespace OCA\Sharing\Command; +use NCU\Sharing\Share; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -27,6 +28,6 @@ public function execute(InputInterface $input, OutputInterface $output): int { /** @var string $id */ $id = $input->getArgument('id'); - return $this->wrapExecution($output, fn (): string => $id); + return $this->wrapExecution($output, fn (): Share => $this->manager->getShare($this->accessContext, $id)); } } diff --git a/apps/sharing/lib/Command/RemoveShareRecipient.php b/apps/sharing/lib/Command/RemoveShareRecipient.php index 84f1fef9a0fe0..e52f836e20c90 100644 --- a/apps/sharing/lib/Command/RemoveShareRecipient.php +++ b/apps/sharing/lib/Command/RemoveShareRecipient.php @@ -11,6 +11,7 @@ use NCU\Sharing\Recipient\IShareRecipientType; use NCU\Sharing\Recipient\ShareRecipient; +use NCU\Sharing\Share; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -38,9 +39,9 @@ public function execute(InputInterface $input, OutputInterface $output): int { /** @var ?non-empty-string $instance */ $instance = $input->getArgument('instance'); - return $this->wrapExecution($output, function () use ($id, $class, $value, $instance): string { - $this->manager->removeShareRecipient($this->accessContext, $id, new ShareRecipient($class, $value, $instance)); - return $id; + return $this->wrapExecution($output, function () use ($id, $class, $value, $instance): Share { + $share = $this->manager->getShare($this->accessContext, $id); + return $this->manager->removeShareRecipient($this->accessContext, $share, new ShareRecipient($class, $value, $instance)); }); } } diff --git a/apps/sharing/lib/Command/RemoveShareSource.php b/apps/sharing/lib/Command/RemoveShareSource.php index cd2bab47729b4..e5a8411c15298 100644 --- a/apps/sharing/lib/Command/RemoveShareSource.php +++ b/apps/sharing/lib/Command/RemoveShareSource.php @@ -9,6 +9,7 @@ namespace OCA\Sharing\Command; +use NCU\Sharing\Share; use NCU\Sharing\Source\IShareSourceType; use NCU\Sharing\Source\ShareSource; use Symfony\Component\Console\Input\InputArgument; @@ -35,9 +36,9 @@ public function execute(InputInterface $input, OutputInterface $output): int { /** @var non-empty-string $value */ $value = $input->getArgument('value'); - return $this->wrapExecution($output, function () use ($id, $class, $value): string { - $this->manager->removeShareSource($this->accessContext, $id, new ShareSource($class, $value)); - return $id; + return $this->wrapExecution($output, function () use ($id, $class, $value): Share { + $share = $this->manager->getShare($this->accessContext, $id); + return $this->manager->removeShareSource($this->accessContext, $share, new ShareSource($class, $value)); }); } } diff --git a/apps/sharing/lib/Command/SelectSharePermissionPreset.php b/apps/sharing/lib/Command/SelectSharePermissionPreset.php index c492fbad05693..42fded2396958 100644 --- a/apps/sharing/lib/Command/SelectSharePermissionPreset.php +++ b/apps/sharing/lib/Command/SelectSharePermissionPreset.php @@ -10,6 +10,7 @@ namespace OCA\Sharing\Command; use NCU\Sharing\Permission\ISharePermissionPreset; +use NCU\Sharing\Share; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -31,9 +32,9 @@ public function execute(InputInterface $input, OutputInterface $output): int { /** @var class-string $permissionPresetClass */ $permissionPresetClass = $input->getArgument('permission-preset'); - return $this->wrapExecution($output, function () use ($id, $permissionPresetClass): string { - $this->manager->selectSharePermissionPreset($this->accessContext, $id, $permissionPresetClass); - return $id; + return $this->wrapExecution($output, function () use ($id, $permissionPresetClass): Share { + $share = $this->manager->getShare($this->accessContext, $id); + return $this->manager->selectSharePermissionPreset($this->accessContext, $share, $permissionPresetClass); }); } } diff --git a/apps/sharing/lib/Command/SharingBase.php b/apps/sharing/lib/Command/SharingBase.php index bdbc3ad9f3646..1ebdb77e9d493 100644 --- a/apps/sharing/lib/Command/SharingBase.php +++ b/apps/sharing/lib/Command/SharingBase.php @@ -14,6 +14,7 @@ use NCU\Sharing\Exception\AShareException; use NCU\Sharing\ISharingManager; use NCU\Sharing\ISharingRegistry; +use NCU\Sharing\Share; use NCU\Sharing\ShareAccessContext; use OC\Core\Command\Base; use OCP\IDBConnection; @@ -40,7 +41,7 @@ public function __construct( } /** - * @param Closure():string $closure + * @param Closure():Share $closure */ protected function wrapExecution(OutputInterface $output, Closure $closure): int { @@ -48,8 +49,7 @@ protected function wrapExecution(OutputInterface $output, Closure $closure): int try { $this->dbConnection->beginTransaction(); - $id = $closure(); - $share = $this->manager->getShare($this->accessContext, $id); + $share = $closure(); $this->dbConnection->commit(); $output->writeln(json_encode($share->format($this->registry, $this->l10nFactory, $this->urlGenerator, $this->userManager), JSON_THROW_ON_ERROR)); return Base::SUCCESS; diff --git a/apps/sharing/lib/Command/UpdateSharePermission.php b/apps/sharing/lib/Command/UpdateSharePermission.php index 17e93bc107852..4eb632ff2f626 100644 --- a/apps/sharing/lib/Command/UpdateSharePermission.php +++ b/apps/sharing/lib/Command/UpdateSharePermission.php @@ -11,6 +11,7 @@ use NCU\Sharing\Permission\ISharePermissionType; use NCU\Sharing\Permission\SharePermission; +use NCU\Sharing\Share; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -36,9 +37,9 @@ public function execute(InputInterface $input, OutputInterface $output): int { $enabled = $input->getArgument('enabled'); $enabled = $enabled === 'true'; - return $this->wrapExecution($output, function () use ($id, $class, $enabled): string { - $this->manager->updateSharePermission($this->accessContext, $id, new SharePermission($class, $enabled)); - return $id; + return $this->wrapExecution($output, function () use ($id, $class, $enabled): Share { + $share = $this->manager->getShare($this->accessContext, $id); + return $this->manager->updateSharePermission($this->accessContext, $share, new SharePermission($class, $enabled)); }); } } diff --git a/apps/sharing/lib/Command/UpdateShareProperty.php b/apps/sharing/lib/Command/UpdateShareProperty.php index 38f8dc96774e1..f8b08c2f71e9a 100644 --- a/apps/sharing/lib/Command/UpdateShareProperty.php +++ b/apps/sharing/lib/Command/UpdateShareProperty.php @@ -11,6 +11,7 @@ use NCU\Sharing\Property\ISharePropertyType; use NCU\Sharing\Property\ShareProperty; +use NCU\Sharing\Share; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -35,9 +36,9 @@ public function execute(InputInterface $input, OutputInterface $output): int { /** @var ?string $value */ $value = $input->getArgument('value'); - return $this->wrapExecution($output, function () use ($id, $class, $value): string { - $this->manager->updateShareProperty($this->accessContext, $id, new ShareProperty($class, $value)); - return $id; + return $this->wrapExecution($output, function () use ($id, $class, $value): Share { + $share = $this->manager->getShare($this->accessContext, $id); + return $this->manager->updateShareProperty($this->accessContext, $share, new ShareProperty($class, $value)); }); } } diff --git a/apps/sharing/lib/Command/UpdateShareRecipientSecret.php b/apps/sharing/lib/Command/UpdateShareRecipientSecret.php index 4a77341fb6fc3..1f43fa99bc47d 100644 --- a/apps/sharing/lib/Command/UpdateShareRecipientSecret.php +++ b/apps/sharing/lib/Command/UpdateShareRecipientSecret.php @@ -11,6 +11,7 @@ use NCU\Sharing\Recipient\IShareRecipientType; use NCU\Sharing\Recipient\ShareRecipient; +use NCU\Sharing\Share; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -41,9 +42,9 @@ public function execute(InputInterface $input, OutputInterface $output): int { /** @var non-empty-string $secret */ $secret = $input->getArgument('secret'); - return $this->wrapExecution($output, function () use ($id, $class, $value, $instance, $secret): string { - $this->manager->updateShareRecipientSecret($this->accessContext, $id, new ShareRecipient($class, $value, $instance), $secret); - return $id; + return $this->wrapExecution($output, function () use ($id, $class, $value, $instance, $secret): Share { + $share = $this->manager->getShare($this->accessContext, $id); + return $this->manager->updateShareRecipientSecret($this->accessContext, $share, new ShareRecipient($class, $value, $instance), $secret); }); } } diff --git a/apps/sharing/lib/Command/UpdateShareState.php b/apps/sharing/lib/Command/UpdateShareState.php index f71c393e91355..eb9a26fd1c49f 100644 --- a/apps/sharing/lib/Command/UpdateShareState.php +++ b/apps/sharing/lib/Command/UpdateShareState.php @@ -9,6 +9,7 @@ namespace OCA\Sharing\Command; +use NCU\Sharing\Share; use NCU\Sharing\ShareState; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; @@ -32,9 +33,9 @@ public function execute(InputInterface $input, OutputInterface $output): int { $state = $input->getArgument('state'); $state = ShareState::from($state); - return $this->wrapExecution($output, function () use ($id, $state): string { - $this->manager->updateShareState($this->accessContext, $id, $state); - return $id; + return $this->wrapExecution($output, function () use ($id, $state): Share { + $share = $this->manager->getShare($this->accessContext, $id); + return $this->manager->updateShareState($this->accessContext, $share, $state); }); } } diff --git a/apps/sharing/lib/Controller/ApiV1Controller.php b/apps/sharing/lib/Controller/ApiV1Controller.php index 0efcbc4c6eaff..d56a653c14793 100644 --- a/apps/sharing/lib/Controller/ApiV1Controller.php +++ b/apps/sharing/lib/Controller/ApiV1Controller.php @@ -107,7 +107,8 @@ public function searchRecipients(?array $filterRecipientTypeClasses, string $que try { try { $this->dbConnection->beginTransaction(); - $recipients = $this->manager->searchRecipients($this->accessContext, $filterRecipientTypeClasses, $query, $limit, $offset, $id); + $forShare = ($id === null) ? null : $this->manager->getShare($this->accessContext, $id); + $recipients = $this->manager->searchRecipients($this->accessContext, $filterRecipientTypeClasses, $query, $limit, $offset, $forShare); $this->dbConnection->commit(); return new DataResponse(ShareRecipient::formatMultiple($this->registry, $this->l10nFactory, $this->urlGenerator, $this->userManager, $recipients)); } catch (Exception $exception) { @@ -146,9 +147,8 @@ public function createShare(): DataResponse { try { $this->dbConnection->beginTransaction(); - $id = $this->manager->createShare($this->accessContext); + $share = $this->manager->createShare($this->accessContext); - $share = $this->manager->getShare($this->accessContext, $id); $this->dbConnection->commit(); return new DataResponse($share->format($this->registry, $this->l10nFactory, $this->urlGenerator, $this->userManager), Http::STATUS_CREATED); } catch (Exception $exception) { @@ -185,7 +185,8 @@ public function updateShareState(string $id, string $state): DataResponse { try { $this->dbConnection->beginTransaction(); - $this->manager->updateShareState($this->accessContext, $id, $shareState); + $share = $this->manager->getShare($this->accessContext, $id); + $this->manager->updateShareState($this->accessContext, $share, $shareState); $share = $this->manager->getShare($this->accessContext, $id); $this->dbConnection->commit(); return new DataResponse($share->format($this->registry, $this->l10nFactory, $this->urlGenerator, $this->userManager)); @@ -220,8 +221,8 @@ public function addShareSource(string $id, string $class, string $value): DataRe try { $this->dbConnection->beginTransaction(); - $this->manager->addShareSource($this->accessContext, $id, new ShareSource($class, $value)); $share = $this->manager->getShare($this->accessContext, $id); + $share = $this->manager->addShareSource($this->accessContext, $share, new ShareSource($class, $value)); $this->dbConnection->commit(); return new DataResponse($share->format($this->registry, $this->l10nFactory, $this->urlGenerator, $this->userManager)); } catch (Exception $exception) { @@ -256,8 +257,8 @@ public function removeShareSource(string $id, string $class, string $value): Dat try { $this->dbConnection->beginTransaction(); - $this->manager->removeShareSource($this->accessContext, $id, new ShareSource($class, $value)); $share = $this->manager->getShare($this->accessContext, $id); + $share = $this->manager->removeShareSource($this->accessContext, $share, new ShareSource($class, $value)); $this->dbConnection->commit(); return new DataResponse($share->format($this->registry, $this->l10nFactory, $this->urlGenerator, $this->userManager)); } catch (Exception $exception) { @@ -292,8 +293,8 @@ public function addShareRecipient(string $id, string $class, string $value, ?str try { $this->dbConnection->beginTransaction(); - $this->manager->addShareRecipient($this->accessContext, $id, new ShareRecipient($class, $value, $instance)); $share = $this->manager->getShare($this->accessContext, $id); + $share = $this->manager->addShareRecipient($this->accessContext, $share, new ShareRecipient($class, $value, $instance)); $this->dbConnection->commit(); return new DataResponse($share->format($this->registry, $this->l10nFactory, $this->urlGenerator, $this->userManager)); } catch (Exception $exception) { @@ -329,8 +330,8 @@ public function removeShareRecipient(string $id, string $class, string $value, ? try { $this->dbConnection->beginTransaction(); - $this->manager->removeShareRecipient($this->accessContext, $id, new ShareRecipient($class, $value, $instance)); $share = $this->manager->getShare($this->accessContext, $id); + $share = $this->manager->removeShareRecipient($this->accessContext, $share, new ShareRecipient($class, $value, $instance)); $this->dbConnection->commit(); return new DataResponse($share->format($this->registry, $this->l10nFactory, $this->urlGenerator, $this->userManager)); } catch (Exception $exception) { @@ -366,8 +367,8 @@ public function updateShareRecipientSecret(string $id, string $class, string $va try { $this->dbConnection->beginTransaction(); - $this->manager->updateShareRecipientSecret($this->accessContext, $id, new ShareRecipient($class, $value, $instance), $secret); $share = $this->manager->getShare($this->accessContext, $id); + $share = $this->manager->updateShareRecipientSecret($this->accessContext, $share, new ShareRecipient($class, $value, $instance), $secret); $this->dbConnection->commit(); return new DataResponse($share->format($this->registry, $this->l10nFactory, $this->urlGenerator, $this->userManager)); } catch (Exception $exception) { @@ -403,8 +404,8 @@ public function updateShareProperty(string $id, string $class, ?string $value): try { $this->dbConnection->beginTransaction(); - $this->manager->updateShareProperty($this->accessContext, $id, new ShareProperty($class, $value)); $share = $this->manager->getShare($this->accessContext, $id); + $share = $this->manager->updateShareProperty($this->accessContext, $share, new ShareProperty($class, $value)); $this->dbConnection->commit(); return new DataResponse($share->format($this->registry, $this->l10nFactory, $this->urlGenerator, $this->userManager)); } catch (Exception $exception) { @@ -440,8 +441,8 @@ public function updateSharePermission(string $id, string $class, bool $enabled): try { $this->dbConnection->beginTransaction(); - $this->manager->updateSharePermission($this->accessContext, $id, new SharePermission($class, $enabled)); $share = $this->manager->getShare($this->accessContext, $id); + $share = $this->manager->updateSharePermission($this->accessContext, $share, new SharePermission($class, $enabled)); $this->dbConnection->commit(); return new DataResponse($share->format($this->registry, $this->l10nFactory, $this->urlGenerator, $this->userManager)); } catch (Exception $exception) { @@ -476,8 +477,8 @@ public function selectSharePermissionPreset(string $id, string $permissionPreset try { $this->dbConnection->beginTransaction(); - $this->manager->selectSharePermissionPreset($this->accessContext, $id, $permissionPresetClass); $share = $this->manager->getShare($this->accessContext, $id); + $share = $this->manager->selectSharePermissionPreset($this->accessContext, $share, $permissionPresetClass); $this->dbConnection->commit(); return new DataResponse($share->format($this->registry, $this->l10nFactory, $this->urlGenerator, $this->userManager)); } catch (Exception $exception) { @@ -508,7 +509,8 @@ public function deleteShare(string $id): DataResponse { try { $this->dbConnection->beginTransaction(); - $this->manager->deleteShare($this->accessContext, $id); + $share = $this->manager->getShare($this->accessContext, $id); + $this->manager->deleteShare($this->accessContext, $share); $this->dbConnection->commit(); return new DataResponse([], Http::STATUS_NO_CONTENT); } catch (Exception $exception) { diff --git a/apps/sharing/tests/Command/CommandTest.php b/apps/sharing/tests/Command/CommandTest.php index 19b1ca1b27139..3245541e90b7b 100644 --- a/apps/sharing/tests/Command/CommandTest.php +++ b/apps/sharing/tests/Command/CommandTest.php @@ -149,12 +149,12 @@ private function runCommand(ShareAccessContext $accessContext, string $class, ar } #[Override] - protected function searchRecipients(ShareAccessContext $accessContext, ?array $filterRecipientTypeClasses, string $query, int $limit, int $offset, ?string $id = null): array { + protected function searchRecipients(ShareAccessContext $accessContext, ?array $filterRecipientTypeClasses, string $query, int $limit, int $offset, ?Share $forShare = null): array { // We don't have a command for this, so we just call the real manager to make the test pass. try { $this->dbConnection->beginTransaction(); /** @psalm-suppress ArgumentTypeCoercion */ - $shares = ShareRecipient::formatMultiple($this->registry, Server::get(IFactory::class), Server::get(IURLGenerator::class), Server::get(IUserManager::class), $this->manager->searchRecipients($accessContext, $filterRecipientTypeClasses, $query, $limit, $offset, $id)); + $shares = ShareRecipient::formatMultiple($this->registry, Server::get(IFactory::class), Server::get(IURLGenerator::class), Server::get(IUserManager::class), $this->manager->searchRecipients($accessContext, $filterRecipientTypeClasses, $query, $limit, $offset, $forShare)); $this->dbConnection->commit(); return $shares; } catch (Exception $exception) { @@ -185,12 +185,12 @@ protected function createShare(ShareAccessContext $accessContext): array { * @return SharingShare */ #[Override] - protected function updateShareState(ShareAccessContext $accessContext, string $id, ShareState $state): array { + protected function updateShareState(ShareAccessContext $accessContext, Share $share, ShareState $state): array { $stdout = $this->runCommand( $accessContext, UpdateShareState::class, [ - ['id', $id], + ['id', $share->id], ['state', $state->value], ], [], @@ -203,12 +203,12 @@ protected function updateShareState(ShareAccessContext $accessContext, string $i * @return SharingShare */ #[Override] - protected function addShareSource(ShareAccessContext $accessContext, string $id, ShareSource $source): array { + protected function addShareSource(ShareAccessContext $accessContext, Share $share, ShareSource $source): array { $stdout = $this->runCommand( $accessContext, AddShareSource::class, [ - ['id', $id], + ['id', $share->id], ['class', $source->class], ['value', $source->value], ], @@ -222,12 +222,12 @@ protected function addShareSource(ShareAccessContext $accessContext, string $id, * @return SharingShare */ #[Override] - protected function removeShareSource(ShareAccessContext $accessContext, string $id, ShareSource $source): array { + protected function removeShareSource(ShareAccessContext $accessContext, Share $share, ShareSource $source): array { $stdout = $this->runCommand( $accessContext, RemoveShareSource::class, [ - ['id', $id], + ['id', $share->id], ['class', $source->class], ['value', $source->value], ], @@ -241,12 +241,12 @@ protected function removeShareSource(ShareAccessContext $accessContext, string $ * @return SharingShare */ #[Override] - protected function addShareRecipient(ShareAccessContext $accessContext, string $id, ShareRecipient $recipient): array { + protected function addShareRecipient(ShareAccessContext $accessContext, Share $share, ShareRecipient $recipient): array { $stdout = $this->runCommand( $accessContext, AddShareRecipient::class, [ - ['id', $id], + ['id', $share->id], ['class', $recipient->class], ['value', $recipient->value], ['instance', $recipient->instance], @@ -261,12 +261,12 @@ protected function addShareRecipient(ShareAccessContext $accessContext, string $ * @return SharingShare */ #[Override] - protected function removeShareRecipient(ShareAccessContext $accessContext, string $id, ShareRecipient $recipient): array { + protected function removeShareRecipient(ShareAccessContext $accessContext, Share $share, ShareRecipient $recipient): array { $stdout = $this->runCommand( $accessContext, RemoveShareRecipient::class, [ - ['id', $id], + ['id', $share->id], ['class', $recipient->class], ['value', $recipient->value], ['instance', $recipient->instance], @@ -281,12 +281,12 @@ protected function removeShareRecipient(ShareAccessContext $accessContext, strin * @return SharingShare */ #[Override] - protected function updateShareRecipientSecret(ShareAccessContext $accessContext, string $id, ShareRecipient $recipient, string $secret): array { + protected function updateShareRecipientSecret(ShareAccessContext $accessContext, Share $share, ShareRecipient $recipient, string $secret): array { $stdout = $this->runCommand( $accessContext, UpdateShareRecipientSecret::class, [ - ['id', $id], + ['id', $share->id], ['class', $recipient->class], ['value', $recipient->value], ['instance', $recipient->instance], @@ -302,12 +302,12 @@ protected function updateShareRecipientSecret(ShareAccessContext $accessContext, * @return SharingShare */ #[Override] - protected function updateShareProperty(ShareAccessContext $accessContext, string $id, ShareProperty $property): array { + protected function updateShareProperty(ShareAccessContext $accessContext, Share $share, ShareProperty $property): array { $stdout = $this->runCommand( $accessContext, UpdateShareProperty::class, [ - ['id', $id], + ['id', $share->id], ['class', $property->class], ['value', $property->value], ], @@ -321,12 +321,12 @@ protected function updateShareProperty(ShareAccessContext $accessContext, string * @return SharingShare */ #[Override] - protected function updateSharePermission(ShareAccessContext $accessContext, string $id, SharePermission $permission): array { + protected function updateSharePermission(ShareAccessContext $accessContext, Share $share, SharePermission $permission): array { $stdout = $this->runCommand( $accessContext, UpdateSharePermission::class, [ - ['id', $id], + ['id', $share->id], ['class', $permission->class], ['enabled', $permission->enabled ? 'true' : 'false'], ], @@ -340,12 +340,12 @@ protected function updateSharePermission(ShareAccessContext $accessContext, stri * @return SharingShare */ #[Override] - protected function selectSharePermissionPreset(ShareAccessContext $accessContext, string $id, string $permissionPresetClass): array { + protected function selectSharePermissionPreset(ShareAccessContext $accessContext, Share $share, string $permissionPresetClass): array { $stdout = $this->runCommand( $accessContext, SelectSharePermissionPreset::class, [ - ['id', $id], + ['id', $share->id], ['permission-preset', $permissionPresetClass], ], [], @@ -355,12 +355,12 @@ protected function selectSharePermissionPreset(ShareAccessContext $accessContext } #[Override] - protected function deleteShare(ShareAccessContext $accessContext, string $id): void { + protected function deleteShare(ShareAccessContext $accessContext, Share $share): void { $this->runCommand( $accessContext, DeleteShare::class, [ - ['id', $id], + ['id', $share->id], ], [], ); diff --git a/apps/sharing/tests/Controller/ApiV1ControllerTest.php b/apps/sharing/tests/Controller/ApiV1ControllerTest.php index 05395007891c8..1a7afe1ff216c 100644 --- a/apps/sharing/tests/Controller/ApiV1ControllerTest.php +++ b/apps/sharing/tests/Controller/ApiV1ControllerTest.php @@ -88,9 +88,9 @@ private function executeRequest(ShareAccessContext $accessContext, Closure $clos } #[Override] - protected function searchRecipients(ShareAccessContext $accessContext, ?array $filterRecipientTypeClasses, string $query, int $limit, int $offset, ?string $id = null): array { + protected function searchRecipients(ShareAccessContext $accessContext, ?array $filterRecipientTypeClasses, string $query, int $limit, int $offset, ?Share $forShare = null): array { /** @psalm-suppress ArgumentTypeCoercion */ - return $this->executeRequest($accessContext, fn (ApiV1Controller $controller): DataResponse => $controller->searchRecipients($filterRecipientTypeClasses, $query, $limit, $offset, $id)); + return $this->executeRequest($accessContext, fn (ApiV1Controller $controller): DataResponse => $controller->searchRecipients($filterRecipientTypeClasses, $query, $limit, $offset, $forShare?->id)); } #[Override] @@ -100,64 +100,64 @@ protected function createShare(ShareAccessContext $accessContext): array { } #[Override] - protected function updateShareState(ShareAccessContext $accessContext, string $id, ShareState $state): array { + protected function updateShareState(ShareAccessContext $accessContext, Share $share, ShareState $state): array { /** @var SharingShare */ - return $this->executeRequest($accessContext, fn (ApiV1Controller $controller): DataResponse => $controller->updateShareState($id, $state->value)); + return $this->executeRequest($accessContext, fn (ApiV1Controller $controller): DataResponse => $controller->updateShareState($share->id, $state->value)); } #[Override] - protected function addShareSource(ShareAccessContext $accessContext, string $id, ShareSource $source): array { + protected function addShareSource(ShareAccessContext $accessContext, Share $share, ShareSource $source): array { /** @var SharingShare */ - return $this->executeRequest($accessContext, fn (ApiV1Controller $controller): DataResponse => $controller->addShareSource($id, $source->class, $source->value)); + return $this->executeRequest($accessContext, fn (ApiV1Controller $controller): DataResponse => $controller->addShareSource($share->id, $source->class, $source->value)); } #[Override] - protected function removeShareSource(ShareAccessContext $accessContext, string $id, ShareSource $source): array { + protected function removeShareSource(ShareAccessContext $accessContext, Share $share, ShareSource $source): array { /** @var SharingShare */ - return $this->executeRequest($accessContext, fn (ApiV1Controller $controller): DataResponse => $controller->removeShareSource($id, $source->class, $source->value)); + return $this->executeRequest($accessContext, fn (ApiV1Controller $controller): DataResponse => $controller->removeShareSource($share->id, $source->class, $source->value)); } #[Override] - protected function addShareRecipient(ShareAccessContext $accessContext, string $id, ShareRecipient $recipient): array { + protected function addShareRecipient(ShareAccessContext $accessContext, Share $share, ShareRecipient $recipient): array { /** @var SharingShare */ - return $this->executeRequest($accessContext, fn (ApiV1Controller $controller): DataResponse => $controller->addShareRecipient($id, $recipient->class, $recipient->value, $recipient->instance)); + return $this->executeRequest($accessContext, fn (ApiV1Controller $controller): DataResponse => $controller->addShareRecipient($share->id, $recipient->class, $recipient->value, $recipient->instance)); } #[Override] - protected function removeShareRecipient(ShareAccessContext $accessContext, string $id, ShareRecipient $recipient): array { + protected function removeShareRecipient(ShareAccessContext $accessContext, Share $share, ShareRecipient $recipient): array { /** @var SharingShare */ - return $this->executeRequest($accessContext, fn (ApiV1Controller $controller): DataResponse => $controller->removeShareRecipient($id, $recipient->class, $recipient->value, $recipient->instance)); + return $this->executeRequest($accessContext, fn (ApiV1Controller $controller): DataResponse => $controller->removeShareRecipient($share->id, $recipient->class, $recipient->value, $recipient->instance)); } #[Override] - protected function updateShareRecipientSecret(ShareAccessContext $accessContext, string $id, ShareRecipient $recipient, string $secret): array { + protected function updateShareRecipientSecret(ShareAccessContext $accessContext, Share $share, ShareRecipient $recipient, string $secret): array { /** @psalm-suppress ArgumentTypeCoercion */ /** @var SharingShare */ - return $this->executeRequest($accessContext, fn (ApiV1Controller $controller): DataResponse => $controller->updateShareRecipientSecret($id, $recipient->class, $recipient->value, $recipient->instance, $secret)); + return $this->executeRequest($accessContext, fn (ApiV1Controller $controller): DataResponse => $controller->updateShareRecipientSecret($share->id, $recipient->class, $recipient->value, $recipient->instance, $secret)); } #[Override] - protected function updateShareProperty(ShareAccessContext $accessContext, string $id, ShareProperty $property): array { + protected function updateShareProperty(ShareAccessContext $accessContext, Share $share, ShareProperty $property): array { /** @var SharingShare */ - return $this->executeRequest($accessContext, fn (ApiV1Controller $controller): DataResponse => $controller->updateShareProperty($id, $property->class, $property->value)); + return $this->executeRequest($accessContext, fn (ApiV1Controller $controller): DataResponse => $controller->updateShareProperty($share->id, $property->class, $property->value)); } #[Override] - protected function updateSharePermission(ShareAccessContext $accessContext, string $id, SharePermission $permission): array { + protected function updateSharePermission(ShareAccessContext $accessContext, Share $share, SharePermission $permission): array { /** @var SharingShare */ - return $this->executeRequest($accessContext, fn (ApiV1Controller $controller): DataResponse => $controller->updateSharePermission($id, $permission->class, $permission->enabled)); + return $this->executeRequest($accessContext, fn (ApiV1Controller $controller): DataResponse => $controller->updateSharePermission($share->id, $permission->class, $permission->enabled)); } #[Override] - protected function selectSharePermissionPreset(ShareAccessContext $accessContext, string $id, string $permissionPresetClass): array { + protected function selectSharePermissionPreset(ShareAccessContext $accessContext, Share $share, string $permissionPresetClass): array { /** @psalm-suppress ArgumentTypeCoercion */ /** @var SharingShare */ - return $this->executeRequest($accessContext, fn (ApiV1Controller $controller): DataResponse => $controller->selectSharePermissionPreset($id, $permissionPresetClass)); + return $this->executeRequest($accessContext, fn (ApiV1Controller $controller): DataResponse => $controller->selectSharePermissionPreset($share->id, $permissionPresetClass)); } #[Override] - protected function deleteShare(ShareAccessContext $accessContext, string $id): void { - $this->executeRequest($accessContext, fn (ApiV1Controller $controller): DataResponse => $controller->deleteShare($id)); + protected function deleteShare(ShareAccessContext $accessContext, Share $share): void { + $this->executeRequest($accessContext, fn (ApiV1Controller $controller): DataResponse => $controller->deleteShare($share->id)); } #[Override] diff --git a/lib/private/Sharing/SharingBackend.php b/lib/private/Sharing/SharingBackend.php index c57ffbdd6bcff..e8cd285e50389 100644 --- a/lib/private/Sharing/SharingBackend.php +++ b/lib/private/Sharing/SharingBackend.php @@ -136,7 +136,10 @@ public function addShareSource(string $id, ShareSource $source): void { ->executeStatement(); } catch (Exception $exception) { if ($exception instanceof \OCP\DB\Exception && $exception->getReason() === \OCP\DB\Exception::REASON_UNIQUE_CONSTRAINT_VIOLATION) { - throw new ShareInvalidException('Tried to add share source that already exists: ' . $source->class . ' ' . $source->value, $this->l10n->t('The share already contains the source.'), previous: $exception); + throw new ShareInvalidException( + 'Tried to add share source that already exists: ' . $source->class . ' ' . $source->value, + $this->l10n->t('The share already contains the source.'), previous: $exception + ); } throw $exception; @@ -214,7 +217,10 @@ public function addShareRecipient(string $id, ShareRecipient $recipient): void { ->executeStatement(); } catch (Exception $exception) { if ($exception instanceof \OCP\DB\Exception && $exception->getReason() === \OCP\DB\Exception::REASON_UNIQUE_CONSTRAINT_VIOLATION) { - throw new ShareInvalidException('Tried to add share recipient that already exists: ' . $recipient->class . ' ' . $recipient->value . ' ' . ($recipient->instance ?? 'local'), $this->l10n->t('The share already contains the recipient.'), previous: $exception); + throw new ShareInvalidException( + 'Tried to add share recipient that already exists: ' . $recipient->class . ' ' . $recipient->value . ' ' . ($recipient->instance ?? 'local'), + $this->l10n->t('The share already contains the recipient.'), previous: $exception + ); } throw $exception; @@ -227,7 +233,9 @@ public function removeShareRecipient(string $id, ShareRecipient $recipient): voi $rowCount = $qb ->delete('sharing_share_recipients') ->where($qb->expr()->eq('share_id', $qb->createNamedParameter($id))) - ->andWhere($qb->expr()->eq('recipient_class_id', $qb->createNamedParameter($this->classMapper->getClassId($recipient->class), IQueryBuilder::PARAM_INT))) + ->andWhere( + $qb->expr()->eq('recipient_class_id', $qb->createNamedParameter($this->classMapper->getClassId($recipient->class), IQueryBuilder::PARAM_INT)) + ) ->andWhere($qb->expr()->eq('recipient_value', $qb->createNamedParameter($recipient->value))) ->andWhere( $recipient->instance === null @@ -246,7 +254,9 @@ public function onRecipientDeleted(ShareRecipient $recipient): array { $result = $qb ->selectDistinct('share_id') ->from('sharing_share_recipients') - ->where($qb->expr()->eq('recipient_class_id', $qb->createNamedParameter($this->classMapper->getClassId($recipient->class), IQueryBuilder::PARAM_INT))) + ->where( + $qb->expr()->eq('recipient_class_id', $qb->createNamedParameter($this->classMapper->getClassId($recipient->class), IQueryBuilder::PARAM_INT)) + ) ->andWhere($qb->expr()->eq('recipient_value', $qb->createNamedParameter($recipient->value))) ->andWhere( $recipient->instance === null @@ -266,7 +276,9 @@ public function onRecipientDeleted(ShareRecipient $recipient): array { $qb = $this->connection->getQueryBuilder(); $qb ->delete('sharing_share_recipients') - ->where($qb->expr()->eq('recipient_class_id', $qb->createNamedParameter($this->classMapper->getClassId($recipient->class), IQueryBuilder::PARAM_INT))) + ->where( + $qb->expr()->eq('recipient_class_id', $qb->createNamedParameter($this->classMapper->getClassId($recipient->class), IQueryBuilder::PARAM_INT)) + ) ->andWhere($qb->expr()->eq('recipient_value', $qb->createNamedParameter($recipient->value))) ->andWhere( $recipient->instance === null @@ -330,7 +342,9 @@ public function updateShareRecipientSecret(string $id, ShareRecipient $recipient ->update('sharing_share_recipients') ->set('recipient_secret', $qb->createNamedParameter($secret)) ->where($qb->expr()->eq('share_id', $qb->createNamedParameter($id))) - ->andWhere($qb->expr()->eq('recipient_class_id', $qb->createNamedParameter($this->classMapper->getClassId($recipient->class), IQueryBuilder::PARAM_INT))) + ->andWhere( + $qb->expr()->eq('recipient_class_id', $qb->createNamedParameter($this->classMapper->getClassId($recipient->class), IQueryBuilder::PARAM_INT)) + ) ->andWhere($qb->expr()->eq('recipient_value', $qb->createNamedParameter($recipient->value))) ->andWhere( $recipient->instance === null @@ -384,7 +398,11 @@ public function updateShareProperty(string $id, ShareProperty $property): void { ->select('sp.property_value') ->from('sharing_share_properties', 'sp') ->where($qb->expr()->eq('sp.share_id', $qb->createNamedParameter($id))) - ->andWhere($qb->expr()->eq('sp.property_class_id', $qb->createNamedParameter($this->classMapper->getClassId($property->class), IQueryBuilder::PARAM_INT))); + ->andWhere( + $qb->expr()->eq( + 'sp.property_class_id', $qb->createNamedParameter($this->classMapper->getClassId($property->class), IQueryBuilder::PARAM_INT) + ) + ); /** @var string|false $oldValue */ $oldValue = $qb->executeQuery()->fetchOne(); @@ -400,7 +418,9 @@ public function updateShareProperty(string $id, ShareProperty $property): void { ->update('sharing_share_properties') ->set('property_value', $qb->createNamedParameter($value)) ->where($qb->expr()->eq('share_id', $qb->createNamedParameter($id))) - ->andWhere($qb->expr()->eq('property_class_id', $qb->createNamedParameter($this->classMapper->getClassId($property->class), IQueryBuilder::PARAM_INT))) + ->andWhere( + $qb->expr()->eq('property_class_id', $qb->createNamedParameter($this->classMapper->getClassId($property->class), IQueryBuilder::PARAM_INT)) + ) ->executeStatement(); if ($rowCount === 0) { throw new ShareNotFoundException(); @@ -435,7 +455,9 @@ public function updateSharePermission(string $id, SharePermission $permission): ->update('sharing_share_permissions') ->set('permission_enabled', $qb->createNamedParameter($permission->enabled, IQueryBuilder::PARAM_BOOL)) ->where($qb->expr()->eq('share_id', $qb->createNamedParameter($id))) - ->andWhere($qb->expr()->eq('permission_class_id', $qb->createNamedParameter($this->classMapper->getClassId($permission->class), IQueryBuilder::PARAM_INT))) + ->andWhere( + $qb->expr()->eq('permission_class_id', $qb->createNamedParameter($this->classMapper->getClassId($permission->class), IQueryBuilder::PARAM_INT)) + ) ->executeStatement(); if ($rowCount === 0) { throw new ShareNotFoundException(); @@ -492,7 +514,9 @@ public function getShare(ShareAccessContext $accessContext, string $id): Share { } #[\Override] - public function getShares(ShareAccessContext $accessContext, ?string $filterSourceTypeClass, ?string $filterSourceTypeValue, ?string $lastShareID, ?int $limit): array { + public function getShares( + ShareAccessContext $accessContext, ?string $filterSourceTypeClass, ?string $filterSourceTypeValue, ?string $lastShareID, ?int $limit, + ): array { return $this->list($accessContext, null, $filterSourceTypeClass, $filterSourceTypeValue, $lastShareID, $limit); } @@ -563,7 +587,10 @@ private function hideDisabledUserShares(): bool { * @param ?non-empty-string $filterSourceTypeValue * @return list */ - private function list(ShareAccessContext $accessContext, ?string $filterShareID, ?string $filterSourceTypeClass, ?string $filterSourceTypeValue, ?string $lastShareID, ?int $limit): array { + private function list( + ShareAccessContext $accessContext, ?string $filterShareID, ?string $filterSourceTypeClass, ?string $filterSourceTypeValue, ?string $lastShareID, + ?int $limit, + ): array { /** @var array, list> $recipientTypeValues */ $recipientTypeValues = []; @@ -588,18 +615,25 @@ private function list(ShareAccessContext $accessContext, ?string $filterShareID, // Do not add a query if no recipients matched, otherwise all shares will be returned. if ($recipientTypeValues !== []) { $qb = $this->connection->getQueryBuilder(); - $qb->innerJoin('s', 'sharing_share_recipients', 'sr', $qb->expr()->andX( - $qb->expr()->eq('s.state', $qb->createNamedParameter(ShareState::Active->value)), - $qb->expr()->eq('s.id', 'sr.share_id'), - )); + $qb->innerJoin( + 's', 'sharing_share_recipients', 'sr', $qb->expr()->andX( + $qb->expr()->eq('s.state', $qb->createNamedParameter(ShareState::Active->value)), + $qb->expr()->eq('s.id', 'sr.share_id'), + ) + ); foreach ($recipientTypeValues as $recipientTypeClass => $recipientValues) { - $qb->orWhere($qb->expr()->andX( - $qb->expr()->eq('sr.recipient_class_id', $qb->createNamedParameter($this->classMapper->getClassId($recipientTypeClass), IQueryBuilder::PARAM_INT)), - // TODO: Add chunking - $qb->expr()->in('sr.recipient_value', $qb->createNamedParameter($recipientValues, IQueryBuilder::PARAM_STR_ARRAY)), - $qb->expr()->isNull('sr.recipient_instance'), - )); + $qb->orWhere( + $qb->expr()->andX( + $qb->expr()->eq( + 'sr.recipient_class_id', + $qb->createNamedParameter($this->classMapper->getClassId($recipientTypeClass), IQueryBuilder::PARAM_INT) + ), + // TODO: Add chunking + $qb->expr()->in('sr.recipient_value', $qb->createNamedParameter($recipientValues, IQueryBuilder::PARAM_STR_ARRAY)), + $qb->expr()->isNull('sr.recipient_instance'), + ) + ); } $queries[] = $qb; @@ -607,11 +641,13 @@ private function list(ShareAccessContext $accessContext, ?string $filterShareID, if ($filterShareID !== null && $accessContext->secret !== null) { $qb = $this->connection->getQueryBuilder(); - $qb->innerJoin('s', 'sharing_share_recipients', 'sr', $qb->expr()->andX( - $qb->expr()->eq('s.state', $qb->createNamedParameter(ShareState::Active->value)), - $qb->expr()->eq('s.id', 'sr.share_id'), - $qb->expr()->eq('sr.recipient_secret', $qb->createNamedParameter($accessContext->secret)), - )); + $qb->innerJoin( + 's', 'sharing_share_recipients', 'sr', $qb->expr()->andX( + $qb->expr()->eq('s.state', $qb->createNamedParameter(ShareState::Active->value)), + $qb->expr()->eq('s.id', 'sr.share_id'), + $qb->expr()->eq('sr.recipient_secret', $qb->createNamedParameter($accessContext->secret)), + ) + ); $queries[] = $qb; } @@ -639,7 +675,9 @@ private function list(ShareAccessContext $accessContext, ?string $filterShareID, if ($filterSourceTypeClass !== null) { $sourceTypeFilters = [ $qb->expr()->eq('s.id', 'ss.share_id'), - $qb->expr()->eq('ss.source_class_id', $qb->createNamedParameter($this->classMapper->getClassId($filterSourceTypeClass), IQueryBuilder::PARAM_INT)), + $qb->expr()->eq( + 'ss.source_class_id', $qb->createNamedParameter($this->classMapper->getClassId($filterSourceTypeClass), IQueryBuilder::PARAM_INT) + ), ]; if ($filterSourceTypeValue !== null) { @@ -666,7 +704,9 @@ private function list(ShareAccessContext $accessContext, ?string $filterShareID, $ownerInstance = $row['owner_instance']; /** @psalm-suppress PossiblyNullReference The share is automatically deleted, when the owner is deleted. */ - if ($ownerInstance === null && !$accessContext->overrideChecks && $this->hideDisabledUserShares() && !$this->userManager->get($ownerUserId)->isEnabled()) { + if ($ownerInstance === null && !$accessContext->overrideChecks && $this->hideDisabledUserShares() && !$this->userManager->get( + $ownerUserId + )->isEnabled()) { continue; } @@ -795,7 +835,9 @@ private function list(ShareAccessContext $accessContext, ?string $filterShareID, $initiatorInstance = $row['initiator_instance']; /** @psalm-suppress PossiblyNullReference The initiator is automatically promoted to the owner, when the initiator is deleted. */ - if ($initiatorInstance === null && !$accessContext->overrideChecks && !$shares[$id]['owner']->isCurrentUser($accessContext) && $this->hideDisabledUserShares() && !$this->userManager->get($initiatorUserId)->isEnabled()) { + if ($initiatorInstance === null && !$accessContext->overrideChecks && !$shares[$id]['owner']->isCurrentUser( + $accessContext + ) && $this->hideDisabledUserShares() && !$this->userManager->get($initiatorUserId)->isEnabled()) { continue; } @@ -912,7 +954,9 @@ private function list(ShareAccessContext $accessContext, ?string $filterShareID, continue; } - if (array_intersect($registryPropertyTypeCompatibleRecipientTypeClasses[$propertyTypeClass], array_keys($shareRecipientTypeClasses[$id])) === []) { + if (array_intersect( + $registryPropertyTypeCompatibleRecipientTypeClasses[$propertyTypeClass], array_keys($shareRecipientTypeClasses[$id]) + ) === []) { // Skip properties that are currently not compatible, but don't remove them. continue; } @@ -929,28 +973,10 @@ private function list(ShareAccessContext $accessContext, ?string $filterShareID, } } - $registrySourceTypePermissionTypeClasses = $this->registry->getSourceTypePermissionTypeClasses(); - $registryGenericPermissionTypeClasses = $this->registry->getGenericPermissionTypeClasses(); - - /** @var array, bool>> $shareCompatiblePermissionTypeClasses */ - $shareCompatiblePermissionTypeClasses = []; - foreach (array_keys($shares) as $id) { - $id = (string)$id; - $shareCompatiblePermissionTypeClasses[$id] = []; - foreach ($registryGenericPermissionTypeClasses as $permissionTypeClass) { - $shareCompatiblePermissionTypeClasses[$id][$permissionTypeClass] = true; - } - - if (isset($shareSourceTypeClasses[$id])) { - foreach (array_keys($shareSourceTypeClasses[$id]) as $shareSourceTypeClass) { - if (isset($registrySourceTypePermissionTypeClasses[$shareSourceTypeClass])) { - foreach ($registrySourceTypePermissionTypeClasses[$shareSourceTypeClass] as $permissionTypeClass) { - $shareCompatiblePermissionTypeClasses[$id][$permissionTypeClass] = true; - } - } - } - } - } + $shareCompatiblePermissionTypeClasses = array_map( + fn (array $shareData): array => array_flip($this->getShareCompatiblePermissionTypeClasses($shareData['sources'])), + $shares + ); foreach ($chunks as $chunk) { $qb = $this->connection->getQueryBuilder(); @@ -965,8 +991,7 @@ private function list(ShareAccessContext $accessContext, ?string $filterShareID, $result = $qb->executeQuery(); foreach ($result->fetchAll() as $row) { - /** @var non-empty-string $id */ - $id = (string)$row['share_id']; + $id = (int)$row['share_id']; /** @var class-string $permissionTypeClass */ $permissionTypeClass = $this->classMapper->getClassName((int)$row['permission_class_id']); @@ -992,7 +1017,9 @@ private function list(ShareAccessContext $accessContext, ?string $filterShareID, ), $shares); if (!$accessContext->overrideChecks) { - $filterPropertyTypes = array_filter($registryPropertyTypes, static fn (ISharePropertyType $propertyType): bool => $propertyType instanceof ISharePropertyTypeFilter); + $filterPropertyTypes = array_filter( + $registryPropertyTypes, static fn (ISharePropertyType $propertyType): bool => $propertyType instanceof ISharePropertyTypeFilter + ); if ($filterPropertyTypes !== []) { $shares = array_filter($shares, static function (Share $share) use ($accessContext, $filterPropertyTypes): bool { if ($share->owner->isCurrentUser($accessContext)) { @@ -1010,34 +1037,50 @@ private function list(ShareAccessContext $accessContext, ?string $filterShareID, } } + if ($shares !== []) { + $shares = $this->ensureDefaults($shares); + } + + return array_values($shares); + } + + /** + * @param ShareSource[] $sources + * @return list> + */ + private function getShareCompatiblePermissionTypeClasses(array $sources): array { + $shareSourceTypeClasses = array_map(fn (ShareSource $source): string => $source->class, $sources); + return $this->registry->getCompatiblePermissionTypeClasses($shareSourceTypeClasses); + } + + #[\Override] + public function ensureDefaults(array $shares): array { $defaultSet = false; - foreach (array_keys($shares) as $id) { - $id = (string)$id; - foreach (array_keys($registryPropertyTypes) as $propertyTypeClass) { - $share = $shares[$id]; - if ( - !isset($share->properties[$propertyTypeClass]) - && isset($shareSourceTypeClasses[$id], $shareRecipientTypeClasses[$id]) - && array_intersect($registryPropertyTypeCompatibleSourceTypeClasses[$propertyTypeClass], array_keys($shareSourceTypeClasses[$id])) !== [] - && array_intersect($registryPropertyTypeCompatibleRecipientTypeClasses[$propertyTypeClass], array_keys($shareRecipientTypeClasses[$id])) !== []) { - $shares[$id] = $this->createSharePropertyDefaultValue($shares[$id], $propertyTypeClass); + foreach ($shares as &$share) { + $shareSourceTypeClasses = array_map(fn (ShareSource $source): string => $source->class, $share->sources); + $shareRecipientTypeClasses = array_map(fn (ShareRecipient $recipient): string => $recipient->class, $share->recipients); + $shareCompatiblePropertyClasses = $this->registry->getCompatiblePropertyTypeClasses($shareSourceTypeClasses, $shareRecipientTypeClasses); + + foreach ($shareCompatiblePropertyClasses as $propertyTypeClass) { + if (!isset($share->properties[$propertyTypeClass])) { + $share = $this->createSharePropertyDefaultValue($share, $propertyTypeClass); $defaultSet = true; } } } - foreach (array_keys($shares) as $id) { - foreach (array_keys($shareCompatiblePermissionTypeClasses[$id]) as $permissionTypeClass) { - $share = $shares[$id]; + foreach ($shares as &$share) { + $shareCompatiblePermissionTypeClasses = $this->getShareCompatiblePermissionTypeClasses($share->sources); + + foreach ($shareCompatiblePermissionTypeClasses as $permissionTypeClass) { if (!isset($share->permissions[$permissionTypeClass])) { - $shares[$id] = $this->createSharePermissionDefaultValue($shares[$id], $permissionTypeClass); + $share = $this->createSharePermissionDefaultValue($share, $permissionTypeClass); $defaultSet = true; } } } - $shares = array_values($shares); - if ($defaultSet && $shares !== []) { + if ($defaultSet) { $event = new SharesDefaultSetEvent($shares); $this->eventDispatcher->dispatchTyped($event); $shares = $event->getShares(); @@ -1064,7 +1107,7 @@ public function createSharePropertyDefaultValue(Share $share, string $propertyTy $properties = $share->properties; $properties[$propertyTypeClass] = $property; - $share = new Share( + return new Share( $share->id, $share->owner, $timestamp, @@ -1074,8 +1117,6 @@ public function createSharePropertyDefaultValue(Share $share, string $propertyTy $properties, $share->permissions, ); - - return $share; } /** @@ -1096,7 +1137,7 @@ public function createSharePermissionDefaultValue(Share $share, string $permissi $permissions = $share->permissions; $permissions[$permissionTypeClass] = $permission; - $share = new Share( + return new Share( $share->id, $share->owner, $timestamp, @@ -1106,8 +1147,6 @@ public function createSharePermissionDefaultValue(Share $share, string $permissi $share->properties, $permissions, ); - - return $share; } private static function parseTimestamp(string $timestampMs): \DateTimeImmutable { diff --git a/lib/private/Sharing/SharingManager.php b/lib/private/Sharing/SharingManager.php index 4c2b0f2ee11ca..468be32cb0dee 100644 --- a/lib/private/Sharing/SharingManager.php +++ b/lib/private/Sharing/SharingManager.php @@ -78,7 +78,9 @@ public function __construct( } #[\Override] - public function searchRecipients(ShareAccessContext $accessContext, ?array $filterRecipientTypeClasses, string $query, int $limit, int $offset, ?string $id = null): array { + public function searchRecipients( + ShareAccessContext $accessContext, ?array $filterRecipientTypeClasses, string $query, int $limit, int $offset, ?Share $forShare = null, + ): array { $recipientTypes = $this->registry->getRecipientTypes(); if ($filterRecipientTypeClasses !== null) { @@ -97,28 +99,36 @@ public function searchRecipients(ShareAccessContext $accessContext, ?array $filt $recipientTypes = $filteredRecipientTypes; } else { - $recipientTypes = array_values(array_filter( - $recipientTypes, - static fn (IShareRecipientType $recipientType): bool => $recipientType instanceof IShareRecipientTypeSearch, - )); + $recipientTypes = array_values( + array_filter( + $recipientTypes, + static fn (IShareRecipientType $recipientType): bool => $recipientType instanceof IShareRecipientTypeSearch, + ) + ); } - $results = array_merge(...array_map( - static fn (IShareRecipientTypeSearch $recipientType): array => $recipientType->searchRecipients($accessContext, $query, $limit, $offset), - $recipientTypes, - )); + $results = array_merge( + ...array_map( + static fn (IShareRecipientTypeSearch $recipientType): array => $recipientType->searchRecipients($accessContext, $query, $limit, $offset), + $recipientTypes, + ) + ); - if ($id !== null) { + if ($forShare instanceof Share) { // Do not create a new access context with overridden checks, because it could leak the existence of shares and share recipients. - $share = $this->getShare($accessContext, $id); $recipients = []; - foreach ($share->recipients as $recipient) { + foreach ($forShare->recipients as $recipient) { $recipients[$recipient->class] ??= []; $recipients[$recipient->class][$recipient->instance ?? ''] ??= []; $recipients[$recipient->class][$recipient->instance ?? ''][$recipient->value] = true; } - $results = array_values(array_filter($results, static fn (ShareRecipient $recipient): bool => !isset($recipients[$recipient->class][$recipient->instance ?? ''][$recipient->value]))); + $results = array_values( + array_filter( + $results, + static fn (ShareRecipient $recipient): bool => !isset($recipients[$recipient->class][$recipient->instance ?? ''][$recipient->value]) + ) + ); } return $results; @@ -137,7 +147,7 @@ public function getTime(): \DateTimeImmutable { } #[\Override] - public function createShare(ShareAccessContext $accessContext): string { + public function createShare(ShareAccessContext $accessContext): Share { if (!($currentUser = $accessContext->currentUser) instanceof IUser) { throw new RuntimeException('No user present to create a share'); } @@ -148,9 +158,9 @@ public function createShare(ShareAccessContext $accessContext): string { $lastUpdated = $this->getTime(); $this->backend->createShare($id, new ShareUser($currentUser->getUID(), null), $lastUpdated); - $this->processShareUpdates([$id]); + [$share] = $this->processShareUpdates([$id]); - return $id; + return $share; } #[\Override] @@ -174,32 +184,40 @@ public function onOwnerDeleted(ShareAccessContext $accessContext, ShareUser $own } #[\Override] - public function updateShareState(ShareAccessContext $accessContext, string $id, ShareState $state): void { + public function updateShareState(ShareAccessContext $accessContext, Share $share, ShareState $state): Share { $this->assertInTransaction(); - $this->backend->setLastUpdated([$id], $this->getTime()); + $time = $this->getTime(); + $this->backend->setLastUpdated([$share->id], $time); - $owner = $this->backend->getShareOwner($id); - $this->validateShareOwnerOperation($accessContext, $owner); + $this->validateShareOwnerOperation($accessContext, $share->owner); if ($state === ShareState::Active) { - $share = $this->getShare($accessContext, $id); $this->assertShareCanBeActive($share); } - $this->backend->updateShareState($id, $state); + $this->backend->updateShareState($share->id, $state); - $this->processShareUpdates([$id]); + $share = new Share( + $share->id, + $share->owner, + $time, + $state, + $share->sources, + $share->recipients, + $share->properties, + $share->permissions, + ); + + [$share] = $this->processShareUpdates([$share]); + return $share; } #[\Override] - public function addShareSource(ShareAccessContext $accessContext, string $id, ShareSource $source): void { + public function addShareSource(ShareAccessContext $accessContext, Share $share, ShareSource $source): Share { $this->assertInTransaction(); - $this->backend->setLastUpdated([$id], $this->getTime()); - - $owner = $this->backend->getShareOwner($id); - $this->validateShareOwnerOperation($accessContext, $owner); + $this->validateShareOwnerOperation($accessContext, $share->owner); if (($sourceType = $this->registry->getSourceTypes()[$source->class] ?? null) === null) { throw new RuntimeException('The source type is not registered: ' . $source->class); @@ -209,13 +227,14 @@ public function addShareSource(ShareAccessContext $accessContext, string $id, Sh throw new ShareInvalidException('Invalid source: ' . $source->value . ' ' . $source->class, $this->l10n->t('The source does not exist.')); } - $share = $this->getShare($accessContext, $id); + $time = $this->getTime(); + $sources = $share->sources; $sources[] = $source; $share = new Share( $share->id, $share->owner, - $share->lastUpdated, + $time, $share->state, $sources, $share->recipients, @@ -227,24 +246,50 @@ public function addShareSource(ShareAccessContext $accessContext, string $id, Sh $this->validateInteraction($accessContext, $share); } - $this->backend->addShareSource($id, $source); + $this->backend->setLastUpdated([$share->id], $time); + + $this->backend->addShareSource($share->id, $source); + + [$share] = $this->backend->ensureDefaults([$share]); - // The modified share object has to be used instead of fetching the share again, because it would trigger the insertion of default values prematurely. - $this->processShareUpdates([$share]); + [$share] = $this->processShareUpdates([$share]); + return $share; } #[\Override] - public function removeShareSource(ShareAccessContext $accessContext, string $id, ShareSource $source): void { + public function removeShareSource(ShareAccessContext $accessContext, Share $share, ShareSource $source): Share { $this->assertInTransaction(); - $this->backend->setLastUpdated([$id], $this->getTime()); + $this->validateShareOwnerOperation($accessContext, $share->owner); + + $time = $this->getTime(); + $this->backend->setLastUpdated([$share->id], $time); + + $this->backend->removeShareSource($share->id, $source); + + $sources = array_values(array_filter($share->sources, static fn (ShareSource $shareSource): bool => !$shareSource->equals($source))); + + $sourceClasses = array_map(static fn (ShareSource $source): string => $source->class, $sources); + $recipientClasses = array_map(static fn (ShareRecipient $recipient): string => $recipient->class, $share->recipients); + $compatiblePropertyClasses = $this->registry->getCompatiblePropertyTypeClasses($sourceClasses, $recipientClasses); + $compatiblePermissionsClasses = $this->registry->getCompatiblePermissionTypeClasses($sourceClasses); - $owner = $this->backend->getShareOwner($id); - $this->validateShareOwnerOperation($accessContext, $owner); + $properties = array_intersect_key($share->properties, array_flip($compatiblePropertyClasses)); + $permissions = array_intersect_key($share->permissions, array_flip($compatiblePermissionsClasses)); - $this->backend->removeShareSource($id, $source); + $share = new Share( + $share->id, + $share->owner, + $time, + $share->state, + $sources, + $share->recipients, + $properties, + $permissions, + ); - $this->processShareUpdates([$id]); + [$share] = $this->processShareUpdates([$share]); + return $share; } #[\Override] @@ -268,22 +313,16 @@ public function onSourceDeleted(ShareAccessContext $accessContext, ShareSource $ } #[\Override] - public function addShareRecipient(ShareAccessContext $accessContext, string $id, ShareRecipient $recipient): void { + public function addShareRecipient(ShareAccessContext $accessContext, Share $share, ShareRecipient $recipient): Share { if (!($currentUser = $accessContext->currentUser) instanceof IUser) { throw new RuntimeException('No current user provided in access context.'); } $this->assertInTransaction(); - $this->backend->setLastUpdated([$id], $this->getTime()); - - $owner = $this->backend->getShareOwner($id); - try { - $this->validateShareOwnerOperation($accessContext, $owner); - $share = null; + $this->validateShareOwnerOperation($accessContext, $share->owner); } catch (ShareOperationForbiddenException) { - $share = $this->getShare($accessContext, $id); $this->validatePermission($share, ReshareSharePermissionType::class); } @@ -292,13 +331,15 @@ public function addShareRecipient(ShareAccessContext $accessContext, string $id, } if (!$recipientType->validateRecipient($recipient->value)) { - throw new ShareInvalidException('Invalid recipient: ' . $recipient->value . ' ' . $recipient->class . ' ' . ($recipient->instance ?? 'local'), $this->l10n->t('The recipient does not exist.')); + throw new ShareInvalidException( + 'Invalid recipient: ' . $recipient->value . ' ' . $recipient->class . ' ' . ($recipient->instance ?? 'local'), + $this->l10n->t('The recipient does not exist.') + ); } - $share ??= $this->getShare($accessContext, $id); $recipients = $share->recipients; $recipients[] = $recipient; - $share = new Share( + $validationShare = new Share( $share->id, $share->owner, $share->lastUpdated, @@ -310,9 +351,12 @@ public function addShareRecipient(ShareAccessContext $accessContext, string $id, ); if (!$accessContext->overrideChecks) { - $this->validateInteraction($accessContext, $share); + $this->validateInteraction($accessContext, $validationShare); } + $time = $this->getTime(); + $this->backend->setLastUpdated([$share->id], $time); + if ($recipient->secret === null || !$recipient->initiator instanceof ShareUser) { $secret = $recipient->secret ?? $this->generateSecret(); $initiator = $recipient->initiator ?? new ShareUser($currentUser->getUID(), null); @@ -326,33 +370,66 @@ public function addShareRecipient(ShareAccessContext $accessContext, string $id, ); } - $this->backend->addShareRecipient($id, $recipient); + $this->backend->addShareRecipient($share->id, $recipient); + + $recipients = $share->recipients; + $recipients[] = $recipient; + $share = new Share( + $share->id, + $share->owner, + $time, + $share->state, + $share->sources, + $recipients, + $share->properties, + $share->permissions, + ); + + [$share] = $this->backend->ensureDefaults([$share]); - // The modified share object has to be used instead of fetching the share again, because it would trigger the insertion of default values prematurely. - $this->processShareUpdates([$share]); + [$share] = $this->processShareUpdates([$share]); + return $share; } #[\Override] - public function removeShareRecipient(ShareAccessContext $accessContext, string $id, ShareRecipient $recipient): void { + public function removeShareRecipient(ShareAccessContext $accessContext, Share $share, ShareRecipient $recipient): Share { $this->assertInTransaction(); $this->assertInTransaction(); - $this->backend->setLastUpdated([$id], $this->getTime()); - - $owner = $this->backend->getShareOwner($id); - try { - $this->validateShareOwnerOperation($accessContext, $owner); + $this->validateShareOwnerOperation($accessContext, $share->owner); } catch (ShareOperationForbiddenException) { - $share = $this->getShare($accessContext, $id); // This does not allow removing own recipients. A user can only reject a share, but not remove it for the recipient. $this->validateReshareOperation($accessContext, $share, $recipient); } - $this->backend->removeShareRecipient($id, $recipient); + $time = $this->getTime(); + $this->backend->setLastUpdated([$share->id], $time); + + $this->backend->removeShareRecipient($share->id, $recipient); + + $recipients = array_values(array_filter($share->recipients, static fn (ShareRecipient $shareRecipient): bool => !$shareRecipient->equals($recipient))); + + $sourceClasses = array_map(static fn (ShareSource $source): string => $source->class, $share->sources); + $recipientClasses = array_map(static fn (ShareRecipient $recipient): string => $recipient->class, $recipients); + $compatiblePropertyClasses = $this->registry->getCompatiblePropertyTypeClasses($sourceClasses, $recipientClasses); + + $properties = array_intersect_key($share->properties, array_flip($compatiblePropertyClasses)); + + $share = new Share( + $share->id, + $share->owner, + $time, + $share->state, + $share->sources, + $recipients, + $properties, + $share->permissions, + ); - $this->processShareUpdates([$id]); + [$share] = $this->processShareUpdates([$share]); + return $share; } #[\Override] @@ -395,18 +472,20 @@ public function onInitiatorDeleted(ShareAccessContext $accessContext, ShareUser $this->processShareUpdates($updatedIds); } + /** + * @psalm-assert-if-true non-empty-string $secret + */ + private function validateShareSecret(string $secret): bool { + return (bool)preg_match('/^[a-z0-9-]{1,32}$/i', $secret); + } + #[\Override] - public function updateShareRecipientSecret(ShareAccessContext $accessContext, string $id, ShareRecipient $recipient, string $secret): void { + public function updateShareRecipientSecret(ShareAccessContext $accessContext, Share $share, ShareRecipient $recipient, string $secret): Share { $this->assertInTransaction(); - $this->backend->setLastUpdated([$id], $this->getTime()); - - $owner = $this->backend->getShareOwner($id); - try { - $this->validateShareOwnerOperation($accessContext, $owner); + $this->validateShareOwnerOperation($accessContext, $share->owner); } catch (ShareOperationForbiddenException) { - $share = $this->getShare($accessContext, $id); $this->validateReshareOperation($accessContext, $share, $recipient); } @@ -418,60 +497,100 @@ public function updateShareRecipientSecret(ShareAccessContext $accessContext, st throw new ShareOperationForbiddenException(); } - if (!preg_match('/^[a-z0-9-]{1,32}$/i', $secret)) { - throw new ShareInvalidException('Invalid secret: ' . $secret, $this->l10n->t('The value must be alphanumeric, 1 to 32 characters long and may contain dashes.')); + if (!$this->validateShareSecret($secret)) { + throw new ShareInvalidException( + 'Invalid secret: ' . $secret, $this->l10n->t('The value must be alphanumeric, 1 to 32 characters long and may contain dashes.') + ); + } + + $time = $this->getTime(); + $this->backend->setLastUpdated([$share->id], $time); + + $this->backend->updateShareRecipientSecret($share->id, $recipient, $secret); + + $recipients = $share->recipients; + foreach ($recipients as &$shareRecipient) { + if ($shareRecipient->equals($recipient)) { + $shareRecipient = new ShareRecipient( + $recipient->class, + $recipient->value, + $recipient->instance, + $secret, + $shareRecipient->initiator, + ); + } } - $this->backend->updateShareRecipientSecret($id, $recipient, $secret); + $share = new Share( + $share->id, + $share->owner, + $time, + $share->state, + $share->sources, + $recipients, + $share->properties, + $share->permissions, + ); - $this->processShareUpdates([$id]); + [$share] = $this->processShareUpdates([$share]); + return $share; } #[\Override] - public function updateShareProperty(ShareAccessContext $accessContext, string $id, ShareProperty $property): void { + public function updateShareProperty(ShareAccessContext $accessContext, Share $share, ShareProperty $property): Share { $this->assertInTransaction(); - $this->backend->setLastUpdated([$id], $this->getTime()); - - $owner = $this->backend->getShareOwner($id); - $this->validateShareOwnerOperation($accessContext, $owner); + $this->validateShareOwnerOperation($accessContext, $share->owner); if (($propertyType = $this->registry->getPropertyTypes()[$property->class] ?? null) === null) { throw new RuntimeException('The property is not registered: ' . $property->class); } - if ($property->value !== null) { - $share = $this->getShare($accessContext, $id); - if (($message = $propertyType->validateValue($this->l10nFactory, $share, $property->value)) !== true) { - throw new ShareInvalidException('Invalid property value: ' . $property->value . ' ' . $property->class, $message); - } + if ($property->value !== null && ($message = $propertyType->validateValue($this->l10nFactory, $share, $property->value)) !== true) { + throw new ShareInvalidException('Invalid property value: ' . $property->value . ' ' . $property->class, $message); } - $this->backend->updateShareProperty($id, $property); + $time = $this->getTime(); + $this->backend->setLastUpdated([$share->id], $time); + + $this->backend->updateShareProperty($share->id, $property); - $this->processShareUpdates([$id]); + $properties = $share->properties; + $properties[$property->class] = $property; + + $share = new Share( + $share->id, + $share->owner, + $time, + $share->state, + $share->sources, + $share->recipients, + $properties, + $share->permissions, + ); + + [$share] = $this->processShareUpdates([$share->id]); + return $share; } #[\Override] - public function updateSharePermission(ShareAccessContext $accessContext, string $id, SharePermission $permission): void { + public function updateSharePermission(ShareAccessContext $accessContext, Share $share, SharePermission $permission): Share { $this->assertInTransaction(); - $this->backend->setLastUpdated([$id], $this->getTime()); - - $owner = $this->backend->getShareOwner($id); - $this->validateShareOwnerOperation($accessContext, $owner); + $this->validateShareOwnerOperation($accessContext, $share->owner); if (!isset($this->registry->getPermissionTypes()[$permission->class])) { throw new RuntimeException('The permission type is not registered: ' . $permission->class); } - $share = $this->getShare($accessContext, $id); + $time = $this->getTime(); + $permissions = $share->permissions; $permissions[$permission->class] = $permission; $share = new Share( $share->id, $share->owner, - $share->lastUpdated, + $time, $share->state, $share->sources, $share->recipients, @@ -483,45 +602,65 @@ public function updateSharePermission(ShareAccessContext $accessContext, string $this->validateInteraction($accessContext, $share); } - $this->backend->updateSharePermission($id, $permission); + $this->backend->setLastUpdated([$share->id], $time); + + $this->backend->updateSharePermission($share->id, $permission); - // The modified share object has to be used instead of fetching the share again, because it would trigger the insertion of default values prematurely. - $this->processShareUpdates([$share]); + [$share] = $this->processShareUpdates([$share]); + return $share; } #[\Override] - public function selectSharePermissionPreset(ShareAccessContext $accessContext, string $id, string $permissionPresetClass): void { + public function selectSharePermissionPreset(ShareAccessContext $accessContext, Share $share, string $permissionPresetClass): Share { $this->assertInTransaction(); - $this->backend->setLastUpdated([$id], $this->getTime()); - - $owner = $this->backend->getShareOwner($id); - $this->validateShareOwnerOperation($accessContext, $owner); + $this->validateShareOwnerOperation($accessContext, $share->owner); if (($this->registry->getPermissionPresetCompatiblePermissionTypeClasses()[$permissionPresetClass] ?? null) === null) { throw new RuntimeException('The permission preset is not registered: ' . $permissionPresetClass); } - $this->backend->selectSharePermissionPreset($id, $permissionPresetClass); + $time = $this->getTime(); + $this->backend->setLastUpdated([$share->id], $time); - $this->processShareUpdates([$id]); + $this->backend->selectSharePermissionPreset($share->id, $permissionPresetClass); + + $sourceClasses = array_map(static fn (ShareSource $source): string => $source->class, $share->sources); + $allPermissionClasses = $this->registry->getCompatiblePermissionTypeClasses($sourceClasses); + $permissionPresetCompatiblePermissionTypeClasses = $this->registry->getPermissionPresetCompatiblePermissionTypeClasses()[$permissionPresetClass]; + $presetPermissions = array_combine($allPermissionClasses, array_map(fn (string $class): SharePermission => new SharePermission( + $class, + in_array($class, $permissionPresetCompatiblePermissionTypeClasses), + ), $allPermissionClasses)); + + $share = new Share( + $share->id, + $share->owner, + $time, + $share->state, + $share->sources, + $share->recipients, + $share->properties, + $presetPermissions, + ); + + [$share] = $this->processShareUpdates([$share]); + return $share; } #[\Override] - public function deleteShare(ShareAccessContext $accessContext, string $id): void { + public function deleteShare(ShareAccessContext $accessContext, Share $share): void { $this->assertInTransaction(); - $owner = $this->backend->getShareOwner($id); - // No need to update the last updated timestamp, because the share will be deleted anyway. - $this->validateShareOwnerOperation($accessContext, $owner); + $this->validateShareOwnerOperation($accessContext, $share->owner); - $this->backend->deleteShare($id); + $this->backend->deleteShare($share->id); $legacyBackend = $this->registry->getLegacyBackend(); if ($legacyBackend instanceof ISharingLegacyBackend) { - $legacyBackend->deleteShare($id); + $legacyBackend->deleteShare($share->id); } } @@ -533,7 +672,9 @@ public function getShare(ShareAccessContext $accessContext, string $id): Share { } #[\Override] - public function getShares(ShareAccessContext $accessContext, ?string $filterSourceTypeClass, ?string $filterSourceTypeValue, ?string $lastShareID, ?int $limit): array { + public function getShares( + ShareAccessContext $accessContext, ?string $filterSourceTypeClass, ?string $filterSourceTypeValue, ?string $lastShareID, ?int $limit, + ): array { $this->assertInTransaction(); return $this->backend->getShares($accessContext, $filterSourceTypeClass, $filterSourceTypeValue, $lastShareID, $limit); @@ -542,10 +683,13 @@ public function getShares(ShareAccessContext $accessContext, ?string $filterSour #[\Override] public function handle(Event $event): void { if ($event instanceof SharesDefaultSetEvent) { - $this->processShareUpdates($event->getShares()); + $shares = $event->getShares(); + $keys = array_keys($shares); + $shares = $this->processShareUpdates(array_values($shares)); + $event->setShares(array_combine($keys, $shares)); } - if ($event instanceof BeforeUserDeletedEvent) { + if ($event instanceof BeforeUserDeletedEvent) { $shareUser = new ShareUser($event->getUser()->getUID(), null); try { @@ -620,7 +764,9 @@ private function validateReshareOperation(ShareAccessContext $accessContext, Sha * @throws ShareInvalidException */ private function validateInteraction(ShareAccessContext $accessContext, Share $share): void { - $action = new ShareAction(null, array_values(array_map(static fn (SharePermission $permission): string => $permission->class, $share->getEnabledPermissions()))); + $action = new ShareAction( + null, array_values(array_map(static fn (SharePermission $permission): string => $permission->class, $share->getEnabledPermissions())) + ); $usersToCheck = []; if ($share->owner->instance === null && ($ownerUser = $this->userManager->get($share->owner->userId)) instanceof IUser) { @@ -689,7 +835,10 @@ private function assertShareCanBeActive(Share $share): void { foreach ($share->properties as $propertyTypeClass => $property) { $propertyType = $propertyTypes[$propertyTypeClass]; if ($property->value === null && $propertyType->isRequired($share)) { - throw new ShareInvalidException('Missing value for required property: ' . $propertyTypeClass, $this->l10n->t('You need to set a value for the %s', [$propertyType->getDisplayName($this->l10nFactory)])); + throw new ShareInvalidException( + 'Missing value for required property: ' . $propertyTypeClass, + $this->l10n->t('You need to set a value for the %s', [$propertyType->getDisplayName($this->l10nFactory)]) + ); } } } @@ -739,7 +888,9 @@ private function processShareUpdates(array $sharesOrIds): array { $compatibleRecipientTypes = array_fill_keys($legacyBackend->getCompatibleRecipientTypes(), true); foreach ($share->recipients as $recipient) { if (!isset($compatibleRecipientTypes[$recipient->class])) { - throw new RuntimeException('The legacy backend ' . $legacyBackend::class . ' does not support this recipient type: ' . $recipient->class); + throw new RuntimeException( + 'The legacy backend ' . $legacyBackend::class . ' does not support this recipient type: ' . $recipient->class + ); } } @@ -756,11 +907,7 @@ private function processShareUpdates(array $sharesOrIds): array { * @return numeric-string */ public static function timeToMs(\DateTimeImmutable $time): string { - if (method_exists($time, 'getMicrosecond')) { - $micros = (float)$time->getMicrosecond(); - } else { - $micros = (float)$time->format('u'); - } + $micros = method_exists($time, 'getMicrosecond') ? (float)$time->getMicrosecond() : (float)$time->format('u'); $time = (string)floor((float)$time->getTimestamp() * 1000.0 + $micros / 1000.0); if ((float)$time > 0) { diff --git a/lib/private/Sharing/SharingRegistry.php b/lib/private/Sharing/SharingRegistry.php index 85647e18f2452..d22e447f2c69a 100644 --- a/lib/private/Sharing/SharingRegistry.php +++ b/lib/private/Sharing/SharingRegistry.php @@ -325,4 +325,48 @@ public function getPermissionPresetCompatiblePermissionTypeClasses(): array { return $out; } + + #[\Override] + public function getCompatiblePermissionTypeClasses(array $shareSourceTypeClasses): array { + /** @var array, bool> $shareCompatiblePermissionTypeClasses */ + $shareCompatiblePermissionTypeClasses = []; + + foreach ($this->genericPermissionTypes as $permissionTypeClass) { + $shareCompatiblePermissionTypeClasses[$permissionTypeClass] = true; + } + + foreach ($shareSourceTypeClasses as $shareSourceTypeClass) { + if (isset($this->sourceTypePermissionTypes[$shareSourceTypeClass])) { + foreach ($this->sourceTypePermissionTypes[$shareSourceTypeClass] as $permissionTypeClass) { + $shareCompatiblePermissionTypeClasses[$permissionTypeClass] = true; + } + } + } + + return array_keys($shareCompatiblePermissionTypeClasses); + } + + /** + * @return list> + */ + #[\Override] + public function getCompatiblePropertyTypeClasses(array $shareSourceTypeClasses, array $shareRecipientTypeClasses): array { + $registryPropertyTypes = $this->getPropertyTypes(); + $registryPropertyTypeCompatibleSourceTypeClasses = $this->getPropertyTypeCompatibleSourceTypeClasses(); + $registryPropertyTypeCompatibleRecipientTypeClasses = $this->getPropertyTypeCompatibleRecipientTypes(); + + /** @var list> $compatiblePropertyTypes */ + $compatiblePropertyTypes = []; + foreach (array_keys($registryPropertyTypes) as $propertyTypeClass) { + if ( + array_intersect($registryPropertyTypeCompatibleSourceTypeClasses[$propertyTypeClass], $shareSourceTypeClasses) !== [] + && array_intersect( + $registryPropertyTypeCompatibleRecipientTypeClasses[$propertyTypeClass], $shareRecipientTypeClasses + ) !== []) { + $compatiblePropertyTypes[] = $propertyTypeClass; + } + } + + return $compatiblePropertyTypes; + } } diff --git a/lib/unstable/Sharing/Event/SharesDefaultSetEvent.php b/lib/unstable/Sharing/Event/SharesDefaultSetEvent.php index c36f9526b3149..ad1c0a7df71a7 100644 --- a/lib/unstable/Sharing/Event/SharesDefaultSetEvent.php +++ b/lib/unstable/Sharing/Event/SharesDefaultSetEvent.php @@ -19,7 +19,7 @@ */ final class SharesDefaultSetEvent extends Event { /** - * @param non-empty-list $shares + * @param non-empty-array $shares * @experimental 35.0.0 */ public function __construct( @@ -29,7 +29,7 @@ public function __construct( } /** - * @return non-empty-list + * @return non-empty-array * @experimental 35.0.0 */ public function getShares(): array { @@ -37,7 +37,7 @@ public function getShares(): array { } /** - * @param non-empty-list $shares + * @param non-empty-array $shares * @experimental 35.0.0 */ public function setShares(array $shares): void { diff --git a/lib/unstable/Sharing/ISharingBackend.php b/lib/unstable/Sharing/ISharingBackend.php index 29ca6f5bc650d..afd3b798cd622 100644 --- a/lib/unstable/Sharing/ISharingBackend.php +++ b/lib/unstable/Sharing/ISharingBackend.php @@ -204,4 +204,13 @@ public function getShareOwner(string $id): ShareUser; * @experimental 35.0.0 */ public function setLastUpdated(array $ids, \DateTimeImmutable $lastUpdated): void; + + /** + * Ensure that all relevant properties and permissions have a value set, inserting defaults when needed + * + * @param non-empty-array $shares + * @return non-empty-array + * @experimental 35.0.0 + */ + public function ensureDefaults(array $shares): array; } diff --git a/lib/unstable/Sharing/ISharingManager.php b/lib/unstable/Sharing/ISharingManager.php index 716c91eb8a32f..214c93b4881ba 100644 --- a/lib/unstable/Sharing/ISharingManager.php +++ b/lib/unstable/Sharing/ISharingManager.php @@ -32,12 +32,12 @@ interface ISharingManager { * @param ?list> $filterRecipientTypeClasses * @param positive-int $limit * @param non-negative-int $offset - * @param ?string $id If provided, recipients that are already part of the share will not be returned. + * @param ?Share $excludeShare If provided, recipients that are already part of the share will not be returned. * @return list * @throws ShareNotFoundException * @experimental 35.0.0 */ - public function searchRecipients(ShareAccessContext $accessContext, ?array $filterRecipientTypeClasses, string $query, int $limit, int $offset, ?string $id = null): array; + public function searchRecipients(ShareAccessContext $accessContext, ?array $filterRecipientTypeClasses, string $query, int $limit, int $offset, ?Share $forShare = null): array; /** * Generate a new secret. @@ -59,7 +59,7 @@ public function getTime(): \DateTimeImmutable; * * @experimental 35.0.0 */ - public function createShare(ShareAccessContext $accessContext): string; + public function createShare(ShareAccessContext $accessContext): Share; /** * Perform all updates when the owner was deleted. @@ -76,7 +76,7 @@ public function onOwnerDeleted(ShareAccessContext $accessContext, ShareUser $own * @throws ShareOperationForbiddenException * @experimental 35.0.0 */ - public function updateShareState(ShareAccessContext $accessContext, string $id, ShareState $state): void; + public function updateShareState(ShareAccessContext $accessContext, Share $share, ShareState $state): Share; /** * Add a new source to a share. @@ -86,7 +86,7 @@ public function updateShareState(ShareAccessContext $accessContext, string $id, * @throws ShareOperationForbiddenException * @experimental 35.0.0 */ - public function addShareSource(ShareAccessContext $accessContext, string $id, ShareSource $source): void; + public function addShareSource(ShareAccessContext $accessContext, Share $share, ShareSource $source): Share; /** * Remove an existing source from a share. @@ -95,7 +95,7 @@ public function addShareSource(ShareAccessContext $accessContext, string $id, Sh * @throws ShareOperationForbiddenException * @experimental 35.0.0 */ - public function removeShareSource(ShareAccessContext $accessContext, string $id, ShareSource $source): void; + public function removeShareSource(ShareAccessContext $accessContext, Share $share, ShareSource $source): Share; /** * Perform all updates when the source was deleted. @@ -112,7 +112,7 @@ public function onSourceDeleted(ShareAccessContext $accessContext, ShareSource $ * @throws ShareOperationForbiddenException * @experimental 35.0.0 */ - public function addShareRecipient(ShareAccessContext $accessContext, string $id, ShareRecipient $recipient): void; + public function addShareRecipient(ShareAccessContext $accessContext, Share $share, ShareRecipient $recipient): Share; /** * Remove an existing recipient from a share. @@ -121,7 +121,7 @@ public function addShareRecipient(ShareAccessContext $accessContext, string $id, * @throws ShareOperationForbiddenException * @experimental 35.0.0 */ - public function removeShareRecipient(ShareAccessContext $accessContext, string $id, ShareRecipient $recipient): void; + public function removeShareRecipient(ShareAccessContext $accessContext, Share $share, ShareRecipient $recipient): Share; /** * Perform all updates when the recipient was deleted. @@ -145,7 +145,7 @@ public function onInitiatorDeleted(ShareAccessContext $accessContext, ShareUser * @throws ShareOperationForbiddenException * @experimental 35.0.0 */ - public function updateShareRecipientSecret(ShareAccessContext $accessContext, string $id, ShareRecipient $recipient, string $secret): void; + public function updateShareRecipientSecret(ShareAccessContext $accessContext, Share $share, ShareRecipient $recipient, string $secret): Share; /** * Update a property of a share. @@ -155,7 +155,7 @@ public function updateShareRecipientSecret(ShareAccessContext $accessContext, st * @throws ShareOperationForbiddenException * @experimental 35.0.0 */ - public function updateShareProperty(ShareAccessContext $accessContext, string $id, ShareProperty $property): void; + public function updateShareProperty(ShareAccessContext $accessContext, Share $share, ShareProperty $property): Share; /** * Update a permission of a share. @@ -165,7 +165,7 @@ public function updateShareProperty(ShareAccessContext $accessContext, string $i * @throws ShareOperationForbiddenException * @experimental 35.0.0 */ - public function updateSharePermission(ShareAccessContext $accessContext, string $id, SharePermission $permission): void; + public function updateSharePermission(ShareAccessContext $accessContext, Share $share, SharePermission $permission): Share; /** * Select a permission preset for a share. @@ -175,7 +175,7 @@ public function updateSharePermission(ShareAccessContext $accessContext, string * @throws ShareOperationForbiddenException * @experimental 35.0.0 */ - public function selectSharePermissionPreset(ShareAccessContext $accessContext, string $id, string $permissionPresetClass): void; + public function selectSharePermissionPreset(ShareAccessContext $accessContext, Share $share, string $permissionPresetClass): Share; /** * Delete a share. @@ -184,7 +184,7 @@ public function selectSharePermissionPreset(ShareAccessContext $accessContext, s * @throws ShareOperationForbiddenException * @experimental 35.0.0 */ - public function deleteShare(ShareAccessContext $accessContext, string $id): void; + public function deleteShare(ShareAccessContext $accessContext, Share $share): void; /** * Get a share. diff --git a/lib/unstable/Sharing/ISharingRegistry.php b/lib/unstable/Sharing/ISharingRegistry.php index a1a352da84582..71ff44da3559b 100644 --- a/lib/unstable/Sharing/ISharingRegistry.php +++ b/lib/unstable/Sharing/ISharingRegistry.php @@ -155,4 +155,19 @@ public function getPermissionTypeCompatiblePermissionPresetClasses(): array; * @experimental 35.0.0 */ public function getPermissionPresetCompatiblePermissionTypeClasses(): array; + + /** + * @param class-string[] $shareSourceTypeClasses + * @return list> + * @experimental 35.0.0 + */ + public function getCompatiblePermissionTypeClasses(array $shareSourceTypeClasses): array; + + /** + * @param class-string[] $shareSourceTypeClasses + * @param class-string[] $shareRecipientTypeClasses + * @return list> + * @experimental 35.0.0 + */ + public function getCompatiblePropertyTypeClasses(array $shareSourceTypeClasses, array $shareRecipientTypeClasses): array; } diff --git a/lib/unstable/Sharing/Recipient/ShareRecipient.php b/lib/unstable/Sharing/Recipient/ShareRecipient.php index 5ddb0fa8b294a..bd191180a52bb 100644 --- a/lib/unstable/Sharing/Recipient/ShareRecipient.php +++ b/lib/unstable/Sharing/Recipient/ShareRecipient.php @@ -114,4 +114,11 @@ public static function formatMultiple(ISharingRegistry $registry, IFactory $l10n return array_map(static fn (ShareRecipient $recipient): array => $recipient->format($registry, $l10nFactory, $urlGenerator, $userManager, $recipientDisplayNames[$recipientTypes[$recipient->class]?->getRecipientDisplayName($recipient->value) ?? $recipient->value] === 1), $recipients); } + + /** + * @experimental 35.0.0 + */ + public function equals(ShareRecipient $other): bool { + return $this->class === $other->class && $this->value === $other->value && $this->instance === $other->instance; + } } diff --git a/lib/unstable/Sharing/Source/ShareSource.php b/lib/unstable/Sharing/Source/ShareSource.php index 59e6cb9f77351..650f385723df5 100644 --- a/lib/unstable/Sharing/Source/ShareSource.php +++ b/lib/unstable/Sharing/Source/ShareSource.php @@ -83,4 +83,11 @@ public static function formatMultiple(ISharingRegistry $registry, IFactory $l10n return array_map(static fn (ShareSource $source): array => $source->format($registry, $l10nFactory, $sourceDisplayNames[$source->getMetadata($registry)->getDisplayName()] === 1), $sources); } + + /** + * @experimental 35.0.0 + */ + public function equals(ShareSource $other): bool { + return $this->class === $other->class && $this->value === $other->value; + } } diff --git a/tests/Core/Sharing/Recipient/GroupShareRecipientTypeTest.php b/tests/Core/Sharing/Recipient/GroupShareRecipientTypeTest.php index 311b686d64778..c26f26a852b8d 100644 --- a/tests/Core/Sharing/Recipient/GroupShareRecipientTypeTest.php +++ b/tests/Core/Sharing/Recipient/GroupShareRecipientTypeTest.php @@ -137,8 +137,8 @@ public function testDelete(): void { $accessContext = new ShareAccessContext(currentUser: $this->user1); $this->dbConnection->beginTransaction(); - $id = $this->manager->createShare($accessContext); - $this->manager->addShareRecipient($accessContext, $id, new ShareRecipient($this->recipientType::class, $this->group1->getGID(), null)); + $share = $this->manager->createShare($accessContext); + $this->manager->addShareRecipient($accessContext, $share, new ShareRecipient($this->recipientType::class, $this->group1->getGID(), null)); $this->dbConnection->commit(); $before = $this->manager->getTime(); @@ -146,12 +146,12 @@ public function testDelete(): void { $after = $this->manager->getTime(); $this->dbConnection->beginTransaction(); - $share = $this->manager->getShare($accessContext, $id); + $share = $this->manager->getShare($accessContext, $share->id); $this->assertGreaterThanOrEqual(SharingManager::timeToMs($before), SharingManager::timeToMs($share->lastUpdated)); $this->assertLessThanOrEqual(SharingManager::timeToMs($after), SharingManager::timeToMs($share->lastUpdated)); $this->assertEquals([], $share->recipients); - $this->manager->deleteShare($accessContext, $id); + $this->manager->deleteShare($accessContext, $share); $this->dbConnection->commit(); $registry->clear(); } diff --git a/tests/Core/Sharing/Recipient/TeamShareRecipientTypeTest.php b/tests/Core/Sharing/Recipient/TeamShareRecipientTypeTest.php index 31bbfd3458a55..61ea50089b892 100644 --- a/tests/Core/Sharing/Recipient/TeamShareRecipientTypeTest.php +++ b/tests/Core/Sharing/Recipient/TeamShareRecipientTypeTest.php @@ -164,8 +164,8 @@ public function testDelete(): void { $accessContext = new ShareAccessContext(currentUser: $this->user1); $this->dbConnection->beginTransaction(); - $id = $this->manager->createShare($accessContext); - $this->manager->addShareRecipient($accessContext, $id, new ShareRecipient($this->recipientType::class, $this->team1->getId(), null)); + $share = $this->manager->createShare($accessContext); + $this->manager->addShareRecipient($accessContext, $share, new ShareRecipient($this->recipientType::class, $this->team1->getId(), null)); $this->dbConnection->commit(); $circlesManager = Server::get(CirclesManager::class); @@ -176,12 +176,12 @@ public function testDelete(): void { $after = $this->manager->getTime(); $this->dbConnection->beginTransaction(); - $share = $this->manager->getShare($accessContext, $id); + $share = $this->manager->getShare($accessContext, $share->id); $this->assertGreaterThanOrEqual($before, $share->lastUpdated->getTimestamp()); $this->assertLessThanOrEqual($after, $share->lastUpdated->getTimestamp()); $this->assertEquals([], $share->recipients); - $this->manager->deleteShare($accessContext, $id); + $this->manager->deleteShare($accessContext, $share); $this->dbConnection->commit(); $registry->clear(); } diff --git a/tests/Core/Sharing/Recipient/UserShareRecipientTypeTest.php b/tests/Core/Sharing/Recipient/UserShareRecipientTypeTest.php index 904db9975827d..e3f1b3427db26 100644 --- a/tests/Core/Sharing/Recipient/UserShareRecipientTypeTest.php +++ b/tests/Core/Sharing/Recipient/UserShareRecipientTypeTest.php @@ -141,8 +141,8 @@ public function testDelete(): void { $accessContext = new ShareAccessContext(currentUser: $this->user1); $this->dbConnection->beginTransaction(); - $id = $this->manager->createShare($accessContext); - $this->manager->addShareRecipient($accessContext, $id, new ShareRecipient($this->recipientType::class, $this->user2->getUID(), null)); + $share = $this->manager->createShare($accessContext); + $this->manager->addShareRecipient($accessContext, $share, new ShareRecipient($this->recipientType::class, $this->user2->getUID(), null)); $this->dbConnection->commit(); $before = $this->manager->getTime(); @@ -150,12 +150,12 @@ public function testDelete(): void { $after = $this->manager->getTime(); $this->dbConnection->beginTransaction(); - $share = $this->manager->getShare($accessContext, $id); + $share = $this->manager->getShare($accessContext, $share->id); $this->assertGreaterThanOrEqual(SharingManager::timeToMs($before), SharingManager::timeToMs($share->lastUpdated)); $this->assertLessThanOrEqual(SharingManager::timeToMs($after), SharingManager::timeToMs($share->lastUpdated)); $this->assertEquals([], $share->recipients); - $this->manager->deleteShare($accessContext, $id); + $this->manager->deleteShare($accessContext, $share); $this->dbConnection->commit(); $registry->clear(); } diff --git a/tests/lib/Sharing/AbstractSharingManagerTests.php b/tests/lib/Sharing/AbstractSharingManagerTests.php index ee248397d8cf9..d1f79eb076427 100644 --- a/tests/lib/Sharing/AbstractSharingManagerTests.php +++ b/tests/lib/Sharing/AbstractSharingManagerTests.php @@ -28,6 +28,7 @@ use OCP\Interaction\RestrictInteractionEvent; use OCP\IUser; use OCP\IUserManager; +use OCP\L10N\IFactory; use OCP\Server; use PHPUnit\Framework\Attributes\DataProvider; use Test\TestCase; @@ -40,7 +41,7 @@ * @psalm-suppress PossiblyUndefinedArrayOffset */ abstract class AbstractSharingManagerTests extends TestCase { - abstract protected function searchRecipients(ShareAccessContext $accessContext, ?array $filterRecipientTypeClasses, string $query, int $limit, int $offset, ?string $id = null): array; + abstract protected function searchRecipients(ShareAccessContext $accessContext, ?array $filterRecipientTypeClasses, string $query, int $limit, int $offset, ?Share $forShare = null): array; /** * @return SharingShare @@ -50,49 +51,49 @@ abstract protected function createShare(ShareAccessContext $accessContext): arra /** * @return SharingShare */ - abstract protected function updateShareState(ShareAccessContext $accessContext, string $id, ShareState $state): array; + abstract protected function updateShareState(ShareAccessContext $accessContext, Share $share, ShareState $state): array; /** * @return SharingShare */ - abstract protected function addShareSource(ShareAccessContext $accessContext, string $id, ShareSource $source): array; + abstract protected function addShareSource(ShareAccessContext $accessContext, Share $share, ShareSource $source): array; /** * @return SharingShare */ - abstract protected function removeShareSource(ShareAccessContext $accessContext, string $id, ShareSource $source): array; + abstract protected function removeShareSource(ShareAccessContext $accessContext, Share $share, ShareSource $source): array; /** * @return SharingShare */ - abstract protected function addShareRecipient(ShareAccessContext $accessContext, string $id, ShareRecipient $recipient): array; + abstract protected function addShareRecipient(ShareAccessContext $accessContext, Share $share, ShareRecipient $recipient): array; /** * @return SharingShare */ - abstract protected function removeShareRecipient(ShareAccessContext $accessContext, string $id, ShareRecipient $recipient): array; + abstract protected function removeShareRecipient(ShareAccessContext $accessContext, Share $share, ShareRecipient $recipient): array; /** * @return SharingShare */ - abstract protected function updateShareRecipientSecret(ShareAccessContext $accessContext, string $id, ShareRecipient $recipient, string $secret): array; + abstract protected function updateShareRecipientSecret(ShareAccessContext $accessContext, Share $share, ShareRecipient $recipient, string $secret): array; /** * @return SharingShare */ - abstract protected function updateShareProperty(ShareAccessContext $accessContext, string $id, ShareProperty $property): array; + abstract protected function updateShareProperty(ShareAccessContext $accessContext, Share $share, ShareProperty $property): array; /** * @return SharingShare */ - abstract protected function updateSharePermission(ShareAccessContext $accessContext, string $id, SharePermission $permission): array; + abstract protected function updateSharePermission(ShareAccessContext $accessContext, Share $share, SharePermission $permission): array; /** * @return SharingShare */ - abstract protected function selectSharePermissionPreset(ShareAccessContext $accessContext, string $id, string $permissionPresetClass): array; + abstract protected function selectSharePermissionPreset(ShareAccessContext $accessContext, Share $share, string $permissionPresetClass): array; - abstract protected function deleteShare(ShareAccessContext $accessContext, string $id): void; + abstract protected function deleteShare(ShareAccessContext $accessContext, Share $share): void; /** * @return SharingShare @@ -116,6 +117,8 @@ abstract protected function getShares(ShareAccessContext $accessContext, ?string protected IUser $user2; + protected IFactory $l10nFactory; + private function parseTime(string $timestampMs): \DateTimeImmutable { $time = \DateTimeImmutable::createFromFormat('U.u', number_format((float)$timestampMs / 1000.0, 3, '.', '')); if ($time === false) { @@ -138,6 +141,8 @@ public function setUp(): void { $this->manager = Server::get(ISharingManager::class); + $this->l10nFactory = Server::get(IFactory::class); + $userManager = Server::get(IUserManager::class); $owner = $userManager->createUser('owner', 'password'); @@ -209,7 +214,7 @@ protected function tearDown(): void { $this->dbConnection->beginTransaction(); foreach ($this->manager->getShares($accessContext, null, null, null, null) as $share) { - $this->manager->deleteShare($accessContext, $share->id); + $this->manager->deleteShare($accessContext, $share); } $this->owner->delete(); @@ -237,6 +242,13 @@ protected function tearDown(): void { parent::tearDown(); } + private function reloadShare(ShareAccessContext $accessContext, Share $share): Share { + $this->dbConnection->beginTransaction(); + $share = $this->manager->getShare($accessContext, $share->id); + $this->dbConnection->commit(); + return $share; + } + public function testSearchRecipients(): void { $this->registry->clear(); $this->registry->registerRecipientType(new TestShareRecipientType1( @@ -556,7 +568,7 @@ public function testSearchRecipientsOmitExisting(): void { $accessContext = new ShareAccessContext($this->owner); $this->dbConnection->beginTransaction(); - $id = $this->manager->createShare($accessContext); + $share = $this->manager->createShare($accessContext); $this->dbConnection->commit(); $this->assertEquals([ @@ -586,10 +598,10 @@ public function testSearchRecipientsOmitExisting(): void { ], 'initiator' => null, ], - ], $this->searchRecipients($accessContext, null, 'recipient', 3, 0, $id)); + ], $this->searchRecipients($accessContext, null, 'recipient', 3, 0, $share)); $this->dbConnection->beginTransaction(); - $this->manager->addShareRecipient($accessContext, $id, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); + $share = $this->manager->addShareRecipient($accessContext, $share, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); $this->dbConnection->commit(); $this->assertEquals([ @@ -606,7 +618,7 @@ public function testSearchRecipientsOmitExisting(): void { ], 'initiator' => null, ], - ], $this->searchRecipients($accessContext, null, 'recipient', 3, 0, $id)); + ], $this->searchRecipients($accessContext, null, 'recipient', 3, 0, $share)); } public function testCreateShare(): void { @@ -705,40 +717,38 @@ public function testUpdateShareState(array $sources, array $recipients, array $p $accessContext = new ShareAccessContext($this->owner); $this->dbConnection->beginTransaction(); - $id = $this->manager->createShare($accessContext); + $share = $this->manager->createShare($accessContext); foreach ($sources as $source) { - $this->manager->addShareSource($accessContext, $id, $source); + $share = $this->manager->addShareSource($accessContext, $share, $source); } foreach ($recipients as $recipient) { - $this->manager->addShareRecipient($accessContext, $id, $recipient); + $share = $this->manager->addShareRecipient($accessContext, $share, $recipient); } - $this->manager->getShare($accessContext, $id); - foreach ($properties as $property) { - $this->manager->updateShareProperty($accessContext, $id, $property); + $share = $this->manager->updateShareProperty($accessContext, $share, $property); } foreach ($permissions as $permission) { - $this->manager->updateSharePermission($accessContext, $id, $permission); + $share = $this->manager->updateSharePermission($accessContext, $share, $permission); } $this->dbConnection->commit(); if ($errorMessage !== null) { try { - $this->updateShareState($accessContext, $id, ShareState::Active); + $this->updateShareState($accessContext, $share, ShareState::Active); $this->fail('Allowed to set share state active.'); } catch (HintException $exception) { $this->assertEquals($errorMessage, $exception->getHint()); } } else { $before = $this->manager->getTime(); - $share = $this->updateShareState($accessContext, $id, ShareState::Active); + $formatted = $this->updateShareState($accessContext, $share, ShareState::Active); $after = $this->manager->getTime(); - $this->assertDateBetween($before, $after, $this->parseTime($share['last_updated'])); - $this->assertEquals(ShareState::Active->value, $share['state']); + $this->assertDateBetween($before, $after, $this->parseTime($formatted['last_updated'])); + $this->assertEquals(ShareState::Active->value, $formatted['state']); } } @@ -746,13 +756,13 @@ public function testAddShareSource(): void { $accessContext = new ShareAccessContext($this->owner); $this->dbConnection->beginTransaction(); - $id = $this->manager->createShare($accessContext); + $share = $this->manager->createShare($accessContext); $this->dbConnection->commit(); $before = $this->manager->getTime(); - $share = $this->addShareSource($accessContext, $id, new ShareSource(TestShareSourceType1::class, 'source1')); + $formatted = $this->addShareSource($accessContext, $share, new ShareSource(TestShareSourceType1::class, 'source1')); $after = $this->manager->getTime(); - $this->assertDateBetween($before, $after, $this->parseTime($share['last_updated'])); + $this->assertDateBetween($before, $after, $this->parseTime($formatted['last_updated'])); $this->assertEquals([ [ 'class' => TestShareSourceType1::class, @@ -762,7 +772,7 @@ public function testAddShareSource(): void { 'svg' => '', ], ], - ], $share ['sources']); + ], $formatted['sources']); } public function testAddShareSourceInteractionRestricted(): void { @@ -779,12 +789,13 @@ public function testAddShareSourceInteractionRestricted(): void { $accessContext = new ShareAccessContext($this->owner); $this->dbConnection->beginTransaction(); - $id = $this->manager->createShare($accessContext); - $this->manager->addShareRecipient($accessContext, $id, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); + $share = $this->manager->createShare($accessContext); + $this->manager->addShareRecipient($accessContext, $share, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); + $share = $this->reloadShare($accessContext, $share); $this->dbConnection->commit(); try { - $this->addShareSource($accessContext, $id, new ShareSource(TestShareSourceType1::class, 'source1')); + $this->addShareSource($accessContext, $share, new ShareSource(TestShareSourceType1::class, 'source1')); $this->fail('Not restricted.'); } catch (HintException $hintException) { $this->assertEquals('You are not allowed to add this source.', $hintException->getHint()); @@ -797,21 +808,22 @@ public function testRemoveShareSource(): void { $accessContext = new ShareAccessContext($this->owner); $this->dbConnection->beginTransaction(); - $id = $this->manager->createShare($accessContext); - $this->manager->addShareSource($accessContext, $id, new ShareSource(TestShareSourceType1::class, 'source1')); - $this->manager->addShareSource($accessContext, $id, new ShareSource(TestShareSourceType2::class, 'source2')); - $this->manager->addShareRecipient($accessContext, $id, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); - $this->manager->getShare($accessContext, $id); - $this->manager->updateSharePermission($accessContext, $id, new SharePermission(TestSharePermissionType2::class, true)); - $this->manager->updateShareState($accessContext, $id, ShareState::Active); + $share = $this->manager->createShare($accessContext); + $share = $this->manager->addShareSource($accessContext, $share, new ShareSource(TestShareSourceType1::class, 'source1')); + $share = $this->manager->addShareSource($accessContext, $share, new ShareSource(TestShareSourceType2::class, 'source2')); + $share = $this->manager->addShareRecipient($accessContext, $share, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); + + $share = $this->manager->updateSharePermission($accessContext, $share, new SharePermission(TestSharePermissionType2::class, true)); + $share = $this->manager->updateShareState($accessContext, $share, ShareState::Active); $this->dbConnection->commit(); $before = $this->manager->getTime(); - $share = $this->removeShareSource($accessContext, $id, new ShareSource(TestShareSourceType1::class, 'source1')); + $formatted = $this->removeShareSource($accessContext, $share, new ShareSource(TestShareSourceType1::class, 'source1')); + $share = $this->reloadShare($accessContext, $share); $after = $this->manager->getTime(); - $this->assertDateBetween($before, $after, $this->parseTime($share['last_updated'])); - $this->assertEquals(ShareState::Active->value, $share['state']); + $this->assertDateBetween($before, $after, $this->parseTime($formatted['last_updated'])); + $this->assertEquals(ShareState::Active->value, $formatted['state']); $this->assertEquals([ [ 'class' => TestShareSourceType2::class, @@ -821,27 +833,27 @@ public function testRemoveShareSource(): void { 'svg' => '', ], ], - ], $share['sources']); + ], $formatted['sources']); $before = $this->manager->getTime(); - $share = $this->removeShareSource($accessContext, $id, new ShareSource(TestShareSourceType2::class, 'source2')); + $formatted = $this->removeShareSource($accessContext, $share, new ShareSource(TestShareSourceType2::class, 'source2')); $after = $this->manager->getTime(); - $this->assertDateBetween($before, $after, $this->parseTime($share['last_updated'])); - $this->assertEquals(ShareState::Draft->value, $share['state']); - $this->assertEquals([], $share['sources']); + $this->assertDateBetween($before, $after, $this->parseTime($formatted['last_updated'])); + $this->assertEquals(ShareState::Draft->value, $formatted['state']); + $this->assertEquals([], $formatted['sources']); } public function testAddShareRecipient(): void { $accessContext = new ShareAccessContext($this->owner); $this->dbConnection->beginTransaction(); - $id = $this->manager->createShare($accessContext); + $share = $this->manager->createShare($accessContext); $this->dbConnection->commit(); $before = $this->manager->getTime(); - $share = $this->addShareRecipient($accessContext, $id, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); + $formatted = $this->addShareRecipient($accessContext, $share, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); $after = $this->manager->getTime(); - $this->assertDateBetween($before, $after, $this->parseTime($share['last_updated'])); + $this->assertDateBetween($before, $after, $this->parseTime($formatted['last_updated'])); $this->assertEquals([ [ 'class' => TestShareRecipientType1::class, @@ -864,7 +876,7 @@ public function testAddShareRecipient(): void { ], ], ], - ], $share['recipients']); + ], $formatted['recipients']); } public function testAddShareRecipientInteractionRestricted(): void { @@ -881,12 +893,13 @@ public function testAddShareRecipientInteractionRestricted(): void { $accessContext = new ShareAccessContext($this->owner); $this->dbConnection->beginTransaction(); - $id = $this->manager->createShare($accessContext); - $this->manager->addShareSource($accessContext, $id, new ShareSource(TestShareSourceType1::class, 'source1')); + $share = $this->manager->createShare($accessContext); + $share = $this->manager->addShareSource($accessContext, $share, new ShareSource(TestShareSourceType1::class, 'source1')); + $this->dbConnection->commit(); try { - $this->addShareRecipient($accessContext, $id, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); + $this->addShareRecipient($accessContext, $share, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); $this->fail('Interaction not restricted.'); } catch (HintException $hintException) { $this->assertEquals('You are not allowed to add this recipient.', $hintException->getHint()); @@ -899,17 +912,18 @@ public function testAddChildShareRecipientWithoutResharePermission(): void { $accessContext = new ShareAccessContext($this->owner); $this->dbConnection->beginTransaction(); - $id = $this->manager->createShare($accessContext); - $this->manager->addShareSource($accessContext, $id, new ShareSource(TestShareSourceType1::class, 'source1')); - $this->manager->addShareRecipient($accessContext, $id, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); - $this->manager->getShare($accessContext, $id); - $this->manager->updateSharePermission($accessContext, $id, new SharePermission(TestSharePermissionType1::class, true)); - $this->manager->updateShareState($accessContext, $id, ShareState::Active); + $share = $this->manager->createShare($accessContext); + $share = $this->manager->addShareSource($accessContext, $share, new ShareSource(TestShareSourceType1::class, 'source1')); + $share = $this->manager->addShareRecipient($accessContext, $share, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); + + $share = $this->manager->getShare($accessContext, $share->id); + $share = $this->manager->updateSharePermission($accessContext, $share, new SharePermission(TestSharePermissionType1::class, true)); + $share = $this->manager->updateShareState($accessContext, $share, ShareState::Active); $this->dbConnection->commit(); try { - $this->addShareRecipient(new ShareAccessContext($this->user1), $id, new ShareRecipient(TestShareRecipientType2::class, 'recipient2', null)); + $this->addShareRecipient(new ShareAccessContext($this->user1), $share, new ShareRecipient(TestShareRecipientType2::class, 'recipient2', null)); $this->fail('Able to add child recipient without reshare permission.'); } catch (HintException $hintException) { $this->assertEquals('You are not allowed to edit this share.', $hintException->getHint()); @@ -920,19 +934,20 @@ public function testAddChildShareRecipientWithResharePermission(): void { $accessContext = new ShareAccessContext($this->owner); $this->dbConnection->beginTransaction(); - $id = $this->manager->createShare($accessContext); - $this->manager->addShareSource($accessContext, $id, new ShareSource(TestShareSourceType1::class, 'source1')); - $this->manager->addShareRecipient($accessContext, $id, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); - $this->manager->getShare($accessContext, $id); - $this->manager->updateSharePermission($accessContext, $id, new SharePermission(ReshareSharePermissionType::class, true)); - $this->manager->updateShareState($accessContext, $id, ShareState::Active); + $share = $this->manager->createShare($accessContext); + $share = $this->manager->addShareSource($accessContext, $share, new ShareSource(TestShareSourceType1::class, 'source1')); + $share = $this->manager->addShareRecipient($accessContext, $share, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); + + $share = $this->manager->getShare($accessContext, $share->id); + $share = $this->manager->updateSharePermission($accessContext, $share, new SharePermission(ReshareSharePermissionType::class, true)); + $share = $this->manager->updateShareState($accessContext, $share, ShareState::Active); $this->dbConnection->commit(); $before = $this->manager->getTime(); - $share = $this->addShareRecipient(new ShareAccessContext($this->user1), $id, new ShareRecipient(TestShareRecipientType2::class, 'recipient2', null)); + $formatted = $this->addShareRecipient(new ShareAccessContext($this->user1), $share, new ShareRecipient(TestShareRecipientType2::class, 'recipient2', null)); $after = $this->manager->getTime(); - $this->assertDateBetween($before, $after, $this->parseTime($share['last_updated'])); + $this->assertDateBetween($before, $after, $this->parseTime($formatted['last_updated'])); $this->assertEquals([ [ 'class' => TestShareRecipientType1::class, @@ -976,28 +991,30 @@ public function testAddChildShareRecipientWithResharePermission(): void { ], ], ], - ], $share['recipients']); + ], $formatted['recipients']); } public function testRemoveShareRecipient(): void { $accessContext = new ShareAccessContext($this->owner); $this->dbConnection->beginTransaction(); - $id = $this->manager->createShare($accessContext); - $this->manager->addShareSource($accessContext, $id, new ShareSource(TestShareSourceType1::class, 'source1')); - $this->manager->addShareRecipient($accessContext, $id, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); - $this->manager->addShareRecipient($accessContext, $id, new ShareRecipient(TestShareRecipientType2::class, 'recipient2', null)); - $this->manager->getShare($accessContext, $id); - $this->manager->updateSharePermission($accessContext, $id, new SharePermission(TestSharePermissionType1::class, true)); - $this->manager->updateShareState($accessContext, $id, ShareState::Active); + $share = $this->manager->createShare($accessContext); + $share = $this->manager->addShareSource($accessContext, $share, new ShareSource(TestShareSourceType1::class, 'source1')); + $share = $this->manager->addShareRecipient($accessContext, $share, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); + $share = $this->manager->addShareRecipient($accessContext, $share, new ShareRecipient(TestShareRecipientType2::class, 'recipient2', null)); + + $share = $this->manager->getShare($accessContext, $share->id); + $share = $this->manager->updateSharePermission($accessContext, $share, new SharePermission(TestSharePermissionType1::class, true)); + $share = $this->manager->updateShareState($accessContext, $share, ShareState::Active); $this->dbConnection->commit(); $before = $this->manager->getTime(); - $share = $this->removeShareRecipient($accessContext, $id, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); + $formatted = $this->removeShareRecipient($accessContext, $share, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); + $share = $this->reloadShare($accessContext, $share); $after = $this->manager->getTime(); - $this->assertDateBetween($before, $after, $this->parseTime($share['last_updated'])); - $this->assertEquals(ShareState::Active->value, $share['state']); + $this->assertDateBetween($before, $after, $this->parseTime($formatted['last_updated'])); + $this->assertEquals(ShareState::Active->value, $formatted['state']); $this->assertEquals([ [ 'class' => TestShareRecipientType2::class, @@ -1020,31 +1037,32 @@ public function testRemoveShareRecipient(): void { ], ], ], - ], $share['recipients']); + ], $formatted['recipients']); $before = $this->manager->getTime(); - $share = $this->removeShareRecipient($accessContext, $id, new ShareRecipient(TestShareRecipientType2::class, 'recipient2', null)); + $formatted = $this->removeShareRecipient($accessContext, $share, new ShareRecipient(TestShareRecipientType2::class, 'recipient2', null)); $after = $this->manager->getTime(); - $this->assertDateBetween($before, $after, $this->parseTime($share['last_updated'])); - $this->assertEquals(ShareState::Draft->value, $share['state']); - $this->assertEquals([], $share['recipients']); + $this->assertDateBetween($before, $after, $this->parseTime($formatted['last_updated'])); + $this->assertEquals(ShareState::Draft->value, $formatted['state']); + $this->assertEquals([], $formatted['recipients']); } public function testRemoveSelfShareRecipientWithoutResharePermission(): void { $accessContext = new ShareAccessContext($this->owner); $this->dbConnection->beginTransaction(); - $id = $this->manager->createShare($accessContext); - $this->manager->addShareSource($accessContext, $id, new ShareSource(TestShareSourceType1::class, 'source1')); - $this->manager->addShareRecipient($accessContext, $id, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); - $this->manager->getShare($accessContext, $id); - $this->manager->updateSharePermission($accessContext, $id, new SharePermission(TestSharePermissionType1::class, true)); - $this->manager->updateShareState($accessContext, $id, ShareState::Active); + $share = $this->manager->createShare($accessContext); + $share = $this->manager->addShareSource($accessContext, $share, new ShareSource(TestShareSourceType1::class, 'source1')); + $share = $this->manager->addShareRecipient($accessContext, $share, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); + + $share = $this->manager->getShare($accessContext, $share->id); + $share = $this->manager->updateSharePermission($accessContext, $share, new SharePermission(TestSharePermissionType1::class, true)); + $share = $this->manager->updateShareState($accessContext, $share, ShareState::Active); $this->dbConnection->commit(); try { - $this->removeShareRecipient(new ShareAccessContext($this->user1), $id, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); + $this->removeShareRecipient(new ShareAccessContext($this->user1), $share, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); $this->fail('Able to remove self recipient.'); } catch (HintException $hintException) { $this->assertEquals('You are not allowed to edit this share.', $hintException->getHint()); @@ -1055,17 +1073,18 @@ public function testRemoveSelfShareRecipientWithResharePermission(): void { $accessContext = new ShareAccessContext($this->owner); $this->dbConnection->beginTransaction(); - $id = $this->manager->createShare($accessContext); - $this->manager->addShareSource($accessContext, $id, new ShareSource(TestShareSourceType1::class, 'source1')); - $this->manager->addShareRecipient($accessContext, $id, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); - $this->manager->getShare($accessContext, $id); - $this->manager->updateSharePermission($accessContext, $id, new SharePermission(ReshareSharePermissionType::class, true)); - $this->manager->updateShareState($accessContext, $id, ShareState::Active); + $share = $this->manager->createShare($accessContext); + $share = $this->manager->addShareSource($accessContext, $share, new ShareSource(TestShareSourceType1::class, 'source1')); + $share = $this->manager->addShareRecipient($accessContext, $share, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); + + $share = $this->manager->getShare($accessContext, $share->id); + $share = $this->manager->updateSharePermission($accessContext, $share, new SharePermission(ReshareSharePermissionType::class, true)); + $share = $this->manager->updateShareState($accessContext, $share, ShareState::Active); $this->dbConnection->commit(); try { - $this->removeShareRecipient(new ShareAccessContext($this->user1), $id, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); + $this->removeShareRecipient(new ShareAccessContext($this->user1), $share, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); $this->fail('Able to remove self recipient.'); } catch (HintException $hintException) { $this->assertEquals('You are not allowed to edit this share.', $hintException->getHint()); @@ -1076,20 +1095,21 @@ public function testRemoveChildShareRecipientWithoutResharePermission(): void { $accessContext = new ShareAccessContext($this->owner); $this->dbConnection->beginTransaction(); - $id = $this->manager->createShare($accessContext); - $this->manager->addShareSource($accessContext, $id, new ShareSource(TestShareSourceType1::class, 'source1')); - $this->manager->addShareRecipient($accessContext, $id, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); - $this->manager->getShare($accessContext, $id); - $this->manager->updateSharePermission($accessContext, $id, new SharePermission(TestSharePermissionType1::class, true)); - $this->manager->updateSharePermission($accessContext, $id, new SharePermission(ReshareSharePermissionType::class, true)); - $this->manager->updateShareState($accessContext, $id, ShareState::Active); - $this->manager->addShareRecipient(new ShareAccessContext($this->user1), $id, new ShareRecipient(TestShareRecipientType2::class, 'recipient2', null)); - $this->manager->updateSharePermission($accessContext, $id, new SharePermission(ReshareSharePermissionType::class, false)); + $share = $this->manager->createShare($accessContext); + $share = $this->manager->addShareSource($accessContext, $share, new ShareSource(TestShareSourceType1::class, 'source1')); + $share = $this->manager->addShareRecipient($accessContext, $share, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); + + $share = $this->manager->getShare($accessContext, $share->id); + $share = $this->manager->updateSharePermission($accessContext, $share, new SharePermission(TestSharePermissionType1::class, true)); + $share = $this->manager->updateSharePermission($accessContext, $share, new SharePermission(ReshareSharePermissionType::class, true)); + $share = $this->manager->updateShareState($accessContext, $share, ShareState::Active); + $share = $this->manager->addShareRecipient(new ShareAccessContext($this->user1), $share, new ShareRecipient(TestShareRecipientType2::class, 'recipient2', null)); + $share = $this->manager->updateSharePermission($accessContext, $share, new SharePermission(ReshareSharePermissionType::class, false)); $this->dbConnection->commit(); try { - $this->removeShareRecipient(new ShareAccessContext($this->user1), $id, new ShareRecipient(TestShareRecipientType2::class, 'recipient2', null)); + $this->removeShareRecipient(new ShareAccessContext($this->user1), $share, new ShareRecipient(TestShareRecipientType2::class, 'recipient2', null)); $this->fail('Able to remove child recipient without reshare permission.'); } catch (HintException $hintException) { $this->assertEquals('You are not allowed to edit this share.', $hintException->getHint()); @@ -1100,20 +1120,21 @@ public function testRemoveChildShareRecipientWithResharePermission(): void { $accessContext = new ShareAccessContext($this->owner); $this->dbConnection->beginTransaction(); - $id = $this->manager->createShare($accessContext); - $this->manager->addShareSource($accessContext, $id, new ShareSource(TestShareSourceType1::class, 'source1')); - $this->manager->addShareRecipient($accessContext, $id, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); - $this->manager->getShare($accessContext, $id); - $this->manager->updateSharePermission($accessContext, $id, new SharePermission(ReshareSharePermissionType::class, true)); - $this->manager->updateShareState($accessContext, $id, ShareState::Active); - $this->manager->addShareRecipient(new ShareAccessContext($this->user1), $id, new ShareRecipient(TestShareRecipientType2::class, 'recipient2', null)); + $share = $this->manager->createShare($accessContext); + $share = $this->manager->addShareSource($accessContext, $share, new ShareSource(TestShareSourceType1::class, 'source1')); + $share = $this->manager->addShareRecipient($accessContext, $share, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); + + $share = $this->manager->getShare($accessContext, $share->id); + $share = $this->manager->updateSharePermission($accessContext, $share, new SharePermission(ReshareSharePermissionType::class, true)); + $share = $this->manager->updateShareState($accessContext, $share, ShareState::Active); + $share = $this->manager->addShareRecipient(new ShareAccessContext($this->user1), $share, new ShareRecipient(TestShareRecipientType2::class, 'recipient2', null)); $this->dbConnection->commit(); $before = $this->manager->getTime(); - $share = $this->removeShareRecipient(new ShareAccessContext($this->user1), $id, new ShareRecipient(TestShareRecipientType2::class, 'recipient2', null)); + $formatted = $this->removeShareRecipient(new ShareAccessContext($this->user1), $share, new ShareRecipient(TestShareRecipientType2::class, 'recipient2', null)); $after = $this->manager->getTime(); - $this->assertDateBetween($before, $after, $this->parseTime($share['last_updated'])); + $this->assertDateBetween($before, $after, $this->parseTime($formatted['last_updated'])); $this->assertEquals([ [ 'class' => TestShareRecipientType1::class, @@ -1136,25 +1157,26 @@ public function testRemoveChildShareRecipientWithResharePermission(): void { ], ], ], - ], $share['recipients']); + ], $formatted['recipients']); } public function testRemoveSiblingShareRecipientWithoutResharePermission(): void { $accessContext = new ShareAccessContext($this->owner); $this->dbConnection->beginTransaction(); - $id = $this->manager->createShare($accessContext); - $this->manager->addShareSource($accessContext, $id, new ShareSource(TestShareSourceType1::class, 'source1')); - $this->manager->addShareRecipient($accessContext, $id, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); - $this->manager->addShareRecipient($accessContext, $id, new ShareRecipient(TestShareRecipientType2::class, 'recipient2', null)); - $this->manager->getShare($accessContext, $id); - $this->manager->updateSharePermission($accessContext, $id, new SharePermission(TestSharePermissionType1::class, true)); - $this->manager->updateShareState($accessContext, $id, ShareState::Active); + $share = $this->manager->createShare($accessContext); + $share = $this->manager->addShareSource($accessContext, $share, new ShareSource(TestShareSourceType1::class, 'source1')); + $share = $this->manager->addShareRecipient($accessContext, $share, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); + $share = $this->manager->addShareRecipient($accessContext, $share, new ShareRecipient(TestShareRecipientType2::class, 'recipient2', null)); + + $share = $this->manager->getShare($accessContext, $share->id); + $share = $this->manager->updateSharePermission($accessContext, $share, new SharePermission(TestSharePermissionType1::class, true)); + $share = $this->manager->updateShareState($accessContext, $share, ShareState::Active); $this->dbConnection->commit(); try { - $this->removeShareRecipient(new ShareAccessContext($this->user1), $id, new ShareRecipient(TestShareRecipientType2::class, 'recipient2', null)); + $this->removeShareRecipient(new ShareAccessContext($this->user1), $share, new ShareRecipient(TestShareRecipientType2::class, 'recipient2', null)); $this->fail('Able to remove sibling recipient.'); } catch (HintException $hintException) { $this->assertEquals('You are not allowed to edit this share.', $hintException->getHint()); @@ -1165,18 +1187,18 @@ public function testRemoveSiblingShareRecipientWithResharePermission(): void { $accessContext = new ShareAccessContext($this->owner); $this->dbConnection->beginTransaction(); - $id = $this->manager->createShare($accessContext); - $this->manager->addShareSource($accessContext, $id, new ShareSource(TestShareSourceType1::class, 'source1')); - $this->manager->addShareRecipient($accessContext, $id, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); - $this->manager->addShareRecipient($accessContext, $id, new ShareRecipient(TestShareRecipientType2::class, 'recipient2', null)); - $this->manager->getShare($accessContext, $id); - $this->manager->updateSharePermission($accessContext, $id, new SharePermission(ReshareSharePermissionType::class, true)); - $this->manager->updateShareState($accessContext, $id, ShareState::Active); + $share = $this->manager->createShare($accessContext); + $share = $this->manager->addShareSource($accessContext, $share, new ShareSource(TestShareSourceType1::class, 'source1')); + $share = $this->manager->addShareRecipient($accessContext, $share, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); + $share = $this->manager->addShareRecipient($accessContext, $share, new ShareRecipient(TestShareRecipientType2::class, 'recipient2', null)); + $share = $this->manager->getShare($accessContext, $share->id); + $share = $this->manager->updateSharePermission($accessContext, $share, new SharePermission(ReshareSharePermissionType::class, true)); + $share = $this->manager->updateShareState($accessContext, $share, ShareState::Active); $this->dbConnection->commit(); try { - $this->removeShareRecipient(new ShareAccessContext($this->user1), $id, new ShareRecipient(TestShareRecipientType2::class, 'recipient2', null)); + $this->removeShareRecipient(new ShareAccessContext($this->user1), $share, new ShareRecipient(TestShareRecipientType2::class, 'recipient2', null)); $this->fail('Able to remove sibling recipient.'); } catch (HintException $hintException) { $this->assertEquals('You are not allowed to edit this share.', $hintException->getHint()); @@ -1187,20 +1209,20 @@ public function testRemoveParentShareRecipientWithoutResharePermission(): void { $accessContext = new ShareAccessContext($this->owner); $this->dbConnection->beginTransaction(); - $id = $this->manager->createShare($accessContext); - $this->manager->addShareSource($accessContext, $id, new ShareSource(TestShareSourceType1::class, 'source1')); - $this->manager->addShareRecipient($accessContext, $id, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); - $this->manager->getShare($accessContext, $id); - $this->manager->updateSharePermission($accessContext, $id, new SharePermission(TestSharePermissionType1::class, true)); - $this->manager->updateSharePermission($accessContext, $id, new SharePermission(ReshareSharePermissionType::class, true)); - $this->manager->updateShareState($accessContext, $id, ShareState::Active); - $this->manager->addShareRecipient(new ShareAccessContext($this->user1), $id, new ShareRecipient(TestShareRecipientType2::class, 'recipient2', null)); - $this->manager->updateSharePermission($accessContext, $id, new SharePermission(ReshareSharePermissionType::class, false)); + $share = $this->manager->createShare($accessContext); + $share = $this->manager->addShareSource($accessContext, $share, new ShareSource(TestShareSourceType1::class, 'source1')); + $share = $this->manager->addShareRecipient($accessContext, $share, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); + $share = $this->manager->getShare($accessContext, $share->id); + $share = $this->manager->updateSharePermission($accessContext, $share, new SharePermission(TestSharePermissionType1::class, true)); + $share = $this->manager->updateSharePermission($accessContext, $share, new SharePermission(ReshareSharePermissionType::class, true)); + $share = $this->manager->updateShareState($accessContext, $share, ShareState::Active); + $share = $this->manager->addShareRecipient(new ShareAccessContext($this->user1), $share, new ShareRecipient(TestShareRecipientType2::class, 'recipient2', null)); + $share = $this->manager->updateSharePermission($accessContext, $share, new SharePermission(ReshareSharePermissionType::class, false)); $this->dbConnection->commit(); try { - $this->removeShareRecipient(new ShareAccessContext($this->user2), $id, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); + $this->removeShareRecipient(new ShareAccessContext($this->user2), $share, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); $this->fail('Able to remove parent recipient.'); } catch (HintException $hintException) { $this->assertEquals('You are not allowed to edit this share.', $hintException->getHint()); @@ -1211,18 +1233,18 @@ public function testRemoveParentShareRecipientWithResharePermission(): void { $accessContext = new ShareAccessContext($this->owner); $this->dbConnection->beginTransaction(); - $id = $this->manager->createShare($accessContext); - $this->manager->addShareSource($accessContext, $id, new ShareSource(TestShareSourceType1::class, 'source1')); - $this->manager->addShareRecipient($accessContext, $id, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); - $this->manager->getShare($accessContext, $id); - $this->manager->updateSharePermission($accessContext, $id, new SharePermission(ReshareSharePermissionType::class, true)); - $this->manager->updateShareState($accessContext, $id, ShareState::Active); - $this->manager->addShareRecipient(new ShareAccessContext($this->user1), $id, new ShareRecipient(TestShareRecipientType2::class, 'recipient2', null)); + $share = $this->manager->createShare($accessContext); + $share = $this->manager->addShareSource($accessContext, $share, new ShareSource(TestShareSourceType1::class, 'source1')); + $share = $this->manager->addShareRecipient($accessContext, $share, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); + $share = $this->manager->getShare($accessContext, $share->id); + $share = $this->manager->updateSharePermission($accessContext, $share, new SharePermission(ReshareSharePermissionType::class, true)); + $share = $this->manager->updateShareState($accessContext, $share, ShareState::Active); + $share = $this->manager->addShareRecipient(new ShareAccessContext($this->user1), $share, new ShareRecipient(TestShareRecipientType2::class, 'recipient2', null)); $this->dbConnection->commit(); try { - $this->removeShareRecipient(new ShareAccessContext($this->user2), $id, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); + $this->removeShareRecipient(new ShareAccessContext($this->user2), $share, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); $this->fail('Able to remove parent recipient.'); } catch (HintException $hintException) { $this->assertEquals('You are not allowed to edit this share.', $hintException->getHint()); @@ -1253,25 +1275,24 @@ public function testUpdateShareRecipientSecret(bool $isSecretUpdatable): void { $accessContext = new ShareAccessContext($this->owner); $this->dbConnection->beginTransaction(); - $id = $this->manager->createShare($accessContext); - $this->manager->getShare($accessContext, $id); + $share = $this->manager->createShare($accessContext); $recipient = new ShareRecipient(TestShareRecipientTypePublicSecret::class, 'recipient1', null); - $this->manager->addShareRecipient($accessContext, $id, $recipient); + $share = $this->manager->addShareRecipient($accessContext, $share, $recipient); $this->dbConnection->commit(); if (!$isSecretUpdatable) { try { - $this->updateShareRecipientSecret($accessContext, $id, $recipient, 'mysecret'); + $this->updateShareRecipientSecret($accessContext, $share, $recipient, 'mysecret'); $this->fail('Able to update recipient secret.'); } catch (HintException $exception) { $this->assertEquals('You are not allowed to edit this share.', $exception->getHint()); } } else { $before = $this->manager->getTime(); - $share = $this->updateShareRecipientSecret($accessContext, $id, $recipient, 'mysecret'); + $formatted = $this->updateShareRecipientSecret($accessContext, $share, $recipient, 'mysecret'); $after = $this->manager->getTime(); - $this->assertDateBetween($before, $after, $this->parseTime($share['last_updated'])); - unset($share['last_updated']); + $this->assertDateBetween($before, $after, $this->parseTime($formatted['last_updated'])); + unset($formatted['last_updated']); $this->assertEquals([ [ 'class' => TestShareRecipientTypePublicSecret::class, @@ -1296,7 +1317,7 @@ public function testUpdateShareRecipientSecret(bool $isSecretUpdatable): void { ], ], ], - ], $share['recipients']); + ], $formatted['recipients']); } } @@ -1318,18 +1339,18 @@ public function testUpdateShareProperty(array $values): void { $accessContext = new ShareAccessContext($this->owner); $this->dbConnection->beginTransaction(); - $id = $this->manager->createShare($accessContext); - $this->manager->addShareSource($accessContext, $id, new ShareSource(TestShareSourceType1::class, 'source1')); - $this->manager->addShareRecipient($accessContext, $id, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); - $this->manager->getShare($accessContext, $id); + $share = $this->manager->createShare($accessContext); + $share = $this->manager->addShareSource($accessContext, $share, new ShareSource(TestShareSourceType1::class, 'source1')); + $share = $this->manager->addShareRecipient($accessContext, $share, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); + $share = $this->manager->getShare($accessContext, $share->id); $this->dbConnection->commit(); foreach ($values as $value) { $before = $this->manager->getTime(); - $share = $this->updateShareProperty($accessContext, $id, new ShareProperty(TestSharePropertyType1::class, $value)); + $formatted = $this->updateShareProperty($accessContext, $share, new ShareProperty(TestSharePropertyType1::class, $value)); $after = $this->manager->getTime(); - $this->assertDateBetween($before, $after, $this->parseTime($share['last_updated'])); + $this->assertDateBetween($before, $after, $this->parseTime($formatted['last_updated'])); $this->assertEquals([ [ 'class' => TestSharePropertyType1::class, @@ -1342,7 +1363,7 @@ public function testUpdateShareProperty(array $values): void { 'type' => 'enum', 'valid_values' => ['valid1'], ], - ], $share['properties']); + ], $formatted['properties']); } } @@ -1354,19 +1375,21 @@ public function testUpdateSharePropertyRequired(): void { $accessContext = new ShareAccessContext($this->owner); $this->dbConnection->beginTransaction(); - $id = $this->manager->createShare($accessContext); - $this->manager->addShareSource($accessContext, $id, new ShareSource(TestShareSourceType1::class, 'source1')); - $this->manager->addShareRecipient($accessContext, $id, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); - $this->manager->getShare($accessContext, $id); - $this->manager->updateSharePermission($accessContext, $id, new SharePermission(TestSharePermissionType1::class, true)); + $share = $this->manager->createShare($accessContext); + $this->manager->addShareSource($accessContext, $share, new ShareSource(TestShareSourceType1::class, 'source1')); + $this->manager->addShareRecipient($accessContext, $share, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); + + $this->manager->getShare($accessContext, $share->id); + $this->manager->updateSharePermission($accessContext, $share, new SharePermission(TestSharePermissionType1::class, true)); $this->dbConnection->commit(); $before = $this->manager->getTime(); - $share = $this->updateShareProperty($accessContext, $id, new ShareProperty(TestSharePropertyTypeRequired::class, 'valid1')); + $formatted = $this->updateShareProperty($accessContext, $share, new ShareProperty(TestSharePropertyTypeRequired::class, 'valid1')); + $share = $this->reloadShare($accessContext, $share); $after = $this->manager->getTime(); - $this->assertDateBetween($before, $after, $this->parseTime($share['last_updated'])); - $this->assertEquals(ShareState::Draft->value, $share['state']); + $this->assertDateBetween($before, $after, $this->parseTime($formatted['last_updated'])); + $this->assertEquals(ShareState::Draft->value, $formatted['state']); $this->assertEquals([ [ 'class' => TestSharePropertyType1::class, @@ -1390,17 +1413,18 @@ public function testUpdateSharePropertyRequired(): void { 'type' => 'enum', 'valid_values' => ['valid1', 'valid2'], ], - ], $share['properties']); + ], $formatted['properties']); $this->dbConnection->beginTransaction(); - $this->manager->updateShareState($accessContext, $id, ShareState::Active); + $this->manager->updateShareState($accessContext, $share, ShareState::Active); $this->dbConnection->commit(); $before = $this->manager->getTime(); - $share = $this->updateShareProperty($accessContext, $id, new ShareProperty(TestSharePropertyTypeRequired::class, 'valid2')); + $formatted = $this->updateShareProperty($accessContext, $share, new ShareProperty(TestSharePropertyTypeRequired::class, 'valid2')); + $share = $this->reloadShare($accessContext, $share); $after = $this->manager->getTime(); - $this->assertDateBetween($before, $after, $this->parseTime($share['last_updated'])); - $this->assertEquals(ShareState::Active->value, $share['state']); + $this->assertDateBetween($before, $after, $this->parseTime($formatted['last_updated'])); + $this->assertEquals(ShareState::Active->value, $formatted['state']); $this->assertEquals([ [ 'class' => TestSharePropertyType1::class, @@ -1424,13 +1448,13 @@ public function testUpdateSharePropertyRequired(): void { 'type' => 'enum', 'valid_values' => ['valid1', 'valid2'], ], - ], $share['properties']); + ], $formatted['properties']); $before = $this->manager->getTime(); - $share = $this->updateShareProperty($accessContext, $id, new ShareProperty(TestSharePropertyTypeRequired::class, null)); + $formatted = $this->updateShareProperty($accessContext, $share, new ShareProperty(TestSharePropertyTypeRequired::class, null)); $after = $this->manager->getTime(); - $this->assertDateBetween($before, $after, $this->parseTime($share['last_updated'])); - $this->assertEquals(ShareState::Draft->value, $share['state']); + $this->assertDateBetween($before, $after, $this->parseTime($formatted['last_updated'])); + $this->assertEquals(ShareState::Draft->value, $formatted['state']); $this->assertEquals([ [ 'class' => TestSharePropertyType1::class, @@ -1454,7 +1478,7 @@ public function testUpdateSharePropertyRequired(): void { 'type' => 'enum', 'valid_values' => ['valid1', 'valid2'], ], - ], $share['properties']); + ], $formatted['properties']); } public function testUpdateSharePropertyModifyProperties(): void { @@ -1465,13 +1489,13 @@ public function testUpdateSharePropertyModifyProperties(): void { $accessContext = new ShareAccessContext($this->owner); $this->dbConnection->beginTransaction(); - $id = $this->manager->createShare($accessContext); - $this->manager->addShareSource($accessContext, $id, new ShareSource(TestShareSourceType1::class, 'source1')); - $this->manager->addShareRecipient($accessContext, $id, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); + $share = $this->manager->createShare($accessContext); + $this->manager->addShareSource($accessContext, $share, new ShareSource(TestShareSourceType1::class, 'source1')); + $this->manager->addShareRecipient($accessContext, $share, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); $this->dbConnection->commit(); - $share = $this->getShare($accessContext, $id); + $formatted = $this->getShare($accessContext, $share->id); $this->assertEquals([ [ 'class' => TestSharePropertyType1::class, @@ -1495,9 +1519,9 @@ public function testUpdateSharePropertyModifyProperties(): void { 'type' => 'enum', 'valid_values' => ['old-value', 'modify-on-save-old-value', 'modify-on-save', 'modify-on-load'], ], - ], $share['properties']); + ], $formatted['properties']); - $share = $this->getShare($accessContext, $id); + $formatted = $this->getShare($accessContext, $share->id); $this->assertEquals([ [ 'class' => TestSharePropertyType1::class, @@ -1521,16 +1545,17 @@ public function testUpdateSharePropertyModifyProperties(): void { 'type' => 'enum', 'valid_values' => ['old-value', 'modify-on-save-old-value', 'modify-on-save', 'modify-on-load'], ], - ], $share['properties']); + ], $formatted['properties']); $this->dbConnection->beginTransaction(); - $this->manager->updateShareProperty($accessContext, $id, new ShareProperty(TestSharePropertyTypeModifyValue::class, 'old-value')); + $this->manager->updateShareProperty($accessContext, $share, new ShareProperty(TestSharePropertyTypeModifyValue::class, 'old-value')); $this->dbConnection->commit(); $before = $this->manager->getTime(); - $share = $this->updateShareProperty($accessContext, $id, new ShareProperty(TestSharePropertyTypeModifyValue::class, 'modify-on-save-old-value')); + $formatted = $this->updateShareProperty($accessContext, $share, new ShareProperty(TestSharePropertyTypeModifyValue::class, 'modify-on-save-old-value')); + $share = $this->reloadShare($accessContext, $share); $after = $this->manager->getTime(); - $this->assertDateBetween($before, $after, $this->parseTime($share['last_updated'])); + $this->assertDateBetween($before, $after, $this->parseTime($formatted['last_updated'])); $this->assertEquals([ [ 'class' => TestSharePropertyType1::class, @@ -1554,12 +1579,13 @@ public function testUpdateSharePropertyModifyProperties(): void { 'type' => 'enum', 'valid_values' => ['old-value', 'modify-on-save-old-value', 'modify-on-save', 'modify-on-load'], ], - ], $share['properties']); + ], $formatted['properties']); $before = $this->manager->getTime(); - $share = $this->updateShareProperty($accessContext, $id, new ShareProperty(TestSharePropertyTypeModifyValue::class, 'modify-on-save')); + $formatted = $this->updateShareProperty($accessContext, $share, new ShareProperty(TestSharePropertyTypeModifyValue::class, 'modify-on-save')); + $share = $this->reloadShare($accessContext, $share); $after = $this->manager->getTime(); - $this->assertDateBetween($before, $after, $this->parseTime($share['last_updated'])); + $this->assertDateBetween($before, $after, $this->parseTime($formatted['last_updated'])); $this->assertEquals([ [ 'class' => TestSharePropertyType1::class, @@ -1583,12 +1609,12 @@ public function testUpdateSharePropertyModifyProperties(): void { 'type' => 'enum', 'valid_values' => ['old-value', 'modify-on-save-old-value', 'modify-on-save', 'modify-on-load'], ], - ], $share['properties']); + ], $formatted['properties']); $before = $this->manager->getTime(); - $share = $this->updateShareProperty($accessContext, $id, new ShareProperty(TestSharePropertyTypeModifyValue::class, 'modify-on-load')); + $formatted = $this->updateShareProperty($accessContext, $share, new ShareProperty(TestSharePropertyTypeModifyValue::class, 'modify-on-load')); $after = $this->manager->getTime(); - $this->assertDateBetween($before, $after, $this->parseTime($share['last_updated'])); + $this->assertDateBetween($before, $after, $this->parseTime($formatted['last_updated'])); $this->assertEquals([ [ 'class' => TestSharePropertyType1::class, @@ -1612,26 +1638,28 @@ public function testUpdateSharePropertyModifyProperties(): void { 'type' => 'enum', 'valid_values' => ['old-value', 'modify-on-save-old-value', 'modify-on-save', 'modify-on-load'], ], - ], $share['properties']); + ], $formatted['properties']); } public function testUpdateSharePermission(): void { $accessContext = new ShareAccessContext($this->owner); $this->dbConnection->beginTransaction(); - $id = $this->manager->createShare($accessContext); - $this->manager->addShareSource($accessContext, $id, new ShareSource(TestShareSourceType1::class, 'source1')); - $this->manager->addShareRecipient($accessContext, $id, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); - $this->manager->getShare($accessContext, $id); + $share = $this->manager->createShare($accessContext); + $share = $this->manager->addShareSource($accessContext, $share, new ShareSource(TestShareSourceType1::class, 'source1')); + $share = $this->manager->addShareRecipient($accessContext, $share, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); + $share = $this->manager->getShare($accessContext, $share->id); $this->dbConnection->commit(); $before = $this->manager->getTime(); - $this->updateSharePermission($accessContext, $id, new SharePermission(ReshareSharePermissionType::class, true)); - $share = $this->updateSharePermission($accessContext, $id, new SharePermission(TestSharePermissionType1::class, true)); + $this->updateSharePermission($accessContext, $share, new SharePermission(ReshareSharePermissionType::class, true)); + $share = $this->reloadShare($accessContext, $share); + $formatted = $this->updateSharePermission($accessContext, $share, new SharePermission(TestSharePermissionType1::class, true)); + $share = $this->reloadShare($accessContext, $share); $after = $this->manager->getTime(); - $this->assertDateBetween($before, $after, $this->parseTime($share['last_updated'])); - $this->assertEquals(ShareState::Draft->value, $share['state']); + $this->assertDateBetween($before, $after, $this->parseTime($formatted['last_updated'])); + $this->assertEquals(ShareState::Draft->value, $formatted['state']); $this->assertEquals([ [ 'class' => ReshareSharePermissionType::class, @@ -1651,17 +1679,18 @@ public function testUpdateSharePermission(): void { 'enabled' => true, 'priority' => 1, ], - ], $share['permissions']); + ], $formatted['permissions']); $this->dbConnection->beginTransaction(); - $this->manager->updateShareState($accessContext, $id, ShareState::Active); + $share = $this->manager->updateShareState($accessContext, $share, ShareState::Active); $this->dbConnection->commit(); $before = $this->manager->getTime(); - $share = $this->updateSharePermission($accessContext, $id, new SharePermission(ReshareSharePermissionType::class, false)); + $formatted = $this->updateSharePermission($accessContext, $share, new SharePermission(ReshareSharePermissionType::class, false)); + $share = $this->reloadShare($accessContext, $share); $after = $this->manager->getTime(); - $this->assertDateBetween($before, $after, $this->parseTime($share['last_updated'])); - $this->assertEquals(ShareState::Active->value, $share['state']); + $this->assertDateBetween($before, $after, $this->parseTime($formatted['last_updated'])); + $this->assertEquals(ShareState::Active->value, $formatted['state']); $this->assertEquals([ [ 'class' => ReshareSharePermissionType::class, @@ -1681,13 +1710,13 @@ public function testUpdateSharePermission(): void { 'enabled' => true, 'priority' => 1, ], - ], $share['permissions']); + ], $formatted['permissions']); $before = $this->manager->getTime(); - $share = $this->updateSharePermission($accessContext, $id, new SharePermission(TestSharePermissionType1::class, false)); + $formatted = $this->updateSharePermission($accessContext, $share, new SharePermission(TestSharePermissionType1::class, false)); $after = $this->manager->getTime(); - $this->assertDateBetween($before, $after, $this->parseTime($share['last_updated'])); - $this->assertEquals(ShareState::Draft->value, $share['state']); + $this->assertDateBetween($before, $after, $this->parseTime($formatted['last_updated'])); + $this->assertEquals(ShareState::Draft->value, $formatted['state']); $this->assertEquals([ [ 'class' => ReshareSharePermissionType::class, @@ -1707,7 +1736,7 @@ public function testUpdateSharePermission(): void { 'enabled' => false, 'priority' => 1, ], - ], $share['permissions']); + ], $formatted['permissions']); } public function testUpdateSharePermissionInteractionRestricted(): void { @@ -1722,14 +1751,14 @@ public function testUpdateSharePermissionInteractionRestricted(): void { $accessContext = new ShareAccessContext($this->owner); $this->dbConnection->beginTransaction(); - $id = $this->manager->createShare($accessContext); - $this->manager->addShareSource($accessContext, $id, new ShareSource(TestShareSourceType1::class, 'source1')); - $this->manager->addShareRecipient($accessContext, $id, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); + $share = $this->manager->createShare($accessContext); + $this->manager->addShareSource($accessContext, $share, new ShareSource(TestShareSourceType1::class, 'source1')); + $this->manager->addShareRecipient($accessContext, $share, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); $this->dbConnection->commit(); try { - $this->updateSharePermission($accessContext, $id, new SharePermission(TestSharePermissionType1::class, true)); + $this->updateSharePermission($accessContext, $share, new SharePermission(TestSharePermissionType1::class, true)); $this->fail('Not restricted.'); } catch (HintException $hintException) { $this->assertEquals('You are not allowed to enable this permission.', $hintException->getHint()); @@ -1753,14 +1782,14 @@ public function testSelectSharePermissionPreset(): void { $before = $this->manager->getTime(); $this->dbConnection->beginTransaction(); - $id = $this->manager->createShare($accessContext); - $this->manager->getShare($accessContext, $id); + $share = $this->manager->createShare($accessContext); + $this->manager->getShare($accessContext, $share->id); $this->dbConnection->commit(); $after = $this->manager->getTime(); - $share = $this->getShare($accessContext, $id); - $this->assertDateBetween($before, $after, $this->parseTime($share['last_updated'])); - $this->assertNull($share['permission_preset']); + $formatted = $this->getShare($accessContext, $share->id); + $this->assertDateBetween($before, $after, $this->parseTime($formatted['last_updated'])); + $this->assertNull($formatted['permission_preset']); $this->assertEquals([ [ 'class' => TestSharePermissionType1::class, @@ -1789,13 +1818,14 @@ public function testSelectSharePermissionPreset(): void { 'enabled' => false, 'priority' => 1, ], - ], $share['permissions']); + ], $formatted['permissions']); $before = $this->manager->getTime(); - $share = $this->selectSharePermissionPreset($accessContext, $id, TestSharePermissionPreset2::class); + $formatted = $this->selectSharePermissionPreset($accessContext, $share, TestSharePermissionPreset2::class); + $share = $this->reloadShare($accessContext, $share); $after = $this->manager->getTime(); - $this->assertDateBetween($before, $after, $this->parseTime($share['last_updated'])); - $this->assertEquals(TestSharePermissionPreset2::class, $share['permission_preset']); + $this->assertDateBetween($before, $after, $this->parseTime($formatted['last_updated'])); + $this->assertEquals(TestSharePermissionPreset2::class, $formatted['permission_preset']); $this->assertEquals([ [ 'class' => TestSharePermissionType1::class, @@ -1824,13 +1854,14 @@ public function testSelectSharePermissionPreset(): void { 'enabled' => false, 'priority' => 1, ], - ], $share['permissions']); + ], $formatted['permissions']); $before = $this->manager->getTime(); - $share = $this->updateSharePermission($accessContext, $id, new SharePermission(TestSharePermissionType3::class, true)); + $formatted = $this->updateSharePermission($accessContext, $share, new SharePermission(TestSharePermissionType3::class, true)); + $share = $this->reloadShare($accessContext, $share); $after = $this->manager->getTime(); - $this->assertDateBetween($before, $after, $this->parseTime($share['last_updated'])); - $this->assertNull($share['permission_preset']); + $this->assertDateBetween($before, $after, $this->parseTime($formatted['last_updated'])); + $this->assertNull($formatted['permission_preset']); $this->assertEquals([ [ 'class' => TestSharePermissionType1::class, @@ -1859,13 +1890,14 @@ public function testSelectSharePermissionPreset(): void { 'enabled' => true, 'priority' => 1, ], - ], $share['permissions']); + ], $formatted['permissions']); $before = $this->manager->getTime(); - $share = $this->selectSharePermissionPreset($accessContext, $id, TestSharePermissionPreset1::class); + $formatted = $this->selectSharePermissionPreset($accessContext, $share, TestSharePermissionPreset1::class); + $share = $this->reloadShare($accessContext, $share); $after = $this->manager->getTime(); - $this->assertDateBetween($before, $after, $this->parseTime($share['last_updated'])); - $this->assertEquals(TestSharePermissionPreset1::class, $share['permission_preset']); + $this->assertDateBetween($before, $after, $this->parseTime($formatted['last_updated'])); + $this->assertEquals(TestSharePermissionPreset1::class, $formatted['permission_preset']); $this->assertEquals([ [ 'class' => TestSharePermissionType1::class, @@ -1894,13 +1926,13 @@ public function testSelectSharePermissionPreset(): void { 'enabled' => false, 'priority' => 1, ], - ], $share['permissions']); + ], $formatted['permissions']); $before = $this->manager->getTime(); - $share = $this->updateSharePermission($accessContext, $id, new SharePermission(TestSharePermissionType1::class, false)); + $formatted = $this->updateSharePermission($accessContext, $share, new SharePermission(TestSharePermissionType1::class, false)); $after = $this->manager->getTime(); - $this->assertDateBetween($before, $after, $this->parseTime($share['last_updated'])); - $this->assertNull($share['permission_preset']); + $this->assertDateBetween($before, $after, $this->parseTime($formatted['last_updated'])); + $this->assertNull($formatted['permission_preset']); $this->assertEquals([ [ 'class' => TestSharePermissionType1::class, @@ -1929,7 +1961,7 @@ public function testSelectSharePermissionPreset(): void { 'enabled' => false, 'priority' => 1, ], - ], $share['permissions']); + ], $formatted['permissions']); } public function testSelectSharePermissionPresetCompatible(): void { @@ -1947,14 +1979,14 @@ public function testSelectSharePermissionPresetCompatible(): void { $before = $this->manager->getTime(); $this->dbConnection->beginTransaction(); - $id = $this->manager->createShare($accessContext); - $this->manager->getShare($accessContext, $id); + $share = $this->manager->createShare($accessContext); + $this->manager->getShare($accessContext, $share->id); $this->dbConnection->commit(); $after = $this->manager->getTime(); - $share = $this->getShare($accessContext, $id); - $this->assertDateBetween($before, $after, $this->parseTime($share['last_updated'])); - $this->assertNull($share['permission_preset']); + $formatted = $this->getShare($accessContext, $share->id); + $this->assertDateBetween($before, $after, $this->parseTime($formatted['last_updated'])); + $this->assertNull($formatted['permission_preset']); $this->assertEquals([ [ 'class' => TestSharePermissionType2::class, @@ -1965,13 +1997,14 @@ public function testSelectSharePermissionPresetCompatible(): void { 'enabled' => false, 'priority' => 1, ], - ], $share['permissions']); + ], $formatted['permissions']); $before = $this->manager->getTime(); - $share = $this->selectSharePermissionPreset($accessContext, $id, TestSharePermissionPreset2::class); + $formatted = $this->selectSharePermissionPreset($accessContext, $share, TestSharePermissionPreset2::class); + $share = $this->reloadShare($accessContext, $share); $after = $this->manager->getTime(); - $this->assertDateBetween($before, $after, $this->parseTime($share['last_updated'])); - $this->assertEquals(TestSharePermissionPreset2::class, $share['permission_preset']); + $this->assertDateBetween($before, $after, $this->parseTime($formatted['last_updated'])); + $this->assertEquals(TestSharePermissionPreset2::class, $formatted['permission_preset']); $this->assertEquals([ [ 'class' => TestSharePermissionType2::class, @@ -1982,13 +2015,14 @@ public function testSelectSharePermissionPresetCompatible(): void { 'enabled' => true, 'priority' => 1, ], - ], $share['permissions']); + ], $formatted['permissions']); $before = $this->manager->getTime(); - $share = $this->addShareSource($accessContext, $id, new ShareSource(TestShareSourceType1::class, 'source1')); + $formatted = $this->addShareSource($accessContext, $share, new ShareSource(TestShareSourceType1::class, 'source1')); + $share = $this->reloadShare($accessContext, $share); $after = $this->manager->getTime(); - $this->assertDateBetween($before, $after, $this->parseTime($share['last_updated'])); - $this->assertNull($share['permission_preset']); + $this->assertDateBetween($before, $after, $this->parseTime($formatted['last_updated'])); + $this->assertNull($formatted['permission_preset']); $this->assertEquals([ [ 'class' => TestSharePermissionType1::class, @@ -2008,13 +2042,13 @@ public function testSelectSharePermissionPresetCompatible(): void { 'enabled' => true, 'priority' => 1, ], - ], $share['permissions']); + ], $formatted['permissions']); $before = $this->manager->getTime(); - $share = $this->selectSharePermissionPreset($accessContext, $id, TestSharePermissionPreset2::class); + $formatted = $this->selectSharePermissionPreset($accessContext, $share, TestSharePermissionPreset2::class); $after = $this->manager->getTime(); - $this->assertDateBetween($before, $after, $this->parseTime($share['last_updated'])); - $this->assertEquals(TestSharePermissionPreset2::class, $share['permission_preset']); + $this->assertDateBetween($before, $after, $this->parseTime($formatted['last_updated'])); + $this->assertEquals(TestSharePermissionPreset2::class, $formatted['permission_preset']); $this->assertEquals([ [ 'class' => TestSharePermissionType1::class, @@ -2034,19 +2068,19 @@ public function testSelectSharePermissionPresetCompatible(): void { 'enabled' => true, 'priority' => 1, ], - ], $share['permissions']); + ], $formatted['permissions']); } public function testDeleteShare(): void { $accessContext = new ShareAccessContext($this->owner); $this->dbConnection->beginTransaction(); - $id = $this->manager->createShare($accessContext); + $share = $this->manager->createShare($accessContext); - $this->deleteShare($accessContext, $id); + $this->deleteShare($accessContext, $share); try { - $this->manager->getShare(new ShareAccessContext(overrideChecks: true), $id); + $this->manager->getShare(new ShareAccessContext(overrideChecks: true), $share->id); $this->fail('Share not deleted.'); } catch (HintException $hintException) { $this->assertEquals('Share not found.', $hintException->getHint()); @@ -2060,19 +2094,19 @@ public function testGetShare(): void { $before = $this->manager->getTime(); $this->dbConnection->beginTransaction(); - $id = $this->manager->createShare($accessContext); - $this->manager->addShareSource($accessContext, $id, new ShareSource(TestShareSourceType1::class, 'source1')); - $this->manager->addShareRecipient($accessContext, $id, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); - $this->manager->getShare($accessContext, $id); + $share = $this->manager->createShare($accessContext); + $this->manager->addShareSource($accessContext, $share, new ShareSource(TestShareSourceType1::class, 'source1')); + $this->manager->addShareRecipient($accessContext, $share, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); + $this->manager->getShare($accessContext, $share->id); $this->dbConnection->commit(); $after = $this->manager->getTime(); - $share = $this->getShare($accessContext, $id); - $this->assertDateBetween($before, $after, $this->parseTime($share['last_updated'])); - unset($share['last_updated']); + $formatted = $this->getShare($accessContext, $share->id); + $this->assertDateBetween($before, $after, $this->parseTime($formatted['last_updated'])); + unset($formatted['last_updated']); $this->assertEquals([ - 'id' => $id, + 'id' => $share->id, 'owner' => [ 'user_id' => 'owner', 'instance' => null, @@ -2150,21 +2184,21 @@ public function testGetShare(): void { ], ], 'permission_preset' => null, - ], $share); + ], $formatted); } public function testGetShareAsRecipientNotActive(): void { $accessContext = new ShareAccessContext($this->owner); $this->dbConnection->beginTransaction(); - $id = $this->manager->createShare($accessContext); - $this->manager->addShareSource($accessContext, $id, new ShareSource(TestShareSourceType1::class, 'source1')); - $this->manager->addShareRecipient($accessContext, $id, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); + $share = $this->manager->createShare($accessContext); + $this->manager->addShareSource($accessContext, $share, new ShareSource(TestShareSourceType1::class, 'source1')); + $this->manager->addShareRecipient($accessContext, $share, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); $this->dbConnection->commit(); try { - $this->getShare(new ShareAccessContext(currentUser: $this->user1), $id); + $this->getShare(new ShareAccessContext(currentUser: $this->user1), $share->id); $this->fail('Draft share visible.'); } catch (HintException $hintException) { $this->assertEquals('Share not found.', $hintException->getHint()); @@ -2176,22 +2210,22 @@ public function testGetShareAsRecipientActive(): void { $before = $this->manager->getTime(); $this->dbConnection->beginTransaction(); - $id = $this->manager->createShare($accessContext); - $this->manager->addShareSource($accessContext, $id, new ShareSource(TestShareSourceType1::class, 'source1')); - $this->manager->addShareRecipient($accessContext, $id, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); - $this->manager->addShareRecipient($accessContext, $id, new ShareRecipient(TestShareRecipientType2::class, 'recipient2', null)); - $this->manager->getShare($accessContext, $id); - $this->manager->updateSharePermission($accessContext, $id, new SharePermission(TestSharePermissionType1::class, true)); - $this->manager->updateShareState($accessContext, $id, ShareState::Active); + $share = $this->manager->createShare($accessContext); + $share = $this->manager->addShareSource($accessContext, $share, new ShareSource(TestShareSourceType1::class, 'source1')); + $share = $this->manager->addShareRecipient($accessContext, $share, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); + $share = $this->manager->addShareRecipient($accessContext, $share, new ShareRecipient(TestShareRecipientType2::class, 'recipient2', null)); + + $share = $this->manager->updateSharePermission($accessContext, $share, new SharePermission(TestSharePermissionType1::class, true)); + $share = $this->manager->updateShareState($accessContext, $share, ShareState::Active); $this->dbConnection->commit(); $after = $this->manager->getTime(); - $share = $this->getShare(new ShareAccessContext(currentUser: $this->user1), $id); - $this->assertDateBetween($before, $after, $this->parseTime($share['last_updated'])); - unset($share['last_updated']); + $formatted = $this->getShare(new ShareAccessContext(currentUser: $this->user1), $share->id); + $this->assertDateBetween($before, $after, $this->parseTime($formatted['last_updated'])); + unset($formatted['last_updated']); $this->assertEquals([ - 'id' => $id, + 'id' => $share->id, 'owner' => [ 'user_id' => 'owner', 'instance' => null, @@ -2290,7 +2324,7 @@ public function testGetShareAsRecipientActive(): void { ], ], 'permission_preset' => TestSharePermissionPreset1::class, - ], $share); + ], $formatted); } public function testGetShareAsRecipientWithArguments(): void { @@ -2300,21 +2334,21 @@ public function testGetShareAsRecipientWithArguments(): void { $before = $this->manager->getTime(); $this->dbConnection->beginTransaction(); - $id = $this->manager->createShare($accessContext); - $this->manager->addShareSource($accessContext, $id, new ShareSource(TestShareSourceType1::class, 'source1')); - $this->manager->addShareRecipient($accessContext, $id, new ShareRecipient(TestShareRecipientTypeArguments::class, 'secret', null)); - $this->manager->getShare($accessContext, $id); - $this->manager->updateSharePermission($accessContext, $id, new SharePermission(TestSharePermissionType1::class, true)); - $this->manager->updateShareState($accessContext, $id, ShareState::Active); + $share = $this->manager->createShare($accessContext); + $share = $this->manager->addShareSource($accessContext, $share, new ShareSource(TestShareSourceType1::class, 'source1')); + $share = $this->manager->addShareRecipient($accessContext, $share, new ShareRecipient(TestShareRecipientTypeArguments::class, 'secret', null)); + + $share = $this->manager->updateSharePermission($accessContext, $share, new SharePermission(TestSharePermissionType1::class, true)); + $share = $this->manager->updateShareState($accessContext, $share, ShareState::Active); $this->dbConnection->commit(); $after = $this->manager->getTime(); - $share = $this->getShare(new ShareAccessContext(currentUser: $this->user1, arguments: [TestShareRecipientTypeArguments::class => 'secret']), $id); - $this->assertDateBetween($before, $after, $this->parseTime($share['last_updated'])); - unset($share['last_updated']); + $formatted = $this->getShare(new ShareAccessContext(currentUser: $this->user1, arguments: [TestShareRecipientTypeArguments::class => 'secret']), $share->id); + $this->assertDateBetween($before, $after, $this->parseTime($formatted['last_updated'])); + unset($formatted['last_updated']); $this->assertEquals([ - 'id' => $id, + 'id' => $share->id, 'owner' => [ 'user_id' => 'owner', 'instance' => null, @@ -2381,10 +2415,10 @@ public function testGetShareAsRecipientWithArguments(): void { ], ], 'permission_preset' => TestSharePermissionPreset1::class, - ], $share); + ], $formatted); try { - $this->getShare(new ShareAccessContext(currentUser: $this->user1), $id); + $this->getShare(new ShareAccessContext(currentUser: $this->user1), $share->id); $this->fail('Share visible without arguments.'); } catch (HintException $hintException) { $this->assertEquals('Share not found.', $hintException->getHint()); @@ -2397,19 +2431,18 @@ public function testGetShareWithSecretNotActive(): void { $accessContext = new ShareAccessContext($this->owner); $this->dbConnection->beginTransaction(); - $id = $this->manager->createShare($accessContext); - $this->manager->addShareSource($accessContext, $id, new ShareSource(TestShareSourceType1::class, 'source1')); - $this->manager->addShareRecipient($accessContext, $id, new ShareRecipient(TestShareRecipientTypeArguments::class, 'secret', null)); - $this->manager->getShare($accessContext, $id); - $this->manager->updateSharePermission($accessContext, $id, new SharePermission(TestSharePermissionType1::class, true)); + $share = $this->manager->createShare($accessContext); + $share = $this->manager->addShareSource($accessContext, $share, new ShareSource(TestShareSourceType1::class, 'source1')); + $share = $this->manager->addShareRecipient($accessContext, $share, new ShareRecipient(TestShareRecipientTypeArguments::class, 'secret', null)); + + $share = $this->manager->updateSharePermission($accessContext, $share, new SharePermission(TestSharePermissionType1::class, true)); - $share = $this->manager->getShare($accessContext, $id); $this->dbConnection->commit(); $secret = $share->recipients[0]->secret; $this->assertNotNull($secret); try { - $this->getShare(new ShareAccessContext(secret: $secret), $id); + $this->getShare(new ShareAccessContext(secret: $secret), $share->id); $this->fail('Draft share visible with secret.'); } catch (HintException $hintException) { $this->assertEquals('Share not found.', $hintException->getHint()); @@ -2423,25 +2456,24 @@ public function testGetShareWithSecretActive(): void { $before = $this->manager->getTime(); $this->dbConnection->beginTransaction(); - $id = $this->manager->createShare($accessContext); - $this->manager->addShareSource($accessContext, $id, new ShareSource(TestShareSourceType1::class, 'source1')); - $this->manager->addShareRecipient($accessContext, $id, new ShareRecipient(TestShareRecipientTypeArguments::class, 'secret', null)); - $this->manager->getShare($accessContext, $id); - $this->manager->updateSharePermission($accessContext, $id, new SharePermission(TestSharePermissionType1::class, true)); - $this->manager->updateShareState($accessContext, $id, ShareState::Active); + $share = $this->manager->createShare($accessContext); + $share = $this->manager->addShareSource($accessContext, $share, new ShareSource(TestShareSourceType1::class, 'source1')); + $share = $this->manager->addShareRecipient($accessContext, $share, new ShareRecipient(TestShareRecipientTypeArguments::class, 'secret', null)); + + $share = $this->manager->updateSharePermission($accessContext, $share, new SharePermission(TestSharePermissionType1::class, true)); + $share = $this->manager->updateShareState($accessContext, $share, ShareState::Active); $after = $this->manager->getTime(); - $share = $this->manager->getShare($accessContext, $id); $this->dbConnection->commit(); $secret = $share->recipients[0]->secret; $this->assertNotNull($secret); - $share = $this->getShare(new ShareAccessContext(secret: $secret), $id); - $this->assertDateBetween($before, $after, $this->parseTime($share['last_updated'])); - unset($share['last_updated']); + $formatted = $this->getShare(new ShareAccessContext(secret: $secret), $share->id); + $this->assertDateBetween($before, $after, $this->parseTime($formatted['last_updated'])); + unset($formatted['last_updated']); $this->assertEquals([ - 'id' => $id, + 'id' => $share->id, 'owner' => [ 'user_id' => 'owner', 'instance' => null, @@ -2508,10 +2540,10 @@ public function testGetShareWithSecretActive(): void { ], ], 'permission_preset' => TestSharePermissionPreset1::class, - ], $share); + ], $formatted); try { - $this->getShare(new ShareAccessContext(), $id); + $this->getShare(new ShareAccessContext(), $share->id); $this->fail('Share visible without secret.'); } catch (HintException $hintException) { $this->assertEquals('Share not found.', $hintException->getHint()); @@ -2522,17 +2554,17 @@ public function testGetShareAsNonRecipient(): void { $accessContext = new ShareAccessContext($this->owner); $this->dbConnection->beginTransaction(); - $id = $this->manager->createShare($accessContext); - $this->manager->addShareSource($accessContext, $id, new ShareSource(TestShareSourceType1::class, 'source1')); - $this->manager->addShareRecipient($accessContext, $id, new ShareRecipient(TestShareRecipientType2::class, 'recipient2', null)); - $this->manager->getShare($accessContext, $id); - $this->manager->updateSharePermission($accessContext, $id, new SharePermission(TestSharePermissionType1::class, true)); - $this->manager->updateShareState($accessContext, $id, ShareState::Active); + $share = $this->manager->createShare($accessContext); + $share = $this->manager->addShareSource($accessContext, $share, new ShareSource(TestShareSourceType1::class, 'source1')); + $share = $this->manager->addShareRecipient($accessContext, $share, new ShareRecipient(TestShareRecipientType2::class, 'recipient2', null)); + + $share = $this->manager->updateSharePermission($accessContext, $share, new SharePermission(TestSharePermissionType1::class, true)); + $share = $this->manager->updateShareState($accessContext, $share, ShareState::Active); $this->dbConnection->commit(); try { - $this->getShare(new ShareAccessContext(currentUser: $this->user1), $id); + $this->getShare(new ShareAccessContext(currentUser: $this->user1), $share->id); $this->fail('Share visible as non-recipient.'); } catch (HintException $hintException) { $this->assertEquals('Share not found.', $hintException->getHint()); @@ -2548,22 +2580,22 @@ public function testGetShareAsRecipientFilteredProperties(): void { $before = $this->manager->getTime(); $this->dbConnection->beginTransaction(); - $id = $this->manager->createShare($accessContext); - $this->manager->addShareSource($accessContext, $id, new ShareSource(TestShareSourceType1::class, 'source1')); - $this->manager->addShareRecipient($accessContext, $id, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); - $this->manager->getShare($accessContext, $id); - $this->manager->updateSharePermission($accessContext, $id, new SharePermission(TestSharePermissionType1::class, true)); - $this->manager->updateShareState($accessContext, $id, ShareState::Active); - $this->manager->updateShareProperty($accessContext, $id, new ShareProperty(TestSharePropertyTypeFilter::class, 'visible')); + $share = $this->manager->createShare($accessContext); + $share = $this->manager->addShareSource($accessContext, $share, new ShareSource(TestShareSourceType1::class, 'source1')); + $share = $this->manager->addShareRecipient($accessContext, $share, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); + + $share = $this->manager->updateSharePermission($accessContext, $share, new SharePermission(TestSharePermissionType1::class, true)); + $share = $this->manager->updateShareState($accessContext, $share, ShareState::Active); + $share = $this->manager->updateShareProperty($accessContext, $share, new ShareProperty(TestSharePropertyTypeFilter::class, 'visible')); $this->dbConnection->commit(); $after = $this->manager->getTime(); - $share = $this->getShare(new ShareAccessContext(currentUser: $this->user1), $id); - $this->assertDateBetween($before, $after, $this->parseTime($share['last_updated'])); - unset($share['last_updated']); + $formatted = $this->getShare(new ShareAccessContext(currentUser: $this->user1), $share->id); + $this->assertDateBetween($before, $after, $this->parseTime($formatted['last_updated'])); + unset($formatted['last_updated']); $this->assertEquals([ - 'id' => $id, + 'id' => $share->id, 'owner' => [ 'user_id' => 'owner', 'instance' => null, @@ -2652,19 +2684,20 @@ public function testGetShareAsRecipientFilteredProperties(): void { ], ], 'permission_preset' => TestSharePermissionPreset1::class, - ], $share); + ], $formatted); $before = $this->manager->getTime(); $this->dbConnection->beginTransaction(); - $this->manager->updateShareProperty($accessContext, $id, new ShareProperty(TestSharePropertyTypeFilter::class, 'filtered')); + $this->manager->updateShareProperty($accessContext, $share, new ShareProperty(TestSharePropertyTypeFilter::class, 'filtered')); + $share = $this->reloadShare($accessContext, $share); $this->dbConnection->commit(); $after = $this->manager->getTime(); - $share = $this->getShare(new ShareAccessContext(currentUser: $this->owner), $id); - $this->assertDateBetween($before, $after, $this->parseTime($share['last_updated'])); - unset($share['last_updated']); + $formatted = $this->getShare(new ShareAccessContext(currentUser: $this->owner), $share->id); + $this->assertDateBetween($before, $after, $this->parseTime($formatted['last_updated'])); + unset($formatted['last_updated']); $this->assertEquals([ - 'id' => $id, + 'id' => $share->id, 'owner' => [ 'user_id' => 'owner', 'instance' => null, @@ -2753,10 +2786,10 @@ public function testGetShareAsRecipientFilteredProperties(): void { ], ], 'permission_preset' => TestSharePermissionPreset1::class, - ], $share); + ], $formatted); try { - $this->getShare(new ShareAccessContext(currentUser: $this->user1), $id); + $this->getShare(new ShareAccessContext(currentUser: $this->user1), $share->id); $this->fail('Share visible with active filter property.'); } catch (HintException $hintException) { $this->assertEquals('Share not found.', $hintException->getHint()); @@ -2772,21 +2805,21 @@ public function testGetShareAsRecipientFilteredArguments(): void { $before = $this->manager->getTime(); $this->dbConnection->beginTransaction(); - $id = $this->manager->createShare($accessContext); - $this->manager->addShareSource($accessContext, $id, new ShareSource(TestShareSourceType1::class, 'source1')); - $this->manager->addShareRecipient($accessContext, $id, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); - $this->manager->getShare($accessContext, $id); - $this->manager->updateSharePermission($accessContext, $id, new SharePermission(TestSharePermissionType1::class, true)); - $this->manager->updateShareState($accessContext, $id, ShareState::Active); + $share = $this->manager->createShare($accessContext); + $share = $this->manager->addShareSource($accessContext, $share, new ShareSource(TestShareSourceType1::class, 'source1')); + $share = $this->manager->addShareRecipient($accessContext, $share, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); + + $share = $this->manager->updateSharePermission($accessContext, $share, new SharePermission(TestSharePermissionType1::class, true)); + $share = $this->manager->updateShareState($accessContext, $share, ShareState::Active); $this->dbConnection->commit(); $after = $this->manager->getTime(); - $share = $this->getShare(new ShareAccessContext(currentUser: $this->user1), $id); - $this->assertDateBetween($before, $after, $this->parseTime($share['last_updated'])); - unset($share['last_updated']); + $formatted = $this->getShare(new ShareAccessContext(currentUser: $this->user1), $share->id); + $this->assertDateBetween($before, $after, $this->parseTime($formatted['last_updated'])); + unset($formatted['last_updated']); $this->assertEquals([ - 'id' => $id, + 'id' => $share->id, 'owner' => [ 'user_id' => 'owner', 'instance' => null, @@ -2875,13 +2908,13 @@ public function testGetShareAsRecipientFilteredArguments(): void { ], ], 'permission_preset' => TestSharePermissionPreset1::class, - ], $share); + ], $formatted); - $share = $this->getShare(new ShareAccessContext(currentUser: $this->owner, arguments: [TestSharePropertyTypeFilter::class => 'filtered']), $id); - $this->assertDateBetween($before, $after, $this->parseTime($share['last_updated'])); - unset($share['last_updated']); + $formatted = $this->getShare(new ShareAccessContext(currentUser: $this->owner, arguments: [TestSharePropertyTypeFilter::class => 'filtered']), $share->id); + $this->assertDateBetween($before, $after, $this->parseTime($formatted['last_updated'])); + unset($formatted['last_updated']); $this->assertEquals([ - 'id' => $id, + 'id' => $share->id, 'owner' => [ 'user_id' => 'owner', 'instance' => null, @@ -2970,10 +3003,10 @@ public function testGetShareAsRecipientFilteredArguments(): void { ], ], 'permission_preset' => TestSharePermissionPreset1::class, - ], $share); + ], $formatted); try { - $this->getShare(new ShareAccessContext(currentUser: $this->user1, arguments: [TestSharePropertyTypeFilter::class => 'filtered']), $id); + $this->getShare(new ShareAccessContext(currentUser: $this->user1, arguments: [TestSharePropertyTypeFilter::class => 'filtered']), $share->id); $this->fail('Share visible with filtered value as recipient.'); } catch (HintException $hintException) { $this->assertEquals('Share not found.', $hintException->getHint()); @@ -3013,20 +3046,20 @@ public function testGetShareWithPublicSecret(bool $isSecretPublic): void { $before = $this->manager->getTime(); $this->dbConnection->beginTransaction(); - $id = $this->manager->createShare($accessContext); - $this->manager->addShareRecipient($accessContext, $id, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); - $this->manager->addShareRecipient($accessContext, $id, new ShareRecipient(TestShareRecipientTypePublicSecret::class, 'recipient2', null)); + $share = $this->manager->createShare($accessContext); + $this->manager->addShareRecipient($accessContext, $share, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); + $this->manager->addShareRecipient($accessContext, $share, new ShareRecipient(TestShareRecipientTypePublicSecret::class, 'recipient2', null)); $this->dbConnection->commit(); $after = $this->manager->getTime(); - $share = $this->getShare($accessContext, $id); - $this->assertDateBetween($before, $after, $this->parseTime($share['last_updated'])); - unset($share['last_updated']); - $this->assertIsList($share['recipients']); - $this->assertCount(2, $share['recipients']); + $formatted = $this->getShare($accessContext, $share->id); + $this->assertDateBetween($before, $after, $this->parseTime($formatted['last_updated'])); + unset($formatted['last_updated']); + $this->assertIsList($formatted['recipients']); + $this->assertCount(2, $formatted['recipients']); // Sort because database order is not guaranteed - usort($share['recipients'], fn (array $a, array $b): int => $a['value'] <=> $b['value']); + usort($formatted['recipients'], fn (array $a, array $b): int => $a['value'] <=> $b['value']); $this->assertEquals([ 'class' => TestShareRecipientType1::class, 'value' => 'recipient1', @@ -3047,24 +3080,24 @@ public function testGetShareWithPublicSecret(bool $isSecretPublic): void { 'dark' => 'http://localhost/index.php/avatar/owner/64/dark', ], ], - ], $share['recipients'][0]); - $this->assertIsArray($share['recipients'][1]); + ], $formatted['recipients'][0]); + $this->assertIsArray($formatted['recipients'][1]); if ($isSecretPublic) { - $this->assertArrayHasKey('secret', $share['recipients'][1]); - $this->assertIsArray($share['recipients'][1]['secret']); + $this->assertArrayHasKey('secret', $formatted['recipients'][1]); + $this->assertIsArray($formatted['recipients'][1]['secret']); - $this->assertArrayHasKey('updatable', $share['recipients'][1]['secret']); - $this->assertFalse($share['recipients'][1]['secret']['updatable']); + $this->assertArrayHasKey('updatable', $formatted['recipients'][1]['secret']); + $this->assertFalse($formatted['recipients'][1]['secret']['updatable']); - $this->assertArrayHasKey('value', $share['recipients'][1]['secret']); - $this->assertIsString($share['recipients'][1]['secret']['value']); - $this->assertNotEmpty($share['recipients'][1]['secret']['value']); + $this->assertArrayHasKey('value', $formatted['recipients'][1]['secret']); + $this->assertIsString($formatted['recipients'][1]['secret']['value']); + $this->assertNotEmpty($formatted['recipients'][1]['secret']['value']); - $this->assertArrayHasKey('url', $share['recipients'][1]['secret']); - $this->assertIsString($share['recipients'][1]['secret']['url']); - $this->assertMatchesRegularExpression('/http:\/\/localhost\/index\.php\/s\/.+/', $share['recipients'][1]['secret']['url']); + $this->assertArrayHasKey('url', $formatted['recipients'][1]['secret']); + $this->assertIsString($formatted['recipients'][1]['secret']['url']); + $this->assertMatchesRegularExpression('/http:\/\/localhost\/index\.php\/s\/.+/', $formatted['recipients'][1]['secret']['url']); } else { - $this->assertArrayNotHasKey('url', $share['recipients'][1]); + $this->assertArrayNotHasKey('url', $formatted['recipients'][1]); } } @@ -3091,58 +3124,58 @@ public function testGetShareWithSecret(): void { $before = $this->manager->getTime(); $this->dbConnection->beginTransaction(); - $id = $this->manager->createShare($accessContext); - $this->manager->addShareSource($accessContext, $id, new ShareSource(TestShareSourceType1::class, 'source1')); - $this->manager->addShareRecipient($accessContext, $id, new ShareRecipient(TestShareRecipientTypePublicSecret::class, 'recipient1', null)); - $this->manager->getShare($accessContext, $id); - $this->manager->updateSharePermission($accessContext, $id, new SharePermission(ReshareSharePermissionType::class, true)); - $this->manager->updateShareState($accessContext, $id, ShareState::Active); - $this->manager->addShareRecipient(new ShareAccessContext($this->user1), $id, new ShareRecipient(TestShareRecipientTypePublicSecret::class, 'recipient2', null)); - $this->manager->addShareRecipient(new ShareAccessContext($this->user1), $id, new ShareRecipient(TestShareRecipientTypePublicSecret::class, 'recipient3', null)); - $this->manager->addShareRecipient(new ShareAccessContext($this->user2), $id, new ShareRecipient(TestShareRecipientTypePublicSecret::class, 'recipient4', null)); + $share = $this->manager->createShare($accessContext); + $share = $this->manager->addShareSource($accessContext, $share, new ShareSource(TestShareSourceType1::class, 'source1')); + $share = $this->manager->addShareRecipient($accessContext, $share, new ShareRecipient(TestShareRecipientTypePublicSecret::class, 'recipient1', null)); + + $share = $this->manager->updateSharePermission($accessContext, $share, new SharePermission(ReshareSharePermissionType::class, true)); + $share = $this->manager->updateShareState($accessContext, $share, ShareState::Active); + $share = $this->manager->addShareRecipient(new ShareAccessContext($this->user1), $share, new ShareRecipient(TestShareRecipientTypePublicSecret::class, 'recipient2', null)); + $share = $this->manager->addShareRecipient(new ShareAccessContext($this->user1), $share, new ShareRecipient(TestShareRecipientTypePublicSecret::class, 'recipient3', null)); + $share = $this->manager->addShareRecipient(new ShareAccessContext($this->user2), $share, new ShareRecipient(TestShareRecipientTypePublicSecret::class, 'recipient4', null)); $this->dbConnection->commit(); $after = $this->manager->getTime(); - $share = $this->getShare(new ShareAccessContext($this->user2), $id); - $this->assertDateBetween($before, $after, $this->parseTime($share['last_updated'])); + $formatted = $this->getShare(new ShareAccessContext($this->user2), $share->id); + $this->assertDateBetween($before, $after, $this->parseTime($formatted['last_updated'])); - usort($share['recipients'], fn (array $a, array $b): int => $a['value'] <=> $b['value']); - $this->assertArrayHasKey('recipients', $share); - $this->assertIsArray($share['recipients']); - $this->assertCount(4, $share['recipients']); + usort($formatted['recipients'], fn (array $a, array $b): int => $a['value'] <=> $b['value']); + $this->assertArrayHasKey('recipients', $formatted); + $this->assertIsArray($formatted['recipients']); + $this->assertCount(4, $formatted['recipients']); // Parent - secret not visible - $this->assertIsArray($share['recipients'][0]); - $this->assertArrayHasKey('value', $share['recipients'][0]); - $this->assertEquals('recipient1', $share['recipients'][0]['value']); - $this->assertArrayHasKey('secret', $share['recipients'][0]); - $this->assertIsArray($share['recipients'][0]['secret']); - $this->assertArrayNotHasKey('value', $share['recipients'][0]['secret']); + $this->assertIsArray($formatted['recipients'][0]); + $this->assertArrayHasKey('value', $formatted['recipients'][0]); + $this->assertEquals('recipient1', $formatted['recipients'][0]['value']); + $this->assertArrayHasKey('secret', $formatted['recipients'][0]); + $this->assertIsArray($formatted['recipients'][0]['secret']); + $this->assertArrayNotHasKey('value', $formatted['recipients'][0]['secret']); // Self - secret visible - $this->assertIsArray($share['recipients'][1]); - $this->assertArrayHasKey('value', $share['recipients'][1]); - $this->assertEquals('recipient2', $share['recipients'][1]['value']); - $this->assertArrayHasKey('secret', $share['recipients'][1]); - $this->assertIsArray($share['recipients'][1]['secret']); - $this->assertNotEmpty($share['recipients'][1]['secret']['value']); + $this->assertIsArray($formatted['recipients'][1]); + $this->assertArrayHasKey('value', $formatted['recipients'][1]); + $this->assertEquals('recipient2', $formatted['recipients'][1]['value']); + $this->assertArrayHasKey('secret', $formatted['recipients'][1]); + $this->assertIsArray($formatted['recipients'][1]['secret']); + $this->assertNotEmpty($formatted['recipients'][1]['secret']['value']); // Sibling - secret not visible - $this->assertIsArray($share['recipients'][2]); - $this->assertArrayHasKey('value', $share['recipients'][2]); - $this->assertEquals('recipient3', $share['recipients'][2]['value']); - $this->assertArrayHasKey('secret', $share['recipients'][2]); - $this->assertIsArray($share['recipients'][2]['secret']); - $this->assertArrayNotHasKey('value', $share['recipients'][2]['secret']); + $this->assertIsArray($formatted['recipients'][2]); + $this->assertArrayHasKey('value', $formatted['recipients'][2]); + $this->assertEquals('recipient3', $formatted['recipients'][2]['value']); + $this->assertArrayHasKey('secret', $formatted['recipients'][2]); + $this->assertIsArray($formatted['recipients'][2]['secret']); + $this->assertArrayNotHasKey('value', $formatted['recipients'][2]['secret']); // Child - secret visible - $this->assertIsArray($share['recipients'][3]); - $this->assertArrayHasKey('value', $share['recipients'][3]); - $this->assertEquals('recipient4', $share['recipients'][3]['value']); - $this->assertArrayHasKey('secret', $share['recipients'][3]); - $this->assertIsArray($share['recipients'][3]['secret']); - $this->assertNotEmpty($share['recipients'][3]['secret']['value']); + $this->assertIsArray($formatted['recipients'][3]); + $this->assertArrayHasKey('value', $formatted['recipients'][3]); + $this->assertEquals('recipient4', $formatted['recipients'][3]['value']); + $this->assertArrayHasKey('secret', $formatted['recipients'][3]); + $this->assertIsArray($formatted['recipients'][3]['secret']); + $this->assertNotEmpty($formatted['recipients'][3]['secret']['value']); } public function testGetShareUniqueDisplayNames(): void { @@ -3155,21 +3188,21 @@ public function testGetShareUniqueDisplayNames(): void { $accessContext = new ShareAccessContext($this->owner); $this->dbConnection->beginTransaction(); - $id = $this->manager->createShare($accessContext); - $this->manager->addShareSource($accessContext, $id, new ShareSource(TestShareSourceType1::class, 'source1')); - $this->manager->addShareSource($accessContext, $id, new ShareSource(TestShareSourceType2::class, 'source2')); - $this->manager->addShareSource($accessContext, $id, new ShareSource(TestShareSourceType2::class, 'source3')); - $this->manager->addShareRecipient($accessContext, $id, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); - $this->manager->addShareRecipient($accessContext, $id, new ShareRecipient(TestShareRecipientType2::class, 'recipient2', null)); - $this->manager->addShareRecipient($accessContext, $id, new ShareRecipient(TestShareRecipientType2::class, 'recipient3', null)); + $share = $this->manager->createShare($accessContext); + $share = $this->manager->addShareSource($accessContext, $share, new ShareSource(TestShareSourceType1::class, 'source1')); + $share = $this->manager->addShareSource($accessContext, $share, new ShareSource(TestShareSourceType2::class, 'source2')); + $share = $this->manager->addShareSource($accessContext, $share, new ShareSource(TestShareSourceType2::class, 'source3')); + $share = $this->manager->addShareRecipient($accessContext, $share, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); + $share = $this->manager->addShareRecipient($accessContext, $share, new ShareRecipient(TestShareRecipientType2::class, 'recipient2', null)); + $share = $this->manager->addShareRecipient($accessContext, $share, new ShareRecipient(TestShareRecipientType2::class, 'recipient3', null)); $this->dbConnection->commit(); - $share = $this->getShare($accessContext, $id); + $formatted = $this->getShare($accessContext, $share->id); // Sort because database order is not guaranteed - usort($share['sources'], fn (array $a, array $b): int => $a['value'] <=> $b['value']); - usort($share['recipients'], fn (array $a, array $b): int => $a['value'] <=> $b['value']); + usort($formatted['sources'], fn (array $a, array $b): int => $a['value'] <=> $b['value']); + usort($formatted['recipients'], fn (array $a, array $b): int => $a['value'] <=> $b['value']); $this->assertEquals([ [ 'class' => TestShareSourceType1::class, @@ -3195,7 +3228,7 @@ public function testGetShareUniqueDisplayNames(): void { 'svg' => '', ], ], - ], $share['sources']); + ], $formatted['sources']); $this->assertEquals([ [ 'class' => TestShareRecipientType1::class, @@ -3260,7 +3293,7 @@ public function testGetShareUniqueDisplayNames(): void { ], ], ], - ], $share['recipients']); + ], $formatted['recipients']); } public function testGetShareDisabledOwner(): void { @@ -3268,13 +3301,13 @@ public function testGetShareDisabledOwner(): void { $before = $this->manager->getTime(); $this->dbConnection->beginTransaction(); - $id = $this->manager->createShare($accessContext); - $this->manager->addShareSource($accessContext, $id, new ShareSource(TestShareSourceType1::class, 'source1')); - $this->manager->addShareRecipient($accessContext, $id, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); - $this->manager->addShareRecipient($accessContext, $id, new ShareRecipient(TestShareRecipientType2::class, 'recipient2', null)); - $this->manager->getShare($accessContext, $id); - $this->manager->updateSharePermission($accessContext, $id, new SharePermission(TestSharePermissionType1::class, true)); - $this->manager->updateShareState($accessContext, $id, ShareState::Active); + $share = $this->manager->createShare($accessContext); + $share = $this->manager->addShareSource($accessContext, $share, new ShareSource(TestShareSourceType1::class, 'source1')); + $share = $this->manager->addShareRecipient($accessContext, $share, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); + $share = $this->manager->addShareRecipient($accessContext, $share, new ShareRecipient(TestShareRecipientType2::class, 'recipient2', null)); + + $share = $this->manager->updateSharePermission($accessContext, $share, new SharePermission(TestSharePermissionType1::class, true)); + $share = $this->manager->updateShareState($accessContext, $share, ShareState::Active); $this->dbConnection->commit(); $after = $this->manager->getTime(); @@ -3282,14 +3315,14 @@ public function testGetShareDisabledOwner(): void { $this->owner->setEnabled(false); try { - $this->getShare(new ShareAccessContext(currentUser: $this->user1), $id); + $this->getShare(new ShareAccessContext(currentUser: $this->user1), $share->id); $this->fail('Share still visible.'); } catch (HintException $hintException) { $this->assertEquals('Share not found.', $hintException->getHint()); } - $share = $this->getShare(new ShareAccessContext(overrideChecks: true), $id); - $this->assertDateBetween($before, $after, $this->parseTime($share['last_updated'])); + $formatted = $this->getShare(new ShareAccessContext(overrideChecks: true), $share->id); + $this->assertDateBetween($before, $after, $this->parseTime($formatted['last_updated'])); $this->assertEquals([ 'user_id' => 'owner', 'instance' => null, @@ -3298,7 +3331,7 @@ public function testGetShareDisabledOwner(): void { 'light' => 'http://localhost/index.php/avatar/owner/64', 'dark' => 'http://localhost/index.php/avatar/owner/64/dark', ], - ], $share['owner']); + ], $formatted['owner']); } public function testGetShareDisabledInitiator(): void { @@ -3306,12 +3339,12 @@ public function testGetShareDisabledInitiator(): void { $before = $this->manager->getTime(); $this->dbConnection->beginTransaction(); - $id = $this->manager->createShare($accessContext); - $this->manager->addShareSource($accessContext, $id, new ShareSource(TestShareSourceType1::class, 'source1')); - $this->manager->addShareRecipient($accessContext, $id, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); - $this->manager->updateSharePermission($accessContext, $id, new SharePermission(ReshareSharePermissionType::class, true)); - $this->manager->updateShareState($accessContext, $id, ShareState::Active); - $this->manager->addShareRecipient(new ShareAccessContext(currentUser: $this->user1), $id, new ShareRecipient(TestShareRecipientType2::class, 'recipient2', null)); + $share = $this->manager->createShare($accessContext); + $share = $this->manager->addShareSource($accessContext, $share, new ShareSource(TestShareSourceType1::class, 'source1')); + $share = $this->manager->addShareRecipient($accessContext, $share, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); + $share = $this->manager->updateSharePermission($accessContext, $share, new SharePermission(ReshareSharePermissionType::class, true)); + $share = $this->manager->updateShareState($accessContext, $share, ShareState::Active); + $share = $this->manager->addShareRecipient(new ShareAccessContext(currentUser: $this->user1), $share, new ShareRecipient(TestShareRecipientType2::class, 'recipient2', null)); $this->dbConnection->commit(); $after = $this->manager->getTime(); @@ -3319,14 +3352,14 @@ public function testGetShareDisabledInitiator(): void { $this->user1->setEnabled(false); try { - $this->getShare(new ShareAccessContext(currentUser: $this->user2), $id); + $this->getShare(new ShareAccessContext(currentUser: $this->user2), $share->id); $this->fail('Share still visible.'); } catch (HintException $hintException) { $this->assertEquals('Share not found.', $hintException->getHint()); } - $share = $this->getShare($accessContext, $id); - $this->assertDateBetween($before, $after, $this->parseTime($share['last_updated'])); + $formatted = $this->getShare($accessContext, $share->id); + $this->assertDateBetween($before, $after, $this->parseTime($formatted['last_updated'])); $this->assertEquals([ [ 'class' => TestShareRecipientType1::class, @@ -3370,7 +3403,7 @@ public function testGetShareDisabledInitiator(): void { ], ], ], - ], $share['recipients']); + ], $formatted['recipients']); } public function testGetShares(): void { @@ -3378,34 +3411,32 @@ public function testGetShares(): void { $before1 = $this->manager->getTime(); $this->dbConnection->beginTransaction(); - $id1 = $this->manager->createShare($accessContext); - $this->manager->addShareSource($accessContext, $id1, new ShareSource(TestShareSourceType1::class, 'source1')); - $this->manager->addShareRecipient($accessContext, $id1, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); - $this->manager->getShare($accessContext, $id1); + $share1 = $this->manager->createShare($accessContext); + $share1 = $this->manager->addShareSource($accessContext, $share1, new ShareSource(TestShareSourceType1::class, 'source1')); + $share1 = $this->manager->addShareRecipient($accessContext, $share1, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); $this->dbConnection->commit(); $after1 = $this->manager->getTime(); $before2 = $this->manager->getTime(); $this->dbConnection->beginTransaction(); - $id2 = $this->manager->createShare($accessContext); - $this->manager->addShareSource($accessContext, $id2, new ShareSource(TestShareSourceType2::class, 'source2')); - $this->manager->addShareRecipient($accessContext, $id2, new ShareRecipient(TestShareRecipientType2::class, 'recipient2', null)); - $this->manager->getShare($accessContext, $id2); + $share2 = $this->manager->createShare($accessContext); + $share2 = $this->manager->addShareSource($accessContext, $share2, new ShareSource(TestShareSourceType2::class, 'source2')); + $share2 = $this->manager->addShareRecipient($accessContext, $share2, new ShareRecipient(TestShareRecipientType2::class, 'recipient2', null)); $this->dbConnection->commit(); $after2 = $this->manager->getTime(); - $shares = $this->getShares($accessContext, null, null, null, null); - $this->assertCount(2, $shares); - $this->assertIsArray($shares[0]); - $this->assertDateBetween($before1, $after1, $this->parseTime($shares[0]['last_updated'])); - $this->assertIsArray($shares[1]); - $this->assertDateBetween($before2, $after2, $this->parseTime($shares[1]['last_updated'])); - unset($shares[0]['last_updated'], $shares[1]['last_updated']); + $formatted = $this->getShares($accessContext, null, null, null, null); + $this->assertCount(2, $formatted); + $this->assertIsArray($formatted[0]); + $this->assertDateBetween($before1, $after1, $this->parseTime($formatted[0]['last_updated'])); + $this->assertIsArray($formatted[1]); + $this->assertDateBetween($before2, $after2, $this->parseTime($formatted[1]['last_updated'])); + unset($formatted[0]['last_updated'], $formatted[1]['last_updated']); $this->assertEquals([ [ - 'id' => $id1, + 'id' => $share1->id, 'owner' => [ 'user_id' => 'owner', 'instance' => null, @@ -3485,7 +3516,7 @@ public function testGetShares(): void { 'permission_preset' => null, ], [ - 'id' => $id2, + 'id' => $share2->id, 'owner' => [ 'user_id' => 'owner', 'instance' => null, @@ -3564,16 +3595,16 @@ public function testGetShares(): void { ], 'permission_preset' => null, ], - ], $shares); + ], $formatted); - $shares = $this->getShares($accessContext, TestShareSourceType1::class, null, null, null); - $this->assertCount(1, $shares); - $this->assertIsArray($shares[0]); - $this->assertDateBetween($before1, $after1, $this->parseTime($shares[0]['last_updated'])); - unset($shares[0]['last_updated']); + $formatted = $this->getShares($accessContext, TestShareSourceType1::class, null, null, null); + $this->assertCount(1, $formatted); + $this->assertIsArray($formatted[0]); + $this->assertDateBetween($before1, $after1, $this->parseTime($formatted[0]['last_updated'])); + unset($formatted[0]['last_updated']); $this->assertEquals([ [ - 'id' => $id1, + 'id' => $share1->id, 'owner' => [ 'user_id' => 'owner', 'instance' => null, @@ -3652,16 +3683,16 @@ public function testGetShares(): void { ], 'permission_preset' => null, ], - ], $shares); + ], $formatted); - $shares = $this->getShares($accessContext, TestShareSourceType1::class, 'source1', null, null); - $this->assertCount(1, $shares); - $this->assertIsArray($shares[0]); - $this->assertDateBetween($before1, $after1, $this->parseTime($shares[0]['last_updated'])); - unset($shares[0]['last_updated']); + $formatted = $this->getShares($accessContext, TestShareSourceType1::class, 'source1', null, null); + $this->assertCount(1, $formatted); + $this->assertIsArray($formatted[0]); + $this->assertDateBetween($before1, $after1, $this->parseTime($formatted[0]['last_updated'])); + unset($formatted[0]['last_updated']); $this->assertEquals([ [ - 'id' => $id1, + 'id' => $share1->id, 'owner' => [ 'user_id' => 'owner', 'instance' => null, @@ -3740,19 +3771,19 @@ public function testGetShares(): void { ], 'permission_preset' => null, ], - ], $shares); + ], $formatted); - $shares = $this->getShares($accessContext, TestShareSourceType1::class, 'non-existent', null, null); - $this->assertCount(0, $shares); + $formatted = $this->getShares($accessContext, TestShareSourceType1::class, 'non-existent', null, null); + $this->assertCount(0, $formatted); - $shares = $this->getShares($accessContext, null, null, $id1, null); - $this->assertCount(1, $shares); - $this->assertIsArray($shares[0]); - $this->assertDateBetween($before2, $after2, $this->parseTime($shares[0]['last_updated'])); - unset($shares[0]['last_updated']); + $formatted = $this->getShares($accessContext, null, null, $share1->id, null); + $this->assertCount(1, $formatted); + $this->assertIsArray($formatted[0]); + $this->assertDateBetween($before2, $after2, $this->parseTime($formatted[0]['last_updated'])); + unset($formatted[0]['last_updated']); $this->assertEquals([ [ - 'id' => $id2, + 'id' => $share2->id, 'owner' => [ 'user_id' => 'owner', 'instance' => null, @@ -3831,16 +3862,16 @@ public function testGetShares(): void { ], 'permission_preset' => null, ], - ], $shares); + ], $formatted); - $shares = $this->getShares($accessContext, null, null, null, 1); - $this->assertCount(1, $shares); - $this->assertIsArray($shares[0]); - $this->assertDateBetween($before1, $after1, $this->parseTime($shares[0]['last_updated'])); - unset($shares[0]['last_updated']); + $formatted = $this->getShares($accessContext, null, null, null, 1); + $this->assertCount(1, $formatted); + $this->assertIsArray($formatted[0]); + $this->assertDateBetween($before1, $after1, $this->parseTime($formatted[0]['last_updated'])); + unset($formatted[0]['last_updated']); $this->assertEquals([ [ - 'id' => $id1, + 'id' => $share1->id, 'owner' => [ 'user_id' => 'owner', 'instance' => null, @@ -3919,15 +3950,15 @@ public function testGetShares(): void { ], 'permission_preset' => null, ], - ], $shares); + ], $formatted); } public function testGetSharesSorted(): void { $accessContext = new ShareAccessContext(currentUser: $this->owner); $this->dbConnection->beginTransaction(); - $id1 = $this->manager->createShare($accessContext); - $id2 = $this->manager->createShare($accessContext); + $share1 = $this->manager->createShare($accessContext); + $share2 = $this->manager->createShare($accessContext); $this->dbConnection->commit(); $shares = $this->getShares($accessContext, null, null, null, null); @@ -3935,35 +3966,35 @@ public function testGetSharesSorted(): void { $this->assertArrayHasKey('id', $shares[0]); $this->assertIsArray($shares[1]); $this->assertArrayHasKey('id', $shares[1]); - $this->assertEquals($id1, $shares[0]['id']); - $this->assertEquals($id2, $shares[1]['id']); + $this->assertEquals($share1->id, $shares[0]['id']); + $this->assertEquals($share2->id, $shares[1]['id']); $this->dbConnection->beginTransaction(); - $this->manager->addShareSource($accessContext, $id2, new ShareSource(TestShareSourceType2::class, 'source2')); - $this->manager->getShare($accessContext, $id2); - $this->manager->updateSharePermission($accessContext, $id2, new SharePermission(TestSharePermissionType2::class, true)); + $this->manager->addShareSource($accessContext, $share2, new ShareSource(TestShareSourceType2::class, 'source2')); + $this->manager->getShare($accessContext, $share2->id); + $this->manager->updateSharePermission($accessContext, $share2, new SharePermission(TestSharePermissionType2::class, true)); $this->dbConnection->commit(); - $shares = $this->getShares($accessContext, null, null, null, null); - $this->assertIsArray($shares[0]); - $this->assertArrayHasKey('id', $shares[0]); - $this->assertIsArray($shares[1]); - $this->assertArrayHasKey('id', $shares[1]); - $this->assertEquals($id2, $shares[0]['id']); - $this->assertEquals($id1, $shares[1]['id']); + $formatted = $this->getShares($accessContext, null, null, null, null); + $this->assertIsArray($formatted[0]); + $this->assertArrayHasKey('id', $formatted[0]); + $this->assertIsArray($formatted[1]); + $this->assertArrayHasKey('id', $formatted[1]); + $this->assertEquals($share2->id, $formatted[0]['id']); + $this->assertEquals($share1->id, $formatted[1]['id']); } public function testOwnerDeleted(): void { $accessContext = new ShareAccessContext(currentUser: $this->owner); $this->dbConnection->beginTransaction(); - $id = $this->manager->createShare($accessContext); + $share = $this->manager->createShare($accessContext); $this->owner->delete(); $this->dbConnection->commit(); try { - $this->getShare(new ShareAccessContext(overrideChecks: true), $id); + $this->getShare(new ShareAccessContext(overrideChecks: true), $share->id); $this->fail('Share still exists.'); } catch (HintException $hintException) { $this->assertEquals('Share not found.', $hintException->getHint()); @@ -3974,20 +4005,20 @@ public function testInitiatorDeleted(): void { $accessContext = new ShareAccessContext($this->owner); $this->dbConnection->beginTransaction(); - $id = $this->manager->createShare($accessContext); - $this->manager->addShareSource($accessContext, $id, new ShareSource(TestShareSourceType1::class, 'source1')); - $this->manager->addShareRecipient($accessContext, $id, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); - $this->manager->updateSharePermission($accessContext, $id, new SharePermission(ReshareSharePermissionType::class, true)); - $this->manager->updateShareState($accessContext, $id, ShareState::Active); - $this->manager->addShareRecipient(new ShareAccessContext(currentUser: $this->user1), $id, new ShareRecipient(TestShareRecipientType2::class, 'recipient2', null)); + $share = $this->manager->createShare($accessContext); + $share = $this->manager->addShareSource($accessContext, $share, new ShareSource(TestShareSourceType1::class, 'source1')); + $share = $this->manager->addShareRecipient($accessContext, $share, new ShareRecipient(TestShareRecipientType1::class, 'recipient1', null)); + $share = $this->manager->updateSharePermission($accessContext, $share, new SharePermission(ReshareSharePermissionType::class, true)); + $share = $this->manager->updateShareState($accessContext, $share, ShareState::Active); + $share = $this->manager->addShareRecipient(new ShareAccessContext(currentUser: $this->user1), $share, new ShareRecipient(TestShareRecipientType2::class, 'recipient2', null)); $before = $this->manager->getTime(); $this->user1->delete(); $after = $this->manager->getTime(); $this->dbConnection->commit(); - $share = $this->getShare(new ShareAccessContext(overrideChecks: true), $id); - $this->assertDateBetween($before, $after, $this->parseTime($share['last_updated'])); + $formatted = $this->getShare(new ShareAccessContext(overrideChecks: true), $share->id); + $this->assertDateBetween($before, $after, $this->parseTime($formatted['last_updated'])); $this->assertEquals([ [ 'class' => TestShareRecipientType1::class, @@ -4031,6 +4062,6 @@ public function testInitiatorDeleted(): void { ], ], ], - ], $share['recipients']); + ], $formatted['recipients']); } } diff --git a/tests/lib/Sharing/SharingManagerTest.php b/tests/lib/Sharing/SharingManagerTest.php index 47db8ee2ec550..557112b181b66 100644 --- a/tests/lib/Sharing/SharingManagerTest.php +++ b/tests/lib/Sharing/SharingManagerTest.php @@ -17,6 +17,7 @@ use NCU\Sharing\ShareAccessContext; use NCU\Sharing\ShareState; use NCU\Sharing\Source\ShareSource; +use OC\Sharing\SharingManager; use OCP\IURLGenerator; use OCP\IUserManager; use OCP\L10N\IFactory; @@ -25,15 +26,47 @@ #[Group(name: 'DB')] final class SharingManagerTest extends AbstractSharingManagerTests { + private function assertShareSyncedWithDb(ShareAccessContext $accessContext, Share $share): void { + $retrieved = $this->manager->getShare($accessContext, $share->id); + // don't compare time at sub-ms accuracy + $this->assertEquals(SharingManager::timeToMs($retrieved->lastUpdated), SharingManager::timeToMs($share->lastUpdated)); + + // now we compared the lastUpdated, make them the same to not fail the full comparison when there is a sub-ms lastUpdate difference + $retrieved = new Share( + $retrieved->id, + $retrieved->owner, + $share->lastUpdated, + $retrieved->state, + $retrieved->sources, + $retrieved->recipients, + $retrieved->properties, + $retrieved->permissions + ); + + // cache the enabled permissions for both + $retrieved->getEnabledPermissions(); + + $share->getEnabledPermissions(); + // ensure source metadata is loaded + foreach ($share->sources as $source) { + $source->format($this->registry, $this->l10nFactory, false); + } + + $this->assertEquals($retrieved, $share, 'share object not in sync with database'); + } #[\Override] - protected function searchRecipients(ShareAccessContext $accessContext, ?array $filterRecipientTypeClasses, string $query, int $limit, int $offset, ?string $id = null): array { + protected function searchRecipients(ShareAccessContext $accessContext, ?array $filterRecipientTypeClasses, string $query, int $limit, int $offset, ?Share $forShare = null): array { try { $this->dbConnection->beginTransaction(); + if ($forShare instanceof Share) { + $this->assertShareSyncedWithDb($accessContext, $forShare); + } + /** @psalm-suppress ArgumentTypeCoercion */ - $shares = ShareRecipient::formatMultiple($this->registry, Server::get(IFactory::class), Server::get(IURLGenerator::class), Server::get(IUserManager::class), $this->manager->searchRecipients($accessContext, $filterRecipientTypeClasses, $query, $limit, $offset, $id)); + $recipients = ShareRecipient::formatMultiple($this->registry, Server::get(IFactory::class), Server::get(IURLGenerator::class), Server::get(IUserManager::class), $this->manager->searchRecipients($accessContext, $filterRecipientTypeClasses, $query, $limit, $offset, $forShare)); $this->dbConnection->commit(); - return $shares; + return $recipients; } catch (Exception $exception) { $this->dbConnection->rollBack(); throw $exception; @@ -44,8 +77,9 @@ protected function searchRecipients(ShareAccessContext $accessContext, ?array $f protected function createShare(ShareAccessContext $accessContext): array { try { $this->dbConnection->beginTransaction(); - $id = $this->manager->createShare($accessContext); - $share = $this->manager->getShare($accessContext, $id)->format($this->registry, Server::get(IFactory::class), Server::get(IURLGenerator::class), Server::get(IUserManager::class)); + $share = $this->manager->createShare($accessContext); + $this->assertShareSyncedWithDb($accessContext, $share); + $share = $share->format($this->registry, Server::get(IFactory::class), Server::get(IURLGenerator::class), Server::get(IUserManager::class)); $this->dbConnection->commit(); return $share; } catch (Exception $exception) { @@ -56,11 +90,12 @@ protected function createShare(ShareAccessContext $accessContext): array { #[ \Override] - protected function updateShareState(ShareAccessContext $accessContext, string $id, ShareState $state): array { + protected function updateShareState(ShareAccessContext $accessContext, Share $share, ShareState $state): array { try { $this->dbConnection->beginTransaction(); - $this->manager->updateShareState($accessContext, $id, $state); - $share = $this->manager->getShare($accessContext, $id)->format($this->registry, Server::get(IFactory::class), Server::get(IURLGenerator::class), Server::get(IUserManager::class)); + $share = $this->manager->updateShareState($accessContext, $share, $state); + $this->assertShareSyncedWithDb($accessContext, $share); + $share = $share->format($this->registry, Server::get(IFactory::class), Server::get(IURLGenerator::class), Server::get(IUserManager::class)); $this->dbConnection->commit(); return $share; } catch (Exception $exception) { @@ -70,11 +105,12 @@ protected function updateShareState(ShareAccessContext $accessContext, string $i } #[\Override] - protected function addShareSource(ShareAccessContext $accessContext, string $id, ShareSource $source): array { + protected function addShareSource(ShareAccessContext $accessContext, Share $share, ShareSource $source): array { try { $this->dbConnection->beginTransaction(); - $this->manager->addShareSource($accessContext, $id, $source); - $share = $this->manager->getShare($accessContext, $id)->format($this->registry, Server::get(IFactory::class), Server::get(IURLGenerator::class), Server::get(IUserManager::class)); + $share = $this->manager->addShareSource($accessContext, $share, $source); + $this->assertShareSyncedWithDb($accessContext, $share); + $share = $share->format($this->registry, Server::get(IFactory::class), Server::get(IURLGenerator::class), Server::get(IUserManager::class)); $this->dbConnection->commit(); return $share; } catch (Exception $exception) { @@ -84,11 +120,13 @@ protected function addShareSource(ShareAccessContext $accessContext, string $id, } #[\Override] - protected function removeShareSource(ShareAccessContext $accessContext, string $id, ShareSource $source): array { + protected function removeShareSource(ShareAccessContext $accessContext, Share $share, ShareSource $source): array { try { $this->dbConnection->beginTransaction(); - $this->manager->removeShareSource($accessContext, $id, $source); - $share = $this->manager->getShare($accessContext, $id)->format($this->registry, Server::get(IFactory::class), Server::get(IURLGenerator::class), Server::get(IUserManager::class)); + $this->assertShareSyncedWithDb($accessContext, $share); + $share = $this->manager->removeShareSource($accessContext, $share, $source); + $this->assertShareSyncedWithDb($accessContext, $share); + $share = $share->format($this->registry, Server::get(IFactory::class), Server::get(IURLGenerator::class), Server::get(IUserManager::class)); $this->dbConnection->commit(); return $share; } catch (Exception $exception) { @@ -98,11 +136,12 @@ protected function removeShareSource(ShareAccessContext $accessContext, string $ } #[\Override] - protected function addShareRecipient(ShareAccessContext $accessContext, string $id, ShareRecipient $recipient): array { + protected function addShareRecipient(ShareAccessContext $accessContext, Share $share, ShareRecipient $recipient): array { try { $this->dbConnection->beginTransaction(); - $this->manager->addShareRecipient($accessContext, $id, $recipient); - $share = $this->manager->getShare($accessContext, $id)->format($this->registry, Server::get(IFactory::class), Server::get(IURLGenerator::class), Server::get(IUserManager::class)); + $share = $this->manager->addShareRecipient($accessContext, $share, $recipient); + $this->assertShareSyncedWithDb($accessContext, $share); + $share = $share->format($this->registry, Server::get(IFactory::class), Server::get(IURLGenerator::class), Server::get(IUserManager::class)); $this->dbConnection->commit(); return $share; } catch (Exception $exception) { @@ -112,11 +151,12 @@ protected function addShareRecipient(ShareAccessContext $accessContext, string $ } #[\Override] - protected function removeShareRecipient(ShareAccessContext $accessContext, string $id, ShareRecipient $recipient): array { + protected function removeShareRecipient(ShareAccessContext $accessContext, Share $share, ShareRecipient $recipient): array { try { $this->dbConnection->beginTransaction(); - $this->manager->removeShareRecipient($accessContext, $id, $recipient); - $share = $this->manager->getShare($accessContext, $id)->format($this->registry, Server::get(IFactory::class), Server::get(IURLGenerator::class), Server::get(IUserManager::class)); + $share = $this->manager->removeShareRecipient($accessContext, $share, $recipient); + $this->assertShareSyncedWithDb($accessContext, $share); + $share = $share->format($this->registry, Server::get(IFactory::class), Server::get(IURLGenerator::class), Server::get(IUserManager::class)); $this->dbConnection->commit(); return $share; } catch (Exception $exception) { @@ -126,11 +166,12 @@ protected function removeShareRecipient(ShareAccessContext $accessContext, strin } #[\Override] - protected function updateShareRecipientSecret(ShareAccessContext $accessContext, string $id, ShareRecipient $recipient, string $secret): array { + protected function updateShareRecipientSecret(ShareAccessContext $accessContext, Share $share, ShareRecipient $recipient, string $secret): array { try { $this->dbConnection->beginTransaction(); - $this->manager->updateShareRecipientSecret($accessContext, $id, $recipient, $secret); - $share = $this->manager->getShare($accessContext, $id)->format($this->registry, Server::get(IFactory::class), Server::get(IURLGenerator::class), Server::get(IUserManager::class)); + $share = $this->manager->updateShareRecipientSecret($accessContext, $share, $recipient, $secret); + $this->assertShareSyncedWithDb($accessContext, $share); + $share = $share->format($this->registry, Server::get(IFactory::class), Server::get(IURLGenerator::class), Server::get(IUserManager::class)); $this->dbConnection->commit(); return $share; } catch (Exception $exception) { @@ -140,11 +181,12 @@ protected function updateShareRecipientSecret(ShareAccessContext $accessContext, } #[\Override] - protected function updateShareProperty(ShareAccessContext $accessContext, string $id, ShareProperty $property): array { + protected function updateShareProperty(ShareAccessContext $accessContext, Share $share, ShareProperty $property): array { try { $this->dbConnection->beginTransaction(); - $this->manager->updateShareProperty($accessContext, $id, $property); - $share = $this->manager->getShare($accessContext, $id)->format($this->registry, Server::get(IFactory::class), Server::get(IURLGenerator::class), Server::get(IUserManager::class)); + $share = $this->manager->updateShareProperty($accessContext, $share, $property); + $this->assertShareSyncedWithDb($accessContext, $share); + $share = $share->format($this->registry, Server::get(IFactory::class), Server::get(IURLGenerator::class), Server::get(IUserManager::class)); $this->dbConnection->commit(); return $share; } catch (Exception $exception) { @@ -154,11 +196,12 @@ protected function updateShareProperty(ShareAccessContext $accessContext, string } #[\Override] - protected function updateSharePermission(ShareAccessContext $accessContext, string $id, SharePermission $permission): array { + protected function updateSharePermission(ShareAccessContext $accessContext, Share $share, SharePermission $permission): array { try { $this->dbConnection->beginTransaction(); - $this->manager->updateSharePermission($accessContext, $id, $permission); - $share = $this->manager->getShare($accessContext, $id)->format($this->registry, Server::get(IFactory::class), Server::get(IURLGenerator::class), Server::get(IUserManager::class)); + $share = $this->manager->updateSharePermission($accessContext, $share, $permission); + $this->assertShareSyncedWithDb($accessContext, $share); + $share = $share->format($this->registry, Server::get(IFactory::class), Server::get(IURLGenerator::class), Server::get(IUserManager::class)); $this->dbConnection->commit(); return $share; } catch (Exception $exception) { @@ -168,12 +211,13 @@ protected function updateSharePermission(ShareAccessContext $accessContext, stri } #[\Override] - protected function selectSharePermissionPreset(ShareAccessContext $accessContext, string $id, string $permissionPresetClass): array { + protected function selectSharePermissionPreset(ShareAccessContext $accessContext, Share $share, string $permissionPresetClass): array { try { $this->dbConnection->beginTransaction(); /** @psalm-suppress ArgumentTypeCoercion */ - $this->manager->selectSharePermissionPreset($accessContext, $id, $permissionPresetClass); - $share = $this->manager->getShare($accessContext, $id)->format($this->registry, Server::get(IFactory::class), Server::get(IURLGenerator::class), Server::get(IUserManager::class)); + $share = $this->manager->selectSharePermissionPreset($accessContext, $share, $permissionPresetClass); + $this->assertShareSyncedWithDb($accessContext, $share); + $share = $share->format($this->registry, Server::get(IFactory::class), Server::get(IURLGenerator::class), Server::get(IUserManager::class)); $this->dbConnection->commit(); return $share; } catch (Exception $exception) { @@ -183,10 +227,11 @@ protected function selectSharePermissionPreset(ShareAccessContext $accessContext } #[\Override] - protected function deleteShare(ShareAccessContext $accessContext, string $id): void { + protected function deleteShare(ShareAccessContext $accessContext, Share $share): void { try { $this->dbConnection->beginTransaction(); - $this->manager->deleteShare($accessContext, $id); + $this->assertShareSyncedWithDb($accessContext, $share); + $this->manager->deleteShare($accessContext, $share); $this->dbConnection->commit(); } catch (Exception $exception) { $this->dbConnection->rollBack();