From f3551b24dcf1d3d2cbe019ae706afb8e4696e492 Mon Sep 17 00:00:00 2001 From: Louis Chemineau Date: Thu, 23 Jan 2025 12:54:10 +0100 Subject: [PATCH] feat: Support X-NC-Skip-Trashbin header This is useful for clients that want to directly and permanently delete a file. Signed-off-by: Louis Chemineau --- apps/files_trashbin/lib/Storage.php | 36 +++++++++++++++-------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/apps/files_trashbin/lib/Storage.php b/apps/files_trashbin/lib/Storage.php index a1247eaed78ba..97532446da03b 100644 --- a/apps/files_trashbin/lib/Storage.php +++ b/apps/files_trashbin/lib/Storage.php @@ -15,6 +15,7 @@ use OCP\Files\IRootFolder; use OCP\Files\Node; use OCP\Files\Storage\IStorage; +use OCP\IRequest; use OCP\IUserManager; use Psr\Log\LoggerInterface; @@ -33,6 +34,7 @@ public function __construct( private ?LoggerInterface $logger = null, private ?IEventDispatcher $eventDispatcher = null, private ?IRootFolder $rootFolder = null, + private ?IRequest $request = null, ) { $this->mountPoint = $parameters['mountPoint']; parent::__construct($parameters); @@ -118,26 +120,26 @@ protected function createMoveToTrashEvent(Node $node): MoveToTrashEvent { * @return bool true if the operation succeeded, false otherwise */ private function doDelete(string $path, string $method): bool { - if ( - !\OC::$server->getAppManager()->isEnabledForUser('files_trashbin') - || (pathinfo($path, PATHINFO_EXTENSION) === 'part') - || $this->shouldMoveToTrash($path) === false - ) { - return call_user_func([$this->storage, $method], $path); - } + $isTrashbinEnabled = \OC::$server->getAppManager()->isEnabledForUser('files_trashbin'); + $isPartFile = pathinfo($path, PATHINFO_EXTENSION) === 'part'; + $isSkipTrashHeaderSet = $this->request !== null && $this->request->getHeader('X-NC-Skip-Trashbin') === 'true'; + // We keep the shouldMoveToTrash call at the end to prevent emitting unnecessary event. + $shouldMoveToTrash = $isTrashbinEnabled && !$isPartFile && !$isSkipTrashHeaderSet && $this->shouldMoveToTrash($path); + + if ($shouldMoveToTrash) { + // check permissions before we continue, this is especially important for + // shared files + if (!$this->isDeletable($path)) { + return false; + } - // check permissions before we continue, this is especially important for - // shared files - if (!$this->isDeletable($path)) { - return false; + $isMovedToTrash = $this->trashManager->moveToTrash($this, $path); + if ($isMovedToTrash) { + return true; + } } - $isMovedToTrash = $this->trashManager->moveToTrash($this, $path); - if (!$isMovedToTrash) { - return call_user_func([$this->storage, $method], $path); - } else { - return true; - } + return call_user_func([$this->storage, $method], $path); } /**