diff --git a/apps/files_versions/lib/Versions/LegacyVersionsBackend.php b/apps/files_versions/lib/Versions/LegacyVersionsBackend.php index a9ea09247c2..e2b47a4ea50 100644 --- a/apps/files_versions/lib/Versions/LegacyVersionsBackend.php +++ b/apps/files_versions/lib/Versions/LegacyVersionsBackend.php @@ -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\SharedStorage; use OCA\Files_Versions\Db\VersionEntity; use OCA\Files_Versions\Db\VersionsMapper; @@ -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 { 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 { @@ -214,6 +219,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(), @@ -221,4 +230,23 @@ class LegacyVersionsBackend implements IVersionBackend, INameableVersionBackend, ); $this->versionsMapper->delete($versionEntity); } + + 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; + } }