diff --git a/lib/Controller/FoldersController.php b/lib/Controller/FoldersController.php index 9df30ba7e..47e60e73d 100644 --- a/lib/Controller/FoldersController.php +++ b/lib/Controller/FoldersController.php @@ -362,6 +362,11 @@ public function editFolder(int $folderId, ?string $title = null, ?int $parent_fo try { if ($parent_folder !== null) { $parent_folder = $this->toInternalFolderId($parent_folder); + if (!Authorizer::hasPermission(Authorizer::PERM_EDIT, $this->authorizer->getPermissionsForFolder($parent_folder, $this->request))) { + $res = new JSONResponse(['status' => 'error', 'data' => ['Not found']], Http::STATUS_NOT_FOUND); + $res->throttle(); + return $res; + } } $folder = $this->folders->updateSharedFolderOrFolder($this->authorizer->getUserId(), $folderId, $title, $parent_folder); return new JSONResponse(['status' => 'success', 'item' => $this->_returnFolderAsArray($folder)]); diff --git a/tests/FolderControllerTest.php b/tests/FolderControllerTest.php index aa184b70c..c040c1312 100644 --- a/tests/FolderControllerTest.php +++ b/tests/FolderControllerTest.php @@ -464,6 +464,38 @@ public function testSharedEdit(bool $canWrite): void { $this->assertEquals([$this->folder4->getId()], $topLevelFolders); } + /** + * Regression test: moving a folder into a parent folder the user + * is not allowed to edit must be rejected. + * + * @throws AlreadyExistsError + * @throws UrlParseError + * @throws UserLimitExceededError + * @throws \OCP\AppFramework\Db\DoesNotExistException + * @throws MultipleObjectsReturnedException + */ + public function testEditMoveToUnauthorizedParentFail(): void { + $this->setupBookmarks(); + $this->authorizer->setUserId($this->userId); + + // The user owns (and may edit) folder1 but has no access to folder4, + // which belongs to otherUser and is not shared. + $output = $this->controller->editFolder($this->folder1->getId(), 'blabla', $this->folder4->getId()); + $data = $output->getData(); + $this->assertEquals('error', $data['status'], var_export($data, true)); + + // folder1 must stay where it was (a top-level folder), untouched. + $output = $this->controller->getFolder($this->folder1->getId()); + $data = $output->getData(); + $this->assertEquals('success', $data['status'], var_export($data, true)); + $this->assertEquals('foo', $data['item']['title']); // title unchanged + $this->assertEquals(-1, $data['item']['parent_folder']); + + $output = $this->controller->getFolders(); + $topLevelFolders = array_map(fn ($item) => $item['id'], $output->getData()['data']); + $this->assertEquals([$this->folder1->getId(), $this->folder3->getId()], $topLevelFolders); + } + /** * @throws AlreadyExistsError * @throws UrlParseError