diff --git a/lib/private/Sharing/SharingBackend.php b/lib/private/Sharing/SharingBackend.php index 17d4122975827..3b7942444e6e3 100644 --- a/lib/private/Sharing/SharingBackend.php +++ b/lib/private/Sharing/SharingBackend.php @@ -1259,6 +1259,10 @@ public function ensureDefaults(array $shares): array { $defaultSet = false; foreach ($shares as &$share) { + if ($share->owner->instance !== null) { + continue; + } + $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); @@ -1272,6 +1276,10 @@ public function ensureDefaults(array $shares): array { } foreach ($shares as &$share) { + if ($share->owner->instance !== null) { + continue; + } + $shareCompatiblePermissionTypeClasses = $this->getShareCompatiblePermissionTypeClasses($share->sources); foreach ($shareCompatiblePermissionTypeClasses as $permissionTypeClass) { diff --git a/lib/private/Sharing/SharingManager.php b/lib/private/Sharing/SharingManager.php index a6d36ca28e782..9ba172b7d3fe2 100644 --- a/lib/private/Sharing/SharingManager.php +++ b/lib/private/Sharing/SharingManager.php @@ -197,6 +197,8 @@ public function onOwnerDeleted(ShareAccessContext $accessContext, ShareUser $own #[\Override] public function updateShareState(ShareAccessContext $accessContext, Share $share, ShareState $state): Share { + $this->assertLocalShare($share); + $time = $this->getTime(); $this->backend->setLastUpdated([$share->id], $time); @@ -232,6 +234,8 @@ public function updateShareState(ShareAccessContext $accessContext, Share $share #[\Override] public function updateShareUserStatus(ShareAccessContext $accessContext, Share $share, ShareUserStatus $userStatus): Share { + $this->assertLocalShare($share); + if (!($currentUser = $accessContext->currentUser) instanceof IUser) { throw new RuntimeException('No user present to update share status for.'); } @@ -269,9 +273,7 @@ public function updateShareUserStatus(ShareAccessContext $accessContext, Share $ #[\Override] public function addShareSource(ShareAccessContext $accessContext, Share $share, ShareSource $source): Share { - if ($share->owner->instance !== null) { - throw new ShareOperationForbiddenException(); - } + $this->assertLocalShare($share); // only the owner can add sources, otherwise a user could add sources others don't have access to, which would remove their access $this->validateShareEditPermissions($accessContext, $share, true); @@ -328,6 +330,8 @@ public function addShareSource(ShareAccessContext $accessContext, Share $share, #[\Override] public function removeShareSource(ShareAccessContext $accessContext, Share $share, ShareSource $source): Share { + $this->assertLocalShare($share); + // only the owner can remove sources, to mirror the "add source" permissions $this->validateShareEditPermissions($accessContext, $share, true); @@ -389,6 +393,8 @@ public function onSourceDeleted(ShareAccessContext $accessContext, ShareSource $ #[\Override] public function addShareRecipient(ShareAccessContext $accessContext, Share $share, ShareRecipient $recipient): Share { + $this->assertLocalShare($share); + if (!($currentUser = $accessContext->currentUser) instanceof IUser) { throw new RuntimeException('No current user provided in access context.'); } @@ -477,6 +483,8 @@ public function addShareRecipient(ShareAccessContext $accessContext, Share $shar #[\Override] public function removeShareRecipient(ShareAccessContext $accessContext, Share $share, ShareRecipient $recipient): Share { + $this->assertLocalShare($share); + try { $this->validateShareEditPermissions($accessContext, $share); } catch (ShareOperationForbiddenException) { @@ -566,6 +574,8 @@ private function validateShareSecret(string $secret): bool { #[\Override] public function updateShareRecipientSecret(ShareAccessContext $accessContext, Share $share, ShareRecipient $recipient, string $secret): Share { + $this->assertLocalShare($share); + try { $this->validateShareEditPermissions($accessContext, $share); } catch (ShareOperationForbiddenException) { @@ -629,6 +639,8 @@ public function updateShareRecipientSecret(ShareAccessContext $accessContext, Sh #[\Override] public function updateShareProperty(ShareAccessContext $accessContext, Share $share, ShareProperty $property): Share { + $this->assertLocalShare($share); + $this->validateShareEditPermissions($accessContext, $share); if (($propertyType = $this->registry->getPropertyTypes()[$property->class] ?? null) === null) { @@ -679,6 +691,8 @@ public function updateShareProperty(ShareAccessContext $accessContext, Share $sh #[\Override] public function updateSharePermission(ShareAccessContext $accessContext, Share $share, SharePermission $permission): Share { + $this->assertLocalShare($share); + $this->validateShareEditPermissions($accessContext, $share); if (!isset($this->registry->getPermissionTypes()[$permission->class])) { @@ -722,6 +736,8 @@ public function updateSharePermission(ShareAccessContext $accessContext, Share $ #[\Override] public function updateShareRecipientPermission(ShareAccessContext $accessContext, Share $share, ShareRecipient $recipient, SharePermission $permission): Share { + $this->assertLocalShare($share); + $time = $this->getTime(); $this->backend->setLastUpdated([$share->id], $time); @@ -786,6 +802,8 @@ public function updateShareRecipientPermission(ShareAccessContext $accessContext #[\Override] public function selectSharePermissionPreset(ShareAccessContext $accessContext, Share $share, string $permissionPresetClass): Share { + $this->assertLocalShare($share); + $this->validateShareEditPermissions($accessContext, $share); if (($this->registry->getPermissionPresetCompatiblePermissionTypeClasses()[$permissionPresetClass] ?? null) === null) { @@ -829,6 +847,8 @@ public function selectSharePermissionPreset(ShareAccessContext $accessContext, S #[\Override] public function deleteShare(ShareAccessContext $accessContext, Share $share): void { + // Deleting a remote share is allowed. + // No need to update the last updated timestamp, because the share will be deleted anyway. $this->validateShareEditPermissions($accessContext, $share); @@ -1088,4 +1108,10 @@ public static function timeToMs(\DateTimeImmutable $time): string { throw new \RuntimeException('invalid date-time'); } + + private function assertLocalShare(Share $share): void { + if ($share->owner->instance !== null) { + throw new RuntimeException('The SharingManager can only modify local shares.'); + } + } } diff --git a/tests/lib/Sharing/AbstractSharingManagerTests.php b/tests/lib/Sharing/AbstractSharingManagerTests.php index df4ec3fe5cd35..0caf525d9ed7e 100644 --- a/tests/lib/Sharing/AbstractSharingManagerTests.php +++ b/tests/lib/Sharing/AbstractSharingManagerTests.php @@ -767,17 +767,7 @@ public function testCreateShareRemoteOwner(): void { 'sources' => [], 'recipients' => [], 'properties' => [], - 'permissions' => [ - [ - 'class' => ReshareSharePermissionType::class, - 'source_class' => null, - 'display_name' => 'Share with others', - 'hint' => null, - 'presets' => [], - 'enabled' => false, - 'priority' => 90, - ], - ], + 'permissions' => [], 'permission_preset' => null, ], $share); }