diff --git a/apps/dav/lib/Connector/Sabre/ServerFactory.php b/apps/dav/lib/Connector/Sabre/ServerFactory.php index 3aabb828d9c50..7ed8eb2787a6b 100644 --- a/apps/dav/lib/Connector/Sabre/ServerFactory.php +++ b/apps/dav/lib/Connector/Sabre/ServerFactory.php @@ -131,6 +131,7 @@ public function createServer(string $baseUri, // Allow view-only plugin for webdav requests $server->addPlugin(new ViewOnlyPlugin( $userFolder, + $this->config, )); if ($this->userSession->isLoggedIn()) { diff --git a/apps/dav/lib/DAV/ViewOnlyPlugin.php b/apps/dav/lib/DAV/ViewOnlyPlugin.php index d53a74923fe34..7108dc1fa0901 100644 --- a/apps/dav/lib/DAV/ViewOnlyPlugin.php +++ b/apps/dav/lib/DAV/ViewOnlyPlugin.php @@ -14,6 +14,7 @@ use OCP\Files\Folder; use OCP\Files\NotFoundException; use OCP\Files\Storage\ISharedStorage; +use OCP\IConfig; use Sabre\DAV\Exception\NotFound; use Sabre\DAV\Server; use Sabre\DAV\ServerPlugin; @@ -27,6 +28,7 @@ class ViewOnlyPlugin extends ServerPlugin { public function __construct( private ?Folder $userFolder, + private IConfig $config, ) { } @@ -92,6 +94,11 @@ public function checkViewOnly(RequestInterface $request): bool { return true; } + $allowedFileExtensions = $this->config->getSystemValue('allowed_view_extensions', []); + if ($allowedFileExtensions && in_array($node->getExtension(), $allowedFileExtensions, true)) { + return true; + } + // Check if read-only and on whether permission can download is both set and disabled. $canDownload = $attributes->getAttribute('permissions', 'download'); if ($canDownload !== null && !$canDownload) { diff --git a/apps/dav/lib/Server.php b/apps/dav/lib/Server.php index 835a13a45b26e..94f88e586a85a 100644 --- a/apps/dav/lib/Server.php +++ b/apps/dav/lib/Server.php @@ -253,6 +253,7 @@ public function __construct( // Allow view-only plugin for webdav requests $this->server->addPlugin(new ViewOnlyPlugin( \OC::$server->getUserFolder(), + \OCP\Server::get(IConfig::class), )); // custom properties plugin must be the last one diff --git a/apps/dav/tests/unit/DAV/ViewOnlyPluginTest.php b/apps/dav/tests/unit/DAV/ViewOnlyPluginTest.php index 7a4828dd2de53..f1d37b3a1e128 100644 --- a/apps/dav/tests/unit/DAV/ViewOnlyPluginTest.php +++ b/apps/dav/tests/unit/DAV/ViewOnlyPluginTest.php @@ -17,6 +17,7 @@ use OCP\Files\Folder; use OCP\Files\Storage\ISharedStorage; use OCP\Files\Storage\IStorage; +use OCP\IConfig; use OCP\IUser; use OCP\Share\IAttributes; use OCP\Share\IShare; @@ -39,6 +40,7 @@ public function setUp(): void { $this->userFolder = $this->createMock(Folder::class); $this->plugin = new ViewOnlyPlugin( $this->userFolder, + $this->createMock(IConfig::class), ); $this->request = $this->createMock(RequestInterface::class); $this->tree = $this->createMock(Tree::class); diff --git a/core/Controller/PreviewController.php b/core/Controller/PreviewController.php index a3b826c19e64d..a4983f2fbbe99 100644 --- a/core/Controller/PreviewController.php +++ b/core/Controller/PreviewController.php @@ -21,6 +21,7 @@ use OCP\Files\IRootFolder; use OCP\Files\Node; use OCP\Files\NotFoundException; +use OCP\IConfig; use OCP\IPreview; use OCP\IRequest; use OCP\Preview\IMimeIconProvider; @@ -33,6 +34,7 @@ public function __construct( private IRootFolder $root, private ?string $userId, private IMimeIconProvider $mimeIconProvider, + private IConfig $config, ) { parent::__construct($appName, $request); } @@ -145,12 +147,16 @@ private function fetchPreview( return new DataResponse([], Http::STATUS_NOT_FOUND); } + /** @var SharedStorage $storage */ $storage = $node->getStorage(); if ($storage->instanceOfStorage(SharedStorage::class)) { - /** @var SharedStorage $storage */ $share = $storage->getShare(); - $attributes = $share->getAttributes(); - if ($attributes !== null && $attributes->getAttribute('permissions', 'download') === false) { + $allowedFileExtensions = $this->config->getSystemValue('allowed_view_extensions', []); + $isAllowedToViewForExtension = $allowedFileExtensions && in_array($node->getExtension(), $allowedFileExtensions, true); + $shareAttributes = $share->getAttributes(); + $isAllowedByShare = $shareAttributes === null || $shareAttributes->getAttribute('permissions', 'download') !== false; + + if (!$isAllowedToViewForExtension && !$isAllowedByShare) { return new DataResponse([], Http::STATUS_FORBIDDEN); } }