diff options
author | Louis Chemineau <louis@chmn.me> | 2025-01-27 11:32:33 +0100 |
---|---|---|
committer | Louis Chemineau <louis@chmn.me> | 2025-01-30 10:22:31 +0100 |
commit | 6e3195904e05dea5fc3801740114b9840b35f568 (patch) | |
tree | 9d3414aad107081fa392813b1a24c3fb7495bd41 | |
parent | 29533a6130c6398efeb443147ceda543c01a78ae (diff) | |
download | nextcloud-server-backport/50353/stable30.tar.gz nextcloud-server-backport/50353/stable30.zip |
feat: Support X-NC-Skip-Trashbin headerbackport/50353/stable30
This is useful for clients that want to directly and permanently delete a file.
Signed-off-by: Louis Chemineau <louis@chmn.me>
-rw-r--r-- | apps/files_trashbin/lib/Storage.php | 44 | ||||
-rw-r--r-- | apps/files_versions/lib/Storage.php | 3 | ||||
-rw-r--r-- | lib/private/Share20/DefaultShareProvider.php | 12 |
3 files changed, 39 insertions, 20 deletions
diff --git a/apps/files_trashbin/lib/Storage.php b/apps/files_trashbin/lib/Storage.php index 5cfa05dd5e5..90eaf57da67 100644 --- a/apps/files_trashbin/lib/Storage.php +++ b/apps/files_trashbin/lib/Storage.php @@ -10,12 +10,15 @@ 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 { @@ -43,7 +46,8 @@ class Storage extends Wrapper { ?IUserManager $userManager = null, ?LoggerInterface $logger = null, ?IEventDispatcher $eventDispatcher = null, - ?IRootFolder $rootFolder = null + ?IRootFolder $rootFolder = null, + private ?IRequest $request = null, ) { $this->mountPoint = $parameters['mountPoint']; $this->trashManager = $trashManager; @@ -151,26 +155,26 @@ 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); - } + $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); } /** @@ -182,9 +186,10 @@ class Storage extends Wrapper { $logger = \OC::$server->get(LoggerInterface::class); $eventDispatcher = \OC::$server->get(IEventDispatcher::class); $rootFolder = \OC::$server->get(IRootFolder::class); + $request = \OC::$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, @@ -192,6 +197,7 @@ class Storage extends Wrapper { $logger, $eventDispatcher, $rootFolder, + $request, ); }, 1); diff --git a/apps/files_versions/lib/Storage.php b/apps/files_versions/lib/Storage.php index d3e080b9dd2..472283d2c0e 100644 --- a/apps/files_versions/lib/Storage.php +++ b/apps/files_versions/lib/Storage.php @@ -375,7 +375,8 @@ class Storage { $fileInfo->getId(), [ 'encrypted' => $oldVersion, 'encryptedVersion' => $oldVersion, - 'size' => $oldFileInfo->getSize() + 'size' => $oldFileInfo->getData()['size'], + 'unencrypted_size' => $oldFileInfo->getData()['unencrypted_size'], ] ); diff --git a/lib/private/Share20/DefaultShareProvider.php b/lib/private/Share20/DefaultShareProvider.php index 955eb187c46..3e844188f9b 100644 --- a/lib/private/Share20/DefaultShareProvider.php +++ b/lib/private/Share20/DefaultShareProvider.php @@ -1338,6 +1338,18 @@ class DefaultShareProvider implements IShareProviderWithNotification, IShareProv $qb->expr()->eq('item_type', $qb->createNamedParameter('file')), $qb->expr()->eq('item_type', $qb->createNamedParameter('folder')) )); + + // Ensure accepted is true for user and usergroup type + $qb->andWhere( + $qb->expr()->orX( + $qb->expr()->andX( + $qb->expr()->neq('share_type', $qb->createNamedParameter(IShare::TYPE_USER)), + $qb->expr()->neq('share_type', $qb->createNamedParameter(IShare::TYPE_USERGROUP)), + ), + $qb->expr()->eq('accepted', $qb->createNamedParameter(IShare::STATUS_ACCEPTED, IQueryBuilder::PARAM_INT)), + ), + ); + $cursor = $qb->execute(); $users = []; |