From 97fbc665aa17597546b0b31a17d90b46e6b464cc Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 18 Apr 2023 09:58:21 +0200 Subject: [PATCH] fix: catch ManuallyLockedException and use app context The files_lock app may throw ManuallyLockedExceptions when attempting to revert a file that is currently opened. This would prevent the user from rolling back a opened file. Text and Richdocuments handle changes of the file while editing. Allow reverting files even when they are locked by these apps and let the apps handle the conflict. Signed-off-by: Max --- apps/files_versions/lib/Storage.php | 32 ++++++++++--------- .../lib/Versions/VersionManager.php | 5 +++ 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/apps/files_versions/lib/Storage.php b/apps/files_versions/lib/Storage.php index 024e1debc9291..2938accddcc44 100644 --- a/apps/files_versions/lib/Storage.php +++ b/apps/files_versions/lib/Storage.php @@ -436,24 +436,26 @@ private static function copyFileContents($view, $path1, $path2) { $view->lockFile($path1, ILockingProvider::LOCK_EXCLUSIVE); $view->lockFile($path2, ILockingProvider::LOCK_EXCLUSIVE); - // TODO add a proper way of overwriting a file while maintaining file ids - if ($storage1->instanceOfStorage('\OC\Files\ObjectStore\ObjectStoreStorage') || $storage2->instanceOfStorage('\OC\Files\ObjectStore\ObjectStoreStorage')) { - $source = $storage1->fopen($internalPath1, 'r'); - $target = $storage2->fopen($internalPath2, 'w'); - [, $result] = \OC_Helper::streamCopy($source, $target); - fclose($source); - fclose($target); - - if ($result !== false) { - $storage1->unlink($internalPath1); + try { + // TODO add a proper way of overwriting a file while maintaining file ids + if ($storage1->instanceOfStorage('\OC\Files\ObjectStore\ObjectStoreStorage') || $storage2->instanceOfStorage('\OC\Files\ObjectStore\ObjectStoreStorage')) { + $source = $storage1->fopen($internalPath1, 'r'); + $target = $storage2->fopen($internalPath2, 'w'); + [, $result] = \OC_Helper::streamCopy($source, $target); + fclose($source); + fclose($target); + + if ($result !== false) { + $storage1->unlink($internalPath1); + } + } else { + $result = $storage2->moveFromStorage($storage1, $internalPath1, $internalPath2); } - } else { - $result = $storage2->moveFromStorage($storage1, $internalPath1, $internalPath2); + } finally { + $view->unlockFile($path1, ILockingProvider::LOCK_EXCLUSIVE); + $view->unlockFile($path2, ILockingProvider::LOCK_EXCLUSIVE); } - $view->unlockFile($path1, ILockingProvider::LOCK_EXCLUSIVE); - $view->unlockFile($path2, ILockingProvider::LOCK_EXCLUSIVE); - return ($result !== false); } diff --git a/apps/files_versions/lib/Versions/VersionManager.php b/apps/files_versions/lib/Versions/VersionManager.php index 4700f1b208b75..9102c9c91f442 100644 --- a/apps/files_versions/lib/Versions/VersionManager.php +++ b/apps/files_versions/lib/Versions/VersionManager.php @@ -27,8 +27,13 @@ use OCP\Files\File; use OCP\Files\FileInfo; +use OCP\Files\IRootFolder; +use OCP\Files\Lock\ILock; +use OCP\Files\Lock\ILockManager; +use OCP\Files\Lock\LockContext; use OCP\Files\Storage\IStorage; use OCP\IUser; +use OCP\Lock\ManuallyLockedException; class VersionManager implements IVersionManager { /** @var (IVersionBackend[])[] */