Skip to content

Commit

Permalink
feat: Add allowed_view_extensions config node
Browse files Browse the repository at this point in the history
Signed-off-by: Kostiantyn Miakshyn <[email protected]>
  • Loading branch information
Koc committed Oct 26, 2024
1 parent c3ac8bf commit b543b40
Show file tree
Hide file tree
Showing 6 changed files with 23 additions and 4 deletions.
1 change: 1 addition & 0 deletions apps/dav/lib/Connector/Sabre/ServerFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -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()) {
Expand Down
7 changes: 7 additions & 0 deletions apps/dav/lib/DAV/ViewOnlyPlugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -27,6 +28,7 @@ class ViewOnlyPlugin extends ServerPlugin {

public function __construct(
private ?Folder $userFolder,
private IConfig $config,
) {
}

Expand Down Expand Up @@ -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) {
Expand Down
1 change: 1 addition & 0 deletions apps/dav/lib/Server.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions apps/dav/tests/unit/DAV/ViewOnlyPluginTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand Down
12 changes: 9 additions & 3 deletions core/Controller/PreviewController.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -33,6 +34,7 @@ public function __construct(
private IRootFolder $root,
private ?string $userId,
private IMimeIconProvider $mimeIconProvider,
private IConfig $config,
) {
parent::__construct($appName, $request);
}
Expand Down Expand Up @@ -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);
}
}
Expand Down
4 changes: 3 additions & 1 deletion tests/Core/Controller/PreviewControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use OCP\Files\NotFoundException;
use OCP\Files\SimpleFS\ISimpleFile;
use OCP\Files\Storage\IStorage;
use OCP\IConfig;
use OCP\IPreview;
use OCP\IRequest;
use OCP\Preview\IMimeIconProvider;
Expand Down Expand Up @@ -45,7 +46,8 @@ protected function setUp(): void {
$this->previewManager,
$this->rootFolder,
$this->userId,
$this->createMock(IMimeIconProvider::class)
$this->createMock(IMimeIconProvider::class),
$this->createMock(IConfig::class),
);
}

Expand Down

0 comments on commit b543b40

Please sign in to comment.