aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLouis Chemineau <louis@chmn.me>2025-01-27 11:32:33 +0100
committerLouis Chemineau <louis@chmn.me>2025-01-30 10:22:31 +0100
commit6e3195904e05dea5fc3801740114b9840b35f568 (patch)
tree9d3414aad107081fa392813b1a24c3fb7495bd41
parent29533a6130c6398efeb443147ceda543c01a78ae (diff)
downloadnextcloud-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.php44
-rw-r--r--apps/files_versions/lib/Storage.php3
-rw-r--r--lib/private/Share20/DefaultShareProvider.php12
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 = [];