diff options
Diffstat (limited to 'apps/files_sharing/lib/Controller')
6 files changed, 93 insertions, 38 deletions
diff --git a/apps/files_sharing/lib/Controller/ExternalSharesController.php b/apps/files_sharing/lib/Controller/ExternalSharesController.php index 9d15b03c6cd..fa828a9d2c2 100644 --- a/apps/files_sharing/lib/Controller/ExternalSharesController.php +++ b/apps/files_sharing/lib/Controller/ExternalSharesController.php @@ -1,4 +1,5 @@ <?php + /** * SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. diff --git a/apps/files_sharing/lib/Controller/PublicPreviewController.php b/apps/files_sharing/lib/Controller/PublicPreviewController.php index 91dead57e80..d917f6e0ebb 100644 --- a/apps/files_sharing/lib/Controller/PublicPreviewController.php +++ b/apps/files_sharing/lib/Controller/PublicPreviewController.php @@ -1,4 +1,5 @@ <?php + /** * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later @@ -11,6 +12,7 @@ use OCP\AppFramework\Http\Attribute\OpenAPI; use OCP\AppFramework\Http\Attribute\PublicPage; use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\Http\FileDisplayResponse; +use OCP\AppFramework\Http\RedirectResponse; use OCP\AppFramework\PublicShareController; use OCP\Constants; use OCP\Files\Folder; @@ -18,6 +20,7 @@ use OCP\Files\NotFoundException; use OCP\IPreview; use OCP\IRequest; use OCP\ISession; +use OCP\Preview\IMimeIconProvider; use OCP\Share\Exceptions\ShareNotFound; use OCP\Share\IManager as ShareManager; use OCP\Share\IShare; @@ -33,6 +36,7 @@ class PublicPreviewController extends PublicShareController { private ShareManager $shareManager, ISession $session, private IPreview $previewManager, + private IMimeIconProvider $mimeIconProvider, ) { parent::__construct($appName, $request, $session); } @@ -63,9 +67,11 @@ class PublicPreviewController extends PublicShareController { * @param int $x Width of the preview * @param int $y Height of the preview * @param bool $a Whether to not crop the preview - * @return FileDisplayResponse<Http::STATUS_OK, array{Content-Type: string}>|DataResponse<Http::STATUS_BAD_REQUEST|Http::STATUS_FORBIDDEN|Http::STATUS_NOT_FOUND, list<empty>, array{}> + * @param bool $mimeFallback Whether to fallback to the mime icon if no preview is available + * @return FileDisplayResponse<Http::STATUS_OK, array{Content-Type: string}>|DataResponse<Http::STATUS_BAD_REQUEST|Http::STATUS_FORBIDDEN|Http::STATUS_NOT_FOUND, list<empty>, array{}>|RedirectResponse<Http::STATUS_SEE_OTHER, array{}> * * 200: Preview returned + * 303: Redirect to the mime icon url if mimeFallback is true * 400: Getting preview is not possible * 403: Getting preview is not allowed * 404: Share or preview not found @@ -79,6 +85,7 @@ class PublicPreviewController extends PublicShareController { int $x = 32, int $y = 32, $a = false, + bool $mimeFallback = false, ) { $cacheForSeconds = 60 * 60 * 24; // 1 day @@ -96,12 +103,12 @@ class PublicPreviewController extends PublicShareController { return new DataResponse([], Http::STATUS_FORBIDDEN); } - $attributes = $share->getAttributes(); // Only explicitly set to false will forbid the download! - $downloadForbidden = $attributes?->getAttribute('permissions', 'download') === false; + $downloadForbidden = !$share->canSeeContent(); + // Is this header is set it means our UI is doing a preview for no-download shares // we check a header so we at least prevent people from using the link directly (obfuscation) - $isPublicPreview = $this->request->getHeader('X-NC-Preview') === 'true'; + $isPublicPreview = $this->request->getHeader('x-nc-preview') === 'true'; if ($isPublicPreview && $downloadForbidden) { // Only cache for 15 minutes on public preview requests to quickly remove from cache @@ -124,6 +131,12 @@ class PublicPreviewController extends PublicShareController { $response->cacheFor($cacheForSeconds); return $response; } catch (NotFoundException $e) { + // If we have no preview enabled, we can redirect to the mime icon if any + if ($mimeFallback) { + if ($url = $this->mimeIconProvider->getMimeIconUrl($file->getMimeType())) { + return new RedirectResponse($url); + } + } return new DataResponse([], Http::STATUS_NOT_FOUND); } catch (\InvalidArgumentException $e) { return new DataResponse([], Http::STATUS_BAD_REQUEST); @@ -169,8 +182,7 @@ class PublicPreviewController extends PublicShareController { return new DataResponse([], Http::STATUS_FORBIDDEN); } - $attributes = $share->getAttributes(); - if ($attributes !== null && $attributes->getAttribute('permissions', 'download') === false) { + if (!$share->canSeeContent()) { return new DataResponse([], Http::STATUS_FORBIDDEN); } diff --git a/apps/files_sharing/lib/Controller/RemoteController.php b/apps/files_sharing/lib/Controller/RemoteController.php index e23ae51f219..8c15cd8463e 100644 --- a/apps/files_sharing/lib/Controller/RemoteController.php +++ b/apps/files_sharing/lib/Controller/RemoteController.php @@ -1,4 +1,5 @@ <?php + /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. diff --git a/apps/files_sharing/lib/Controller/ShareAPIController.php b/apps/files_sharing/lib/Controller/ShareAPIController.php index 81ead3c4978..a26663d58b3 100644 --- a/apps/files_sharing/lib/Controller/ShareAPIController.php +++ b/apps/files_sharing/lib/Controller/ShareAPIController.php @@ -94,6 +94,7 @@ class ShareAPIController extends OCSController { private LoggerInterface $logger, private IProviderFactory $factory, private IMailer $mailer, + private ITagManager $tagManager, private ?string $userId = null, ) { parent::__construct($appName, $request); @@ -472,7 +473,7 @@ class ShareAPIController extends OCSController { $share = $this->formatShare($share); if ($include_tags) { - $share = Helper::populateTags([$share], Server::get(ITagManager::class)); + $share = $this->populateTags([$share]); } else { $share = [$share]; } @@ -847,7 +848,7 @@ class ShareAPIController extends OCSController { } if ($includeTags) { - $formatted = Helper::populateTags($formatted, Server::get(ITagManager::class)); + $formatted = $this->populateTags($formatted); } return $formatted; @@ -1100,8 +1101,7 @@ class ShareAPIController extends OCSController { $formatted = $this->fixMissingDisplayName($formatted); if ($includeTags) { - $formatted = - Helper::populateTags($formatted, Server::get(ITagManager::class)); + $formatted = $this->populateTags($formatted); } return $formatted; @@ -1258,17 +1258,17 @@ class ShareAPIController extends OCSController { } if ( - $permissions === null && - $password === null && - $sendPasswordByTalk === null && - $publicUpload === null && - $expireDate === null && - $note === null && - $label === null && - $hideDownload === null && - $attributes === null && - $sendMail === null && - $token === null + $permissions === null + && $password === null + && $sendPasswordByTalk === null + && $publicUpload === null + && $expireDate === null + && $note === null + && $label === null + && $hideDownload === null + && $attributes === null + && $sendMail === null + && $token === null ) { throw new OCSBadRequestException($this->l->t('Wrong or no update parameter given')); } @@ -1563,8 +1563,8 @@ class ShareAPIController extends OCSController { // The owner of the file and the creator of the share // can always edit the share - if ($share->getShareOwner() === $this->userId || - $share->getSharedBy() === $this->userId + if ($share->getShareOwner() === $this->userId + || $share->getSharedBy() === $this->userId ) { return true; } @@ -1596,16 +1596,16 @@ class ShareAPIController extends OCSController { // if the user is the recipient, i can unshare // the share with self - if ($share->getShareType() === IShare::TYPE_USER && - $share->getSharedWith() === $this->userId + if ($share->getShareType() === IShare::TYPE_USER + && $share->getSharedWith() === $this->userId ) { return true; } // The owner of the file and the creator of the share // can always delete the share - if ($share->getShareOwner() === $this->userId || - $share->getSharedBy() === $this->userId + if ($share->getShareOwner() === $this->userId + || $share->getSharedBy() === $this->userId ) { return true; } @@ -1632,16 +1632,16 @@ class ShareAPIController extends OCSController { * @suppress PhanUndeclaredClassMethod */ protected function canDeleteShareFromSelf(IShare $share): bool { - if ($share->getShareType() !== IShare::TYPE_GROUP && - $share->getShareType() !== IShare::TYPE_ROOM && - $share->getShareType() !== IShare::TYPE_DECK && - $share->getShareType() !== IShare::TYPE_SCIENCEMESH + if ($share->getShareType() !== IShare::TYPE_GROUP + && $share->getShareType() !== IShare::TYPE_ROOM + && $share->getShareType() !== IShare::TYPE_DECK + && $share->getShareType() !== IShare::TYPE_SCIENCEMESH ) { return false; } - if ($share->getShareOwner() === $this->userId || - $share->getSharedBy() === $this->userId + if ($share->getShareOwner() === $this->userId + || $share->getSharedBy() === $this->userId ) { // Delete the whole share, not just for self return false; @@ -1874,8 +1874,8 @@ class ShareAPIController extends OCSController { continue; } - $providerShares = - $this->shareManager->getSharesBy($viewer, $provider, $node, $reShares, -1, 0); + $providerShares + = $this->shareManager->getSharesBy($viewer, $provider, $node, $reShares, -1, 0); $shares = array_merge($shares, $providerShares); } @@ -2118,6 +2118,8 @@ class ShareAPIController extends OCSController { $hideDownload = $hideDownload && $originalShare->getHideDownload(); // allow download if already allowed by previous share or when the current share allows downloading $canDownload = $canDownload || $inheritedAttributes === null || $inheritedAttributes->getAttribute('permissions', 'download') !== false; + } elseif ($node->getStorage()->instanceOfStorage(Storage::class)) { + $canDownload = true; // in case of federation storage, we can expect the download to be activated by default } } @@ -2219,4 +2221,41 @@ class ShareAPIController extends OCSController { throw new OCSException($this->l->t('Failed to generate a unique token')); } } + + /** + * Populate the result set with file tags + * + * @psalm-template T of array{tags?: list<string>, file_source: int, ...array<string, mixed>} + * @param list<T> $fileList + * @return list<T> file list populated with tags + */ + private function populateTags(array $fileList): array { + $tagger = $this->tagManager->load('files'); + $tags = $tagger->getTagsForObjects(array_map(static fn (array $fileData) => $fileData['file_source'], $fileList)); + + if (!is_array($tags)) { + throw new \UnexpectedValueException('$tags must be an array'); + } + + // Set empty tag array + foreach ($fileList as &$fileData) { + $fileData['tags'] = []; + } + unset($fileData); + + if (!empty($tags)) { + foreach ($tags as $fileId => $fileTags) { + foreach ($fileList as &$fileData) { + if ($fileId !== $fileData['file_source']) { + continue; + } + + $fileData['tags'] = $fileTags; + } + unset($fileData); + } + } + + return $fileList; + } } diff --git a/apps/files_sharing/lib/Controller/ShareController.php b/apps/files_sharing/lib/Controller/ShareController.php index ad8023ba6bb..5a776379fce 100644 --- a/apps/files_sharing/lib/Controller/ShareController.php +++ b/apps/files_sharing/lib/Controller/ShareController.php @@ -1,4 +1,5 @@ <?php + /** * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2016 ownCloud, Inc. @@ -251,9 +252,9 @@ class ShareController extends AuthPublicShareController { * Emit a ShareLinkAccessedEvent event when a share is accessed, downloaded, auth... */ protected function emitShareAccessEvent(IShare $share, string $step = '', int $errorCode = 200, string $errorMessage = ''): void { - if ($step !== self::SHARE_ACCESS && - $step !== self::SHARE_AUTH && - $step !== self::SHARE_DOWNLOAD) { + if ($step !== self::SHARE_ACCESS + && $step !== self::SHARE_AUTH + && $step !== self::SHARE_DOWNLOAD) { return; } $this->eventDispatcher->dispatchTyped(new ShareLinkAccessedEvent($share, $step, $errorCode, $errorMessage)); diff --git a/apps/files_sharing/lib/Controller/ShareInfoController.php b/apps/files_sharing/lib/Controller/ShareInfoController.php index 0a290d69c65..b7e79aec830 100644 --- a/apps/files_sharing/lib/Controller/ShareInfoController.php +++ b/apps/files_sharing/lib/Controller/ShareInfoController.php @@ -1,4 +1,5 @@ <?php + /** * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later |