diff --git a/apps/dav/lib/DAV/ViewOnlyPlugin.php b/apps/dav/lib/DAV/ViewOnlyPlugin.php index b0e2cd4680094..792ea013fe88c 100644 --- a/apps/dav/lib/DAV/ViewOnlyPlugin.php +++ b/apps/dav/lib/DAV/ViewOnlyPlugin.php @@ -8,6 +8,7 @@ namespace OCA\DAV\DAV; +use OCA\DAV\Connector\Sabre\Directory; use OCA\DAV\Connector\Sabre\Exception\Forbidden; use OCA\DAV\Connector\Sabre\File as DavFile; use OCA\Files_Versions\Sabre\VersionFile; @@ -93,17 +94,27 @@ public function checkViewOnly(RequestInterface $request): bool { return true; } - // We have two options here, if download is disabled, but viewing is allowed, - // we still allow the GET request to return the file content. - $canDownload = $attributes->getAttribute('permissions', 'download'); - if (!$share->canSeeContent()) { - throw new Forbidden('Access to this shared resource has been denied because its download permission is disabled.'); - } + switch ($request->getMethod()) { + case 'GET': + // If download is disabled, but viewing is allowed, we still allow the GET method to return the file content. + if (!$share->canSeeContent()) { + throw new Forbidden('Access to this shared resource has been denied because its download permission is disabled.'); + } + break; + case 'COPY': + case 'MOVE': + $destination = $this->server->getCopyAndMoveInfo($request)['destination']; + $destinationParent = $this->server->tree->getNodeForPath(dirname($destination)); + // Copy and move operations within the same storage are allowed, because the destination has the same restrictions. + if (($destinationParent instanceof Directory) && $destinationParent->getNode()->getStorage()->getId() === $storage->getId()) { + break; + } - // If download is disabled, we disable the COPY and MOVE methods even if the - // shareapi_allow_view_without_download is set to true. - if ($request->getMethod() !== 'GET' && ($canDownload !== null && !$canDownload)) { - throw new Forbidden('Access to this shared resource has been denied because its download permission is disabled.'); + // If download is disabled, we disable the COPY and MOVE methods even if the shareapi_allow_view_without_download is set to true. + if (!$share->canDownload()) { + throw new Forbidden('Access to this shared resource has been denied because its download permission is disabled.'); + } + break; } } catch (NotFound $e) { // File not found