summaryrefslogtreecommitdiffstats
path: root/apps/dav/lib/DAV/ViewOnlyPlugin.php
diff options
context:
space:
mode:
Diffstat (limited to 'apps/dav/lib/DAV/ViewOnlyPlugin.php')
-rw-r--r--apps/dav/lib/DAV/ViewOnlyPlugin.php109
1 files changed, 109 insertions, 0 deletions
diff --git a/apps/dav/lib/DAV/ViewOnlyPlugin.php b/apps/dav/lib/DAV/ViewOnlyPlugin.php
new file mode 100644
index 00000000000..b4652da09e1
--- /dev/null
+++ b/apps/dav/lib/DAV/ViewOnlyPlugin.php
@@ -0,0 +1,109 @@
+<?php
+/**
+ * @author Piotr Mrowczynski piotr@owncloud.com
+ *
+ * @copyright Copyright (c) 2019, ownCloud GmbH
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCA\DAV\DAV;
+
+use OCA\DAV\Connector\Sabre\Exception\Forbidden;
+use OCA\DAV\Connector\Sabre\File as DavFile;
+use OCA\DAV\Meta\MetaFile;
+use OCP\Files\FileInfo;
+use OCP\Files\NotFoundException;
+use Psr\Log\LoggerInterface;
+use Sabre\DAV\Server;
+use Sabre\DAV\ServerPlugin;
+use Sabre\HTTP\RequestInterface;
+use Sabre\DAV\Exception\NotFound;
+
+/**
+ * Sabre plugin for restricting file share receiver download:
+ */
+class ViewOnlyPlugin extends ServerPlugin {
+
+ private ?Server $server = null;
+ private LoggerInterface $logger;
+
+ public function __construct(LoggerInterface $logger) {
+ $this->logger = $logger;
+ }
+
+ /**
+ * This initializes the plugin.
+ *
+ * This function is called by Sabre\DAV\Server, after
+ * addPlugin is called.
+ *
+ * This method should set up the required event subscriptions.
+ */
+ public function initialize(Server $server): void {
+ $this->server = $server;
+ //priority 90 to make sure the plugin is called before
+ //Sabre\DAV\CorePlugin::httpGet
+ $this->server->on('method:GET', [$this, 'checkViewOnly'], 90);
+ $this->server->on('method:COPY', [$this, 'checkViewOnly'], 90);
+ }
+
+ /**
+ * Disallow download via DAV Api in case file being received share
+ * and having special permission
+ *
+ * @throws Forbidden
+ * @throws NotFoundException
+ */
+ public function checkViewOnly(RequestInterface $request): bool {
+ $path = $request->getPath();
+
+ try {
+ assert($this->server !== null);
+ $davNode = $this->server->tree->getNodeForPath($path);
+ if (!($davNode instanceof DavFile)) {
+ return true;
+ }
+ // Restrict view-only to nodes which are shared
+ $node = $davNode->getNode();
+
+ $storage = $node->getStorage();
+
+ if (!$storage->instanceOfStorage(\OCA\Files_Sharing\SharedStorage::class)) {
+ return true;
+ }
+ // Extract extra permissions
+ /** @var \OCA\Files_Sharing\SharedStorage $storage */
+ $share = $storage->getShare();
+
+ $attributes = $share->getAttributes();
+ if ($attributes === null) {
+ 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) {
+ throw new Forbidden('Access to this resource has been denied because it is in view-only mode.');
+ }
+ } catch (NotFound $e) {
+ $this->logger->warning($e->getMessage(), [
+ 'exception' => $e,
+ ]);
+ }
+
+ return true;
+ }
+}