diff options
Diffstat (limited to 'apps/files_trashbin/lib/Storage.php')
-rw-r--r-- | apps/files_trashbin/lib/Storage.php | 146 |
1 files changed, 49 insertions, 97 deletions
diff --git a/apps/files_trashbin/lib/Storage.php b/apps/files_trashbin/lib/Storage.php index e1470e7634a..82b7af5a934 100644 --- a/apps/files_trashbin/lib/Storage.php +++ b/apps/files_trashbin/lib/Storage.php @@ -1,30 +1,9 @@ <?php + /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Bjoern Schiessle <bjoern@schiessle.org> - * @author Björn Schießle <bjoern@schiessle.org> - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author Julius Härtl <jus@bitgrid.net> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Robin Appelman <robin@icewind.nl> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * @author Vincent Petry <vincent@nextcloud.com> - * - * @license AGPL-3.0 - * - * This code is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License, version 3, - * along with this program. If not, see <http://www.gnu.org/licenses/> - * + * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files_Trashbin; @@ -32,66 +11,47 @@ use OC\Files\Filesystem; use OC\Files\Storage\Wrapper\Wrapper; use OCA\Files_Trashbin\Events\MoveToTrashEvent; use OCA\Files_Trashbin\Trash\ITrashManager; +use OCP\App\IAppManager; use OCP\Encryption\Exceptions\GenericEncryptionException; use OCP\EventDispatcher\IEventDispatcher; use OCP\Files\IRootFolder; use OCP\Files\Node; use OCP\Files\Storage\IStorage; +use OCP\IRequest; use OCP\IUserManager; +use OCP\Server; use Psr\Log\LoggerInterface; class Storage extends Wrapper { private string $mountPoint; - private IUserManager$userManager; - private LoggerInterface $logger; - private IEventDispatcher $eventDispatcher; - private IRootFolder $rootFolder; - private ITrashManager $trashManager; private bool $trashEnabled = true; /** * Storage constructor. - * * @param array $parameters - * @param ITrashManager|null $trashManager - * @param IUserManager|null $userManager - * @param LoggerInterface|null $logger - * @param IEventDispatcher|null $eventDispatcher - * @param IRootFolder|null $rootFolder */ public function __construct( $parameters, - ITrashManager $trashManager = null, - IUserManager $userManager = null, - LoggerInterface $logger = null, - IEventDispatcher $eventDispatcher = null, - IRootFolder $rootFolder = null + private ?ITrashManager $trashManager = null, + private ?IUserManager $userManager = null, + private ?LoggerInterface $logger = null, + private ?IEventDispatcher $eventDispatcher = null, + private ?IRootFolder $rootFolder = null, + private ?IRequest $request = null, ) { $this->mountPoint = $parameters['mountPoint']; - $this->trashManager = $trashManager; - $this->userManager = $userManager; - $this->logger = $logger; - $this->eventDispatcher = $eventDispatcher; - $this->rootFolder = $rootFolder; parent::__construct($parameters); } - /** - * Deletes the given file by moving it into the trashbin. - * - * @param string $path path of file or folder to delete - * - * @return bool true if the operation succeeded, false otherwise - */ - public function unlink($path) { + public function unlink(string $path): bool { if ($this->trashEnabled) { try { return $this->doDelete($path, 'unlink'); } catch (GenericEncryptionException $e) { // in case of a encryption exception we delete the file right away $this->logger->info( - "Can't move file " . $path . - " to the trash bin, therefore it was deleted right away"); + "Can't move file " . $path + . ' to the trash bin, therefore it was deleted right away'); return $this->storage->unlink($path); } @@ -100,14 +60,7 @@ class Storage extends Wrapper { } } - /** - * Deletes the given folder by moving it into the trashbin. - * - * @param string $path path of folder to delete - * - * @return bool true if the operation succeeded, false otherwise - */ - public function rmdir($path) { + public function rmdir(string $path): bool { if ($this->trashEnabled) { return $this->doDelete($path, 'rmdir'); } else { @@ -118,11 +71,8 @@ class Storage extends Wrapper { /** * check if it is a file located in data/user/files only files in the * 'files' directory should be moved to the trash - * - * @param $path - * @return bool */ - protected function shouldMoveToTrash($path) { + protected function shouldMoveToTrash(string $path): bool { $normalized = Filesystem::normalizePath($this->mountPoint . '/' . $path); $parts = explode('/', $normalized); if (count($parts) < 4 || strpos($normalized, '/appdata_') === 0) { @@ -160,7 +110,7 @@ class Storage extends Wrapper { * @param Node $node * @return MoveToTrashEvent */ - protected function createMoveToTrashEvent(Node $node) { + protected function createMoveToTrashEvent(Node $node): MoveToTrashEvent { return new MoveToTrashEvent($node); } @@ -172,41 +122,42 @@ class Storage extends Wrapper { * * @return bool true if the operation succeeded, false otherwise */ - private function doDelete($path, $method) { - if ( - !\OC::$server->getAppManager()->isEnabledForUser('files_trashbin') - || (pathinfo($path, PATHINFO_EXTENSION) === 'part') - || $this->shouldMoveToTrash($path) === false - ) { - return call_user_func([$this->storage, $method], $path); - } + private function doDelete(string $path, string $method): bool { + $isTrashbinEnabled = Server::get(IAppManager::class)->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); } /** * Setup the storage wrapper callback */ - public static function setupStorage() { - $trashManager = \OC::$server->get(ITrashManager::class); - $userManager = \OC::$server->get(IUserManager::class); - $logger = \OC::$server->get(LoggerInterface::class); - $eventDispatcher = \OC::$server->get(IEventDispatcher::class); - $rootFolder = \OC::$server->get(IRootFolder::class); + public static function setupStorage(): void { + $trashManager = Server::get(ITrashManager::class); + $userManager = Server::get(IUserManager::class); + $logger = Server::get(LoggerInterface::class); + $eventDispatcher = Server::get(IEventDispatcher::class); + $rootFolder = Server::get(IRootFolder::class); + $request = Server::get(IRequest::class); Filesystem::addStorageWrapper( 'oc_trashbin', - function (string $mountPoint, IStorage $storage) use ($trashManager, $userManager, $logger, $eventDispatcher, $rootFolder) { + function (string $mountPoint, IStorage $storage) use ($trashManager, $userManager, $logger, $eventDispatcher, $rootFolder, $request) { return new Storage( ['storage' => $storage, 'mountPoint' => $mountPoint], $trashManager, @@ -214,6 +165,7 @@ class Storage extends Wrapper { $logger, $eventDispatcher, $rootFolder, + $request, ); }, 1); @@ -223,7 +175,7 @@ class Storage extends Wrapper { return $this->mountPoint; } - public function moveFromStorage(IStorage $sourceStorage, $sourceInternalPath, $targetInternalPath) { + public function moveFromStorage(IStorage $sourceStorage, string $sourceInternalPath, string $targetInternalPath): bool { $sourceIsTrashbin = $sourceStorage->instanceOfStorage(Storage::class); try { // the fallback for moving between storage involves a copy+delete @@ -247,11 +199,11 @@ class Storage extends Wrapper { } } - protected function disableTrash() { + protected function disableTrash(): void { $this->trashEnabled = false; } - protected function enableTrash() { + protected function enableTrash(): void { $this->trashEnabled = true; } } |