|  | 
|  | 1 | +<?php | 
|  | 2 | +/** | 
|  | 3 | + * @author Piotr Mrowczynski piotr@owncloud.com | 
|  | 4 | + * | 
|  | 5 | + * @copyright Copyright (c) 2019, ownCloud GmbH | 
|  | 6 | + * @license AGPL-3.0 | 
|  | 7 | + * | 
|  | 8 | + * This code is free software: you can redistribute it and/or modify | 
|  | 9 | + * it under the terms of the GNU Affero General Public License, version 3, | 
|  | 10 | + * as published by the Free Software Foundation. | 
|  | 11 | + * | 
|  | 12 | + * This program is distributed in the hope that it will be useful, | 
|  | 13 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | 14 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 
|  | 15 | + * GNU Affero General Public License for more details. | 
|  | 16 | + * | 
|  | 17 | + * You should have received a copy of the GNU Affero General Public License, version 3, | 
|  | 18 | + * along with this program.  If not, see <http://www.gnu.org/licenses/> | 
|  | 19 | + * | 
|  | 20 | + */ | 
|  | 21 | + | 
|  | 22 | +namespace OCA\DAV\DAV; | 
|  | 23 | + | 
|  | 24 | +use OCA\DAV\Connector\Sabre\Exception\Forbidden; | 
|  | 25 | +use OCA\DAV\Connector\Sabre\File as DavFile; | 
|  | 26 | +use OCA\DAV\Meta\MetaFile; | 
|  | 27 | +use OCP\Files\FileInfo; | 
|  | 28 | +use OCP\Files\NotFoundException; | 
|  | 29 | +use Psr\Log\LoggerInterface; | 
|  | 30 | +use Sabre\DAV\Server; | 
|  | 31 | +use Sabre\DAV\ServerPlugin; | 
|  | 32 | +use Sabre\HTTP\RequestInterface; | 
|  | 33 | +use Sabre\DAV\Exception\NotFound; | 
|  | 34 | + | 
|  | 35 | +/** | 
|  | 36 | + * Sabre plugin for restricting file share receiver download: | 
|  | 37 | + */ | 
|  | 38 | +class ViewOnlyPlugin extends ServerPlugin { | 
|  | 39 | + | 
|  | 40 | +	private ?Server $server = null; | 
|  | 41 | +	private LoggerInterface $logger; | 
|  | 42 | + | 
|  | 43 | +	public function __construct(LoggerInterface $logger) { | 
|  | 44 | +		$this->logger = $logger; | 
|  | 45 | +	} | 
|  | 46 | + | 
|  | 47 | +	/** | 
|  | 48 | +	 * This initializes the plugin. | 
|  | 49 | +	 * | 
|  | 50 | +	 * This function is called by Sabre\DAV\Server, after | 
|  | 51 | +	 * addPlugin is called. | 
|  | 52 | +	 * | 
|  | 53 | +	 * This method should set up the required event subscriptions. | 
|  | 54 | +	 */ | 
|  | 55 | +	public function initialize(Server $server): void { | 
|  | 56 | +		$this->server = $server; | 
|  | 57 | +		//priority 90 to make sure the plugin is called before | 
|  | 58 | +		//Sabre\DAV\CorePlugin::httpGet | 
|  | 59 | +		$this->server->on('method:GET', [$this, 'checkViewOnly'], 90); | 
|  | 60 | +	} | 
|  | 61 | + | 
|  | 62 | +	/** | 
|  | 63 | +	 * Disallow download via DAV Api in case file being received share | 
|  | 64 | +	 * and having special permission | 
|  | 65 | +	 * | 
|  | 66 | +	 * @throws Forbidden | 
|  | 67 | +	 * @throws NotFoundException | 
|  | 68 | +	 */ | 
|  | 69 | +	public function checkViewOnly(RequestInterface $request): bool { | 
|  | 70 | +		$path = $request->getPath(); | 
|  | 71 | + | 
|  | 72 | +		try { | 
|  | 73 | +			assert($this->server !== null); | 
|  | 74 | +			$davNode = $this->server->tree->getNodeForPath($path); | 
|  | 75 | +			if (!($davNode instanceof DavFile)) { | 
|  | 76 | +				return true; | 
|  | 77 | +			} | 
|  | 78 | +			// Restrict view-only to nodes which are shared | 
|  | 79 | +			$node = $davNode->getNode(); | 
|  | 80 | + | 
|  | 81 | +			$storage = $node->getStorage(); | 
|  | 82 | + | 
|  | 83 | +			if (!$storage->instanceOfStorage(\OCA\Files_Sharing\SharedStorage::class)) { | 
|  | 84 | +				return true; | 
|  | 85 | +			} | 
|  | 86 | +			// Extract extra permissions | 
|  | 87 | +			/** @var \OCA\Files_Sharing\SharedStorage $storage */ | 
|  | 88 | +			$share = $storage->getShare(); | 
|  | 89 | + | 
|  | 90 | +			$attributes = $share->getAttributes(); | 
|  | 91 | +			if ($attributes === null) { | 
|  | 92 | +				return true; | 
|  | 93 | +			} | 
|  | 94 | + | 
|  | 95 | +			// Check if read-only and on whether permission can download is both set and disabled. | 
|  | 96 | +			$canDownload = $attributes->getAttribute('permissions', 'download'); | 
|  | 97 | +			if ($canDownload !== null && !$canDownload) { | 
|  | 98 | +				throw new Forbidden('Access to this resource has been denied because it is in view-only mode.'); | 
|  | 99 | +			} | 
|  | 100 | +		} catch (NotFound $e) { | 
|  | 101 | +			$this->logger->warning($e->getMessage(), [ | 
|  | 102 | +				'exception' => $e, | 
|  | 103 | +			]); | 
|  | 104 | +		} | 
|  | 105 | + | 
|  | 106 | +		return true; | 
|  | 107 | +	} | 
|  | 108 | +} | 
0 commit comments