From 160bd75d0ad59b3692ae2e904be52c9e4e7295f4 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Julius=20H=C3=A4rtl?= Date: Sat, 18 Feb 2023 15:43:39 +0100 Subject: [PATCH] fix: Use proper path when creating node instances MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Julius Härtl --- apps/dav/lib/Connector/Sabre/Node.php | 11 ++++++---- .../unit/Connector/Sabre/DirectoryTest.php | 20 +++++++++++++++++-- lib/private/Files/Node/Node.php | 6 +++++- tests/lib/Files/Node/FolderTest.php | 2 ++ 4 files changed, 32 insertions(+), 7 deletions(-) diff --git a/apps/dav/lib/Connector/Sabre/Node.php b/apps/dav/lib/Connector/Sabre/Node.php index 2c8d313eefd..c9407b12786 100644 --- a/apps/dav/lib/Connector/Sabre/Node.php +++ b/apps/dav/lib/Connector/Sabre/Node.php @@ -91,11 +91,13 @@ abstract class Node implements \Sabre\DAV\INode { if ($info instanceof Folder || $info instanceof File) { $this->node = $info; } else { + // The Node API assumes that the view passed doesn't have a fake root + $rootView = \OC::$server->get(View::class); $root = \OC::$server->get(IRootFolder::class); if ($info->getType() === FileInfo::TYPE_FOLDER) { - $this->node = new Folder($root, $view, $this->path, $info); + $this->node = new Folder($root, $rootView, $this->fileView->getAbsolutePath($this->path), $info); } else { - $this->node = new File($root, $view, $this->path, $info); + $this->node = new File($root, $rootView, $this->fileView->getAbsolutePath($this->path), $info); } } } @@ -107,10 +109,11 @@ abstract class Node implements \Sabre\DAV\INode { } $this->info = $info; $root = \OC::$server->get(IRootFolder::class); + $rootView = \OC::$server->get(View::class); if ($this->info->getType() === FileInfo::TYPE_FOLDER) { - $this->node = new Folder($root, $this->fileView, $this->path, $this->info); + $this->node = new Folder($root, $rootView, $this->path, $this->info); } else { - $this->node = new File($root, $this->fileView, $this->path, $this->info); + $this->node = new File($root, $rootView, $this->path, $this->info); } } diff --git a/apps/dav/tests/unit/Connector/Sabre/DirectoryTest.php b/apps/dav/tests/unit/Connector/Sabre/DirectoryTest.php index c6365cf3168..b0d3bdd8ec7 100644 --- a/apps/dav/tests/unit/Connector/Sabre/DirectoryTest.php +++ b/apps/dav/tests/unit/Connector/Sabre/DirectoryTest.php @@ -29,9 +29,12 @@ namespace OCA\DAV\Tests\Unit\Connector\Sabre; use OC\Files\FileInfo; +use OC\Files\Filesystem; use OC\Files\Node\Node; use OC\Files\Storage\Wrapper\Quota; +use OC\Files\View; use OCA\DAV\Connector\Sabre\Directory; +use OCP\Constants; use OCP\Files\ForbiddenException; use OCP\Files\Mount\IMountPoint; use Test\Traits\UserTrait; @@ -91,6 +94,10 @@ class DirectoryTest extends \Test\TestCase { ->willReturn(Node::TYPE_FOLDER); $this->info->method('getName') ->willReturn("folder"); + $this->info->method('getPath') + ->willReturn("/admin/files/folder"); + $this->info->method('getPermissions') + ->willReturn(Constants::PERMISSION_READ); } private function getDir($path = '/') { @@ -207,12 +214,21 @@ class DirectoryTest extends \Test\TestCase { $this->view->expects($this->once()) ->method('getDirectoryContent') - ->with('') ->willReturn([$info1, $info2]); $this->view->expects($this->any()) ->method('getRelativePath') - ->willReturn(''); + ->willReturnCallback(function($path) { + return str_replace('/admin/files/', '', $path); + }); + + $this->view->expects($this->any()) + ->method('getAbsolutePath') + ->willReturnCallback(function($path) { + return Filesystem::normalizePath('/admin/files' . $path); + }); + + $this->overwriteService(View::class, $this->view); $dir = new Directory($this->view, $this->info); $nodes = $dir->getChildren(); diff --git a/lib/private/Files/Node/Node.php b/lib/private/Files/Node/Node.php index 2f88cc3a15a..0eef2716141 100644 --- a/lib/private/Files/Node/Node.php +++ b/lib/private/Files/Node/Node.php @@ -37,6 +37,7 @@ use OCP\Files\InvalidPathException; use OCP\Files\NotFoundException; use OCP\Files\NotPermittedException; use OCP\Lock\LockedException; +use OCP\PreConditionNotMetException; use Symfony\Component\EventDispatcher\GenericEvent; // FIXME: this class really should be abstract @@ -52,7 +53,7 @@ class Node implements \OCP\Files\Node { protected $root; /** - * @var string $path + * @var string $path Absolute path to the node (e.g. /admin/files/folder/file) */ protected $path; @@ -72,6 +73,9 @@ class Node implements \OCP\Files\Node { * @param FileInfo $fileInfo */ public function __construct($root, $view, $path, $fileInfo = null, ?Node $parent = null, bool $infoHasSubMountsIncluded = true) { + if (Filesystem::normalizePath($view->getRoot()) !== '/') { + throw new PreConditionNotMetException('The view passed to the node should not have any fake root set'); + } $this->view = $view; $this->root = $root; $this->path = $path; diff --git a/tests/lib/Files/Node/FolderTest.php b/tests/lib/Files/Node/FolderTest.php index 8a604af3846..f8573f0214d 100644 --- a/tests/lib/Files/Node/FolderTest.php +++ b/tests/lib/Files/Node/FolderTest.php @@ -81,6 +81,8 @@ class FolderTest extends NodeTest { ]); $view->method('getFileInfo') ->willReturn($this->createMock(FileInfo::class)); + $view->method('getRelativePath') + ->willReturn('/bar/foo'); $node = new Folder($root, $view, '/bar/foo'); $children = $node->getDirectoryListing(); -- 2.39.5