From 7b772a2de81f3a93e900975b6d4654eb7c1f9852 Mon Sep 17 00:00:00 2001 From: Sebastien Marinier Date: Thu, 5 Nov 2026 19:06:26 +0100 Subject: [PATCH] fix: #8681 card attachments are not accessible to the new owner after occ deck:transfer-ownership (send UserShareAccessUpdatedEvent event to the source and target users) Assisted-by: ClaudeCode:Opus 5.5 Signed-off-by: Sebastien Marinier --- lib/Service/BoardService.php | 16 ++++++++++++++++ tests/unit/Service/BoardServiceTest.php | 24 ++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/lib/Service/BoardService.php b/lib/Service/BoardService.php index cb38c8d4b..6f3b5e74f 100644 --- a/lib/Service/BoardService.php +++ b/lib/Service/BoardService.php @@ -742,6 +742,7 @@ public function transferBoardOwnership(int $boardId, string $newOwner, bool $cha $this->cardMapper->remapCardOwner($boardId, $previousOwner, $newOwner); } $this->connection->commit(); + $this->dispatchUserShareAccessUpdated([$newOwner, $previousOwner]); $this->eventDispatcher->dispatchTyped(new CriticalActionPerformedEvent( 'Ownership of board %s was transferred from "%s" to "%s"', [ @@ -769,6 +770,21 @@ public function transferOwnership(string $owner, string $newOwner, bool $changeC } } + /** + * Notify files_sharing that the Deck attachments the given users can access have changed + * (otherwise they are mounted under the raw {DECK_PLACEHOLDER} target) + * + * @param list $userIds + */ + private function dispatchUserShareAccessUpdated(array $userIds): void { + if (!class_exists(UserShareAccessUpdatedEvent::class)) { + return; + } + foreach (array_unique($userIds) as $userId) { + $this->eventDispatcher->dispatchTyped(new UserShareAccessUpdatedEvent(new LazyUser($userId, $this->userManager))); + } + } + /** * @throws DoesNotExistException * @throws NoPermissionException diff --git a/tests/unit/Service/BoardServiceTest.php b/tests/unit/Service/BoardServiceTest.php index 7e52be831..1b5a88b6c 100644 --- a/tests/unit/Service/BoardServiceTest.php +++ b/tests/unit/Service/BoardServiceTest.php @@ -56,6 +56,7 @@ use OCA\Deck\NoPermissionException; use OCA\Deck\Notification\NotificationHelper; use OCA\Deck\Validators\BoardServiceValidator; +use OCA\Files_Sharing\Event\UserShareAccessUpdatedEvent; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventDispatcher; use OCP\IConfig; @@ -777,4 +778,27 @@ public function testTransferBoardOwnershipLogsCriticalAction(): void { $this->assertSame('Ownership of board %s was transferred from "%s" to "%s"', $auditEvents[0]->getLogMessage()); $this->assertSame(['boardId' => 7, 'previousOwner' => 'admin', 'newOwner' => 'newowner', 'changeContent' => true], $auditEvents[0]->getParameters()); } + + public function testTransferBoardOwnershipUpdatesShareAccessOfBothOwners(): void { + if (!class_exists(UserShareAccessUpdatedEvent::class)) { + $this->markTestSkipped('files_sharing is not available'); + } + $board = new Board(); + $board->setId(7); + $board->setOwner('admin'); + $this->boardMapper->method('find')->willReturn($board); + $updatedUsers = []; + $this->eventDispatcher->method('dispatchTyped') + ->willReturnCallback(function (Event $event) use (&$updatedUsers): void { + if ($event instanceof UserShareAccessUpdatedEvent) { + foreach ($event->getUsers() as $user) { + $updatedUsers[] = $user->getUID(); + } + } + }); + + $this->service->transferBoardOwnership(7, 'newowner', true); + + $this->assertSame(['newowner', 'admin'], $updatedUsers); + } }