diff --git a/lib/Service/FilesAppService.php b/lib/Service/FilesAppService.php index 75788ecf1c..d6824c51b6 100644 --- a/lib/Service/FilesAppService.php +++ b/lib/Service/FilesAppService.php @@ -255,10 +255,20 @@ public function createFromImport(Attachment $attachment, string $content): Attac $fileName = $attachment->getData(); $this->validateFilename($fileName); - $ownerId = $attachment->getCreatedBy() ?: $this->userId; - if (!is_string($ownerId) || $ownerId === '') { - throw new StatusException('Could not resolve owner for imported attachment'); - } + $cardId = $attachment->getCardId(); + // Use the session user or the card owner for imports without a request user. + $ownerId = $this->resolveImportStorageOwner($attachment); + $this->permissionService->checkPermission( + $this->cardMapper, + $cardId, + Acl::PERMISSION_EDIT, + $ownerId, + true, + true + ); + // Import may run without request user context. + // Set the actor explicitly so DeckShareProvider permission checks evaluate correctly. + $this->permissionService->setUserId($ownerId); $userFolder = $this->rootFolder->getUserFolder($ownerId); $attachmentFolderName = $this->configService->getAttachmentFolder($ownerId); @@ -282,7 +292,6 @@ public function createFromImport(Attachment $attachment, string $content): Attac $target->putContent($content); } - $cardId = $attachment->getCardId(); foreach ($this->shareProvider->getSharesByPath($target) as $share) { if ((int)$share->getSharedWith() === $cardId) { $attachment->setId((int)$share->getId()); @@ -291,18 +300,6 @@ public function createFromImport(Attachment $attachment, string $content): Attac } } - $this->permissionService->checkPermission( - $this->cardMapper, - $cardId, - Acl::PERMISSION_EDIT, - $ownerId, - true, - true - ); - // Import usually runs in background jobs without request user context. - // Set the actor explicitly so DeckShareProvider permission checks evaluate correctly. - $this->permissionService->setUserId($ownerId); - $share = $this->shareManager->newShare(); $share->setNode($target); $share->setShareType(IShare::TYPE_DECK); @@ -331,6 +328,28 @@ public function createFromImport(Attachment $attachment, string $content): Attac return $attachment; } + /** + * Resolve which user Files storage may receive an imported attachment. + * + * @throws StatusException + */ + private function resolveImportStorageOwner(Attachment $attachment): string { + if (is_string($this->userId) && $this->userId !== '') { + return $this->userId; + } + + try { + $ownerId = $this->cardMapper->find($attachment->getCardId())->getOwner(); + } catch (\Throwable) { + $ownerId = null; + } + if (!is_string($ownerId) || $ownerId === '') { + throw new StatusException('Could not resolve owner for imported attachment'); + } + + return $ownerId; + } + /** * @return array|null * @throws StatusException diff --git a/lib/Service/Importer/Systems/DeckJsonService.php b/lib/Service/Importer/Systems/DeckJsonService.php index 99dcb36bac..2aa7071d0c 100644 --- a/lib/Service/Importer/Systems/DeckJsonService.php +++ b/lib/Service/Importer/Systems/DeckJsonService.php @@ -201,11 +201,7 @@ private function importAttachmentsForCard(object $sourceCard): void { continue; } - try { - $this->getImportService()->insertAttachment($attachment, $content); - } catch (\Throwable $e) { - continue; - } + $this->getImportService()->insertAttachment($attachment, $content); } }