From 94501dc4ee1c2c6c3b6ab1080348303c7199cf72 Mon Sep 17 00:00:00 2001 From: Louis Chemineau Date: Tue, 27 Feb 2024 15:51:25 +0100 Subject: [PATCH] Check node permissions when restoring a version Signed-off-by: Louis Chemineau --- .../lib/Versions/LegacyVersionsBackend.php | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/apps/files_versions/lib/Versions/LegacyVersionsBackend.php b/apps/files_versions/lib/Versions/LegacyVersionsBackend.php index 4ea0985e11346..14a9a358febce 100644 --- a/apps/files_versions/lib/Versions/LegacyVersionsBackend.php +++ b/apps/files_versions/lib/Versions/LegacyVersionsBackend.php @@ -27,6 +27,7 @@ namespace OCA\Files_Versions\Versions; use OC\Files\View; +use OCA\DAV\Connector\Sabre\Exception\Forbidden; use OCA\Files_Sharing\SharedStorage; use OCA\Files_Versions\Storage; use OCP\Files\File; @@ -37,16 +38,20 @@ use OCP\Files\Storage\IStorage; use OCP\IUser; use OCP\IUserManager; +use OCP\IUserSession; class LegacyVersionsBackend implements IVersionBackend { /** @var IRootFolder */ private $rootFolder; /** @var IUserManager */ private $userManager; + /** @var IUserSession */ + private $userSession; - public function __construct(IRootFolder $rootFolder, IUserManager $userManager) { + public function __construct(IRootFolder $rootFolder, IUserManager $userManager, IUserSession $userSession) { $this->rootFolder = $rootFolder; $this->userManager = $userManager; + $this->userSession = $userSession; } public function useBackendForStorage(IStorage $storage): bool { @@ -96,6 +101,10 @@ public function createVersion(IUser $user, FileInfo $file) { } public function rollback(IVersion $version) { + if (!$this->currentUserHasPermissions($version, \OCP\Constants::PERMISSION_UPDATE)) { + throw new Forbidden('You cannot restore this version because you do not have update permissions on the source file.'); + } + return Storage::rollback($version->getVersionPath(), $version->getRevisionId(), $version->getUser()); } @@ -125,4 +134,23 @@ public function getVersionFile(IUser $user, FileInfo $sourceFile, $revision): Fi $file = $versionFolder->get($userFolder->getRelativePath($sourceFile->getPath()) . '.v' . $revision); return $file; } + + private function currentUserHasPermissions(IVersion $version, int $permissions): bool { + $sourceFile = $version->getSourceFile(); + $currentUserId = $this->userSession->getUser()->getUID(); + + if ($currentUserId === null) { + throw new NotFoundException("No user logged in"); + } + + if ($sourceFile->getOwner()->getUID() !== $currentUserId) { + $nodes = $this->rootFolder->getUserFolder($currentUserId)->getById($sourceFile->getId()); + $sourceFile = array_pop($nodes); + if (!$sourceFile) { + throw new NotFoundException("Version file not accessible by current user"); + } + } + + return ($sourceFile->getPermissions() & $permissions) === $permissions; + } }