aboutsummaryrefslogtreecommitdiffstats
path: root/apps/files_sharing/lib
diff options
context:
space:
mode:
Diffstat (limited to 'apps/files_sharing/lib')
-rw-r--r--apps/files_sharing/lib/Activity/Settings/PublicLinksUpload.php2
-rw-r--r--apps/files_sharing/lib/AppInfo/Application.php4
-rw-r--r--apps/files_sharing/lib/Cache.php2
-rw-r--r--apps/files_sharing/lib/Config/ConfigLexicon.php39
-rw-r--r--apps/files_sharing/lib/Controller/PublicPreviewController.php16
-rw-r--r--apps/files_sharing/lib/Controller/ShareAPIController.php47
-rw-r--r--apps/files_sharing/lib/DefaultPublicShareTemplateProvider.php13
-rw-r--r--apps/files_sharing/lib/External/Scanner.php3
-rw-r--r--apps/files_sharing/lib/Listener/LoadPublicFileRequestAuthListener.php10
-rw-r--r--apps/files_sharing/lib/Listener/LoadSidebarListener.php5
-rw-r--r--apps/files_sharing/lib/MountProvider.php7
-rw-r--r--apps/files_sharing/lib/SharedStorage.php5
12 files changed, 130 insertions, 23 deletions
diff --git a/apps/files_sharing/lib/Activity/Settings/PublicLinksUpload.php b/apps/files_sharing/lib/Activity/Settings/PublicLinksUpload.php
index 00bf7d0dde9..bcdc4a4ff97 100644
--- a/apps/files_sharing/lib/Activity/Settings/PublicLinksUpload.php
+++ b/apps/files_sharing/lib/Activity/Settings/PublicLinksUpload.php
@@ -61,6 +61,6 @@ class PublicLinksUpload extends ShareActivitySettings {
* @since 11.0.0
*/
public function isDefaultEnabledMail() {
- return true;
+ return false;
}
}
diff --git a/apps/files_sharing/lib/AppInfo/Application.php b/apps/files_sharing/lib/AppInfo/Application.php
index 4c47d3fc2c0..8ddb3afaf33 100644
--- a/apps/files_sharing/lib/AppInfo/Application.php
+++ b/apps/files_sharing/lib/AppInfo/Application.php
@@ -1,4 +1,5 @@
<?php
+
/**
* SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
@@ -12,6 +13,7 @@ use OC\User\DisplayNameCache;
use OCA\Files\Event\LoadAdditionalScriptsEvent;
use OCA\Files\Event\LoadSidebar;
use OCA\Files_Sharing\Capabilities;
+use OCA\Files_Sharing\Config\ConfigLexicon;
use OCA\Files_Sharing\External\Manager;
use OCA\Files_Sharing\External\MountProvider as ExternalMountProvider;
use OCA\Files_Sharing\Helper;
@@ -106,6 +108,8 @@ class Application extends App implements IBootstrap {
// File request auth
$context->registerEventListener(BeforeTemplateRenderedEvent::class, LoadPublicFileRequestAuthListener::class);
+
+ $context->registerConfigLexicon(ConfigLexicon::class);
}
public function boot(IBootContext $context): void {
diff --git a/apps/files_sharing/lib/Cache.php b/apps/files_sharing/lib/Cache.php
index ccc93eb0952..024df5d3f43 100644
--- a/apps/files_sharing/lib/Cache.php
+++ b/apps/files_sharing/lib/Cache.php
@@ -68,7 +68,7 @@ class Cache extends CacheJail {
return $this->root;
}
- protected function getGetUnjailedRoot(): string {
+ public function getGetUnjailedRoot(): string {
return $this->sourceRootInfo->getPath();
}
diff --git a/apps/files_sharing/lib/Config/ConfigLexicon.php b/apps/files_sharing/lib/Config/ConfigLexicon.php
new file mode 100644
index 00000000000..a463b4e7ef2
--- /dev/null
+++ b/apps/files_sharing/lib/Config/ConfigLexicon.php
@@ -0,0 +1,39 @@
+<?php
+
+declare(strict_types=1);
+/**
+ * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace OCA\Files_Sharing\Config;
+
+use NCU\Config\Lexicon\ConfigLexiconEntry;
+use NCU\Config\Lexicon\ConfigLexiconStrictness;
+use NCU\Config\Lexicon\IConfigLexicon;
+use NCU\Config\ValueType;
+
+/**
+ * Config Lexicon for files_sharing.
+ *
+ * Please Add & Manage your Config Keys in that file and keep the Lexicon up to date!
+ *
+ * {@see IConfigLexicon}
+ */
+class ConfigLexicon implements IConfigLexicon {
+ public const SHOW_FEDERATED_AS_INTERNAL = 'show_federated_shares_as_internal';
+
+ public function getStrictness(): ConfigLexiconStrictness {
+ return ConfigLexiconStrictness::IGNORE;
+ }
+
+ public function getAppConfigs(): array {
+ return [
+ new ConfigLexiconEntry(self::SHOW_FEDERATED_AS_INTERNAL, ValueType::BOOL, false, 'shows federated shares as internal shares', true),
+ ];
+ }
+
+ public function getUserConfigs(): array {
+ return [];
+ }
+}
diff --git a/apps/files_sharing/lib/Controller/PublicPreviewController.php b/apps/files_sharing/lib/Controller/PublicPreviewController.php
index 91dead57e80..f275001f162 100644
--- a/apps/files_sharing/lib/Controller/PublicPreviewController.php
+++ b/apps/files_sharing/lib/Controller/PublicPreviewController.php
@@ -11,6 +11,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 +19,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 +35,7 @@ class PublicPreviewController extends PublicShareController {
private ShareManager $shareManager,
ISession $session,
private IPreview $previewManager,
+ private IMimeIconProvider $mimeIconProvider,
) {
parent::__construct($appName, $request, $session);
}
@@ -63,9 +66,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 +84,7 @@ class PublicPreviewController extends PublicShareController {
int $x = 32,
int $y = 32,
$a = false,
+ bool $mimeFallback = false,
) {
$cacheForSeconds = 60 * 60 * 24; // 1 day
@@ -101,7 +107,7 @@ class PublicPreviewController extends PublicShareController {
$downloadForbidden = $attributes?->getAttribute('permissions', 'download') === false;
// 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 +130,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);
diff --git a/apps/files_sharing/lib/Controller/ShareAPIController.php b/apps/files_sharing/lib/Controller/ShareAPIController.php
index 81ead3c4978..23ba9da1568 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;
@@ -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/DefaultPublicShareTemplateProvider.php b/apps/files_sharing/lib/DefaultPublicShareTemplateProvider.php
index 686ba32fd49..afba45cac4a 100644
--- a/apps/files_sharing/lib/DefaultPublicShareTemplateProvider.php
+++ b/apps/files_sharing/lib/DefaultPublicShareTemplateProvider.php
@@ -91,6 +91,9 @@ class DefaultPublicShareTemplateProvider implements IPublicShareTemplateProvider
'disclaimer',
$this->appConfig->getValueString('core', 'shareapi_public_link_disclaimertext'),
);
+ // file drops do not request the root folder so we need to provide label and note if available
+ $this->initialState->provideInitialState('label', $share->getLabel());
+ $this->initialState->provideInitialState('note', $share->getNote());
}
// Set up initial state
$this->initialState->provideInitialState('isPublic', true);
@@ -104,13 +107,12 @@ class DefaultPublicShareTemplateProvider implements IPublicShareTemplateProvider
Util::addInitScript(Application::APP_ID, 'init');
Util::addInitScript(Application::APP_ID, 'init-public');
Util::addScript('files', 'main');
+ Util::addScript(Application::APP_ID, 'public-nickname-handler');
// Add file-request script if needed
$attributes = $share->getAttributes();
$isFileRequest = $attributes?->getAttribute('fileRequest', 'enabled') === true;
- if ($isFileRequest) {
- Util::addScript(Application::APP_ID, 'public-file-request');
- }
+ $this->initialState->provideInitialState('isFileRequest', $isFileRequest);
// Load Viewer scripts
if (class_exists(LoadViewer::class)) {
@@ -149,10 +151,7 @@ class DefaultPublicShareTemplateProvider implements IPublicShareTemplateProvider
$headerActions = [];
if ($view !== 'public-file-drop' && !$share->getHideDownload()) {
// The download URL is used for the "download" header action as well as in some cases for the direct link
- $downloadUrl = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.downloadShare', [
- 'token' => $token,
- 'filename' => ($shareNode instanceof File) ? $shareNode->getName() : null,
- ]);
+ $downloadUrl = $this->urlGenerator->getAbsoluteURL('/public.php/dav/files/' . $token . '/?accept=zip');
// If not a file drop, then add the download header action
$headerActions[] = new SimpleMenuAction('download', $this->l10n->t('Download'), 'icon-download', $downloadUrl, 0, (string)$shareNode->getSize());
diff --git a/apps/files_sharing/lib/External/Scanner.php b/apps/files_sharing/lib/External/Scanner.php
index e45d3723923..2b0741b4b96 100644
--- a/apps/files_sharing/lib/External/Scanner.php
+++ b/apps/files_sharing/lib/External/Scanner.php
@@ -6,6 +6,7 @@
*/
namespace OCA\Files_Sharing\External;
+use OC\Files\Cache\CacheEntry;
use OC\ForbiddenException;
use OCP\Files\NotFoundException;
use OCP\Files\StorageInvalidException;
@@ -29,7 +30,7 @@ class Scanner extends \OC\Files\Cache\Scanner {
* @param string $file file to scan
* @param int $reuseExisting
* @param int $parentId
- * @param \OC\Files\Cache\CacheEntry|array|null|false $cacheData existing data in the cache for the file to be scanned
+ * @param CacheEntry|array|null|false $cacheData existing data in the cache for the file to be scanned
* @param bool $lock set to false to disable getting an additional read lock during scanning
* @param array|null $data the metadata for the file, as returned by the storage
* @return array|null an array of metadata of the scanned file
diff --git a/apps/files_sharing/lib/Listener/LoadPublicFileRequestAuthListener.php b/apps/files_sharing/lib/Listener/LoadPublicFileRequestAuthListener.php
index f1e054c7ee5..6da2476194b 100644
--- a/apps/files_sharing/lib/Listener/LoadPublicFileRequestAuthListener.php
+++ b/apps/files_sharing/lib/Listener/LoadPublicFileRequestAuthListener.php
@@ -10,6 +10,7 @@ namespace OCA\Files_Sharing\Listener;
use OCA\Files_Sharing\AppInfo\Application;
use OCP\AppFramework\Http\Events\BeforeTemplateRenderedEvent;
use OCP\AppFramework\Http\TemplateResponse;
+use OCP\AppFramework\Services\IInitialState;
use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventListener;
use OCP\Share\IManager;
@@ -19,6 +20,7 @@ use OCP\Util;
class LoadPublicFileRequestAuthListener implements IEventListener {
public function __construct(
private IManager $shareManager,
+ private IInitialState $initialState,
) {
}
@@ -51,9 +53,9 @@ class LoadPublicFileRequestAuthListener implements IEventListener {
// Ignore, this is not a file request or the share does not exist
}
- if ($isFileRequest) {
- // Add the script to the public page
- Util::addScript(Application::APP_ID, 'public-file-request');
- }
+ Util::addScript(Application::APP_ID, 'public-nickname-handler');
+
+ // Add file-request script if needed
+ $this->initialState->provideInitialState('isFileRequest', $isFileRequest);
}
}
diff --git a/apps/files_sharing/lib/Listener/LoadSidebarListener.php b/apps/files_sharing/lib/Listener/LoadSidebarListener.php
index b00e937d675..9f0eee9159a 100644
--- a/apps/files_sharing/lib/Listener/LoadSidebarListener.php
+++ b/apps/files_sharing/lib/Listener/LoadSidebarListener.php
@@ -11,9 +11,12 @@ namespace OCA\Files_Sharing\Listener;
use OCA\Files\Event\LoadSidebar;
use OCA\Files_Sharing\AppInfo\Application;
+use OCA\Files_Sharing\Config\ConfigLexicon;
use OCP\AppFramework\Services\IInitialState;
use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventListener;
+use OCP\IAppConfig;
+use OCP\Server;
use OCP\Share\IManager;
use OCP\Util;
@@ -33,6 +36,8 @@ class LoadSidebarListener implements IEventListener {
return;
}
+ $appConfig = Server::get(IAppConfig::class);
+ $this->initialState->provideInitialState('showFederatedSharesAsInternal', $appConfig->getValueBool('files_sharing', ConfigLexicon::SHOW_FEDERATED_AS_INTERNAL));
Util::addScript(Application::APP_ID, 'files_sharing_tab', 'files');
}
}
diff --git a/apps/files_sharing/lib/MountProvider.php b/apps/files_sharing/lib/MountProvider.php
index ea99023676b..91c392de6eb 100644
--- a/apps/files_sharing/lib/MountProvider.php
+++ b/apps/files_sharing/lib/MountProvider.php
@@ -60,7 +60,8 @@ class MountProvider implements IMountProvider {
$superShares = $this->buildSuperShares($shares, $user);
- $mounts = $this->mountManager->getAll();
+ $otherMounts = $this->mountManager->getAll();
+ $mounts = [];
$view = new View('/' . $user->getUID() . '/files');
$ownerViews = [];
$sharingDisabledForUser = $this->shareManager->sharingDisabledForUser($user->getUID());
@@ -90,7 +91,7 @@ class MountProvider implements IMountProvider {
$shareId = (int)$parentShare->getId();
$mount = new SharedMount(
'\OCA\Files_Sharing\SharedStorage',
- $mounts,
+ array_merge($mounts, $otherMounts),
[
'user' => $user->getUID(),
// parent share
@@ -105,7 +106,7 @@ class MountProvider implements IMountProvider {
$foldersExistCache,
$this->eventDispatcher,
$user,
- ($shareId <= $maxValidatedShare)
+ ($shareId <= $maxValidatedShare),
);
$newMaxValidatedShare = max($shareId, $newMaxValidatedShare);
diff --git a/apps/files_sharing/lib/SharedStorage.php b/apps/files_sharing/lib/SharedStorage.php
index dfd4854de1f..1014b0d37d9 100644
--- a/apps/files_sharing/lib/SharedStorage.php
+++ b/apps/files_sharing/lib/SharedStorage.php
@@ -555,4 +555,9 @@ class SharedStorage extends Jail implements LegacyISharedStorage, ISharedStorage
$this->init();
return parent::getUnjailedPath($path);
}
+
+ public function getDirectDownload(string $path): array|false {
+ // disable direct download for shares
+ return [];
+ }
}