]> source.dussan.org Git - nextcloud-server.git/commitdiff
Check share attributes when downloading versions
authorLouis Chemineau <louis@chmn.me>
Tue, 13 Feb 2024 13:46:04 +0000 (14:46 +0100)
committerLouis Chemineau <louis@chmn.me>
Wed, 21 Feb 2024 14:06:01 +0000 (15:06 +0100)
Signed-off-by: Louis Chemineau <louis@chmn.me>
apps/dav/lib/Connector/Sabre/ServerFactory.php
apps/dav/lib/DAV/ViewOnlyPlugin.php
apps/dav/lib/Server.php
apps/dav/tests/unit/DAV/ViewOnlyPluginTest.php
apps/dav/tests/unit/ServerTest.php

index 828977fd8128719c761d3cfb0690e2cf3d356696..113cd8a8c23f3ca4d21b0c499e15d8e6d7086984 100644 (file)
@@ -161,7 +161,7 @@ class ServerFactory {
 
                        // Allow view-only plugin for webdav requests
                        $server->addPlugin(new ViewOnlyPlugin(
-                               $this->logger
+                               $userFolder,
                        ));
 
                        if ($this->userSession->isLoggedIn()) {
index 77a9acd628e02b593d8f2cc28d9f94d72b602522..389dd96efb4a3980aea88a74ae5bd1d17e2f8a25 100644 (file)
@@ -24,8 +24,8 @@ namespace OCA\DAV\DAV;
 use OCA\DAV\Connector\Sabre\Exception\Forbidden;
 use OCA\DAV\Connector\Sabre\File as DavFile;
 use OCA\Files_Versions\Sabre\VersionFile;
+use OCP\Files\Folder;
 use OCP\Files\NotFoundException;
-use Psr\Log\LoggerInterface;
 use Sabre\DAV\Exception\NotFound;
 use Sabre\DAV\Server;
 use Sabre\DAV\ServerPlugin;
@@ -36,10 +36,12 @@ use Sabre\HTTP\RequestInterface;
  */
 class ViewOnlyPlugin extends ServerPlugin {
        private ?Server $server = null;
-       private LoggerInterface $logger;
+       private ?Folder $userFolder;
 
-       public function __construct(LoggerInterface $logger) {
-               $this->logger = $logger;
+       public function __construct(
+               ?Folder $userFolder,
+       ) {
+               $this->userFolder = $userFolder;
        }
 
        /**
@@ -76,6 +78,16 @@ class ViewOnlyPlugin extends ServerPlugin {
                                $node = $davNode->getNode();
                        } elseif ($davNode instanceof VersionFile) {
                                $node = $davNode->getVersion()->getSourceFile();
+                               $currentUserId = $this->userFolder?->getOwner()?->getUID();
+                               // The version source file is relative to the owner storage.
+                               // But we need the node from the current user perspective.
+                               if ($node->getOwner()->getUID() !== $currentUserId) {
+                                       $nodes = $this->userFolder->getById($node->getId());
+                                       $node = array_pop($nodes);
+                                       if (!$node) {
+                                               throw new NotFoundException("Version file not accessible by current user");
+                                       }
+                               }
                        } else {
                                return true;
                        }
index dedb959c1cd6aa7a435df773dc7f9b528b171c87..3197476437bb7407b587e12ee5d5d09fad57edc6 100644 (file)
@@ -240,7 +240,7 @@ class Server {
 
                // Allow view-only plugin for webdav requests
                $this->server->addPlugin(new ViewOnlyPlugin(
-                       $logger
+                       \OC::$server->getUserFolder(),
                ));
 
                if (BrowserErrorPagePlugin::isBrowserRequest($request)) {
index 00dde60d234ad9049c26b7e8e255ec5f2c14301c..32fd9f452b56411c49eb49d2f210fdd85d642618 100644 (file)
@@ -27,10 +27,11 @@ use OCA\Files_Sharing\SharedStorage;
 use OCA\Files_Versions\Sabre\VersionFile;
 use OCA\Files_Versions\Versions\IVersion;
 use OCP\Files\File;
+use OCP\Files\Folder;
 use OCP\Files\Storage\IStorage;
+use OCP\IUser;
 use OCP\Share\IAttributes;
 use OCP\Share\IShare;
-use Psr\Log\LoggerInterface;
 use Sabre\DAV\Server;
 use Sabre\DAV\Tree;
 use Sabre\HTTP\RequestInterface;
@@ -43,10 +44,13 @@ class ViewOnlyPluginTest extends TestCase {
        private $tree;
        /** @var RequestInterface | \PHPUnit\Framework\MockObject\MockObject */
        private $request;
+       /** @var Folder | \PHPUnit\Framework\MockObject\MockObject */
+       private $userFolder;
 
        public function setUp(): void {
+               $this->userFolder = $this->createMock(Folder::class);
                $this->plugin = new ViewOnlyPlugin(
-                       $this->createMock(LoggerInterface::class)
+                       $this->userFolder,
                );
                $this->request = $this->createMock(RequestInterface::class);
                $this->tree = $this->createMock(Tree::class);
@@ -111,6 +115,26 @@ class ViewOnlyPluginTest extends TestCase {
                        $davNode->expects($this->once())
                                ->method('getVersion')
                                ->willReturn($version);
+
+                       $currentUser = $this->createMock(IUser::class);
+                       $currentUser->expects($this->once())
+                               ->method('getUID')
+                               ->willReturn('alice');
+                       $nodeInfo->expects($this->once())
+                               ->method('getOwner')
+                               ->willReturn($currentUser);
+
+                       $nodeInfo = $this->createMock(File::class);
+                       $owner = $this->createMock(IUser::class);
+                       $owner->expects($this->once())
+                               ->method('getUID')
+                               ->willReturn('bob');
+                       $this->userFolder->expects($this->once())
+                               ->method('getById')
+                               ->willReturn([$nodeInfo]);
+                       $this->userFolder->expects($this->once())
+                               ->method('getOwner')
+                               ->willReturn($owner);
                } else {
                        $davPath = 'files/path/to/file.odt';
                        $davNode = $this->createMock(DavFile::class);
index 62e2accd697d3dba0076f96ea01d48ac2ce89fce..26309d5fcd4870da1bb30f58c1dfe9b149274be8 100644 (file)
@@ -45,6 +45,7 @@ class ServerTest extends \Test\TestCase {
                /** @var IRequest | \PHPUnit\Framework\MockObject\MockObject $r */
                $r = $this->createMock(IRequest::class);
                $r->expects($this->any())->method('getRequestUri')->willReturn($uri);
+               $this->loginAsUser('admin');
                $s = new Server($r, '/');
                $this->assertNotNull($s->server);
                foreach ($plugins as $plugin) {