]> source.dussan.org Git - nextcloud-server.git/commitdiff
Check node permissions when deleting a version
authorLouis Chemineau <louis@chmn.me>
Tue, 13 Feb 2024 11:39:31 +0000 (12:39 +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/files_versions/lib/Versions/LegacyVersionsBackend.php

index 784bc0e54499e81ce72f99b41939bd60a472e2f9..fe7f41e81550f4a56bf3711ae4799b604025578a 100644 (file)
@@ -27,6 +27,7 @@ declare(strict_types=1);
 namespace OCA\Files_Versions\Versions;
 
 use OC\Files\View;
+use OCA\DAV\Connector\Sabre\Exception\Forbidden;
 use OCA\Files_Sharing\ISharedStorage;
 use OCA\Files_Sharing\SharedStorage;
 use OCA\Files_Versions\Db\VersionEntity;
@@ -41,23 +42,27 @@ use OCP\Files\NotFoundException;
 use OCP\Files\Storage\IStorage;
 use OCP\IUser;
 use OCP\IUserManager;
+use OCP\IUserSession;
 
 class LegacyVersionsBackend implements IVersionBackend, INameableVersionBackend, IDeletableVersionBackend, INeedSyncVersionBackend {
        private IRootFolder $rootFolder;
        private IUserManager $userManager;
        private VersionsMapper $versionsMapper;
        private IMimeTypeLoader $mimeTypeLoader;
+       private IUserSession $userSession;
 
        public function __construct(
                IRootFolder $rootFolder,
                IUserManager $userManager,
                VersionsMapper $versionsMapper,
-               IMimeTypeLoader $mimeTypeLoader
+               IMimeTypeLoader $mimeTypeLoader,
+               IUserSession $userSession,
        ) {
                $this->rootFolder = $rootFolder;
                $this->userManager = $userManager;
                $this->versionsMapper = $versionsMapper;
                $this->mimeTypeLoader = $mimeTypeLoader;
+               $this->userSession = $userSession;
        }
 
        public function useBackendForStorage(IStorage $storage): bool {
@@ -231,6 +236,10 @@ class LegacyVersionsBackend implements IVersionBackend, INameableVersionBackend,
        }
 
        public function deleteVersion(IVersion $version): void {
+               if (!$this->currentUserHasPermissions($version, \OCP\Constants::PERMISSION_DELETE)) {
+                       throw new Forbidden('You cannot delete this version because you do not have delete permissions on the source file.');
+               }
+
                Storage::deleteRevision($version->getVersionPath(), $version->getRevisionId());
                $versionEntity = $this->versionsMapper->findVersionForFileId(
                        $version->getSourceFile()->getId(),
@@ -270,4 +279,23 @@ class LegacyVersionsBackend implements IVersionBackend, INameableVersionBackend,
        public function deleteVersionsEntity(File $file): void {
                $this->versionsMapper->deleteAllVersionsForFileId($file->getId());
        }
+
+       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;
+       }
 }