Skip to content

Commit 6f80c11

Browse files
committed
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 <louis@chmn.me>
1 parent 29533a6 commit 6f80c11

File tree

1 file changed

+25
-19
lines changed

1 file changed

+25
-19
lines changed

apps/files_trashbin/lib/Storage.php

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,15 @@
1010
use OC\Files\Storage\Wrapper\Wrapper;
1111
use OCA\Files_Trashbin\Events\MoveToTrashEvent;
1212
use OCA\Files_Trashbin\Trash\ITrashManager;
13+
use OCP\App\IAppManager;
1314
use OCP\Encryption\Exceptions\GenericEncryptionException;
1415
use OCP\EventDispatcher\IEventDispatcher;
1516
use OCP\Files\IRootFolder;
1617
use OCP\Files\Node;
1718
use OCP\Files\Storage\IStorage;
19+
use OCP\IRequest;
1820
use OCP\IUserManager;
21+
use OCP\Server;
1922
use Psr\Log\LoggerInterface;
2023

2124
class Storage extends Wrapper {
@@ -43,7 +46,8 @@ public function __construct(
4346
?IUserManager $userManager = null,
4447
?LoggerInterface $logger = null,
4548
?IEventDispatcher $eventDispatcher = null,
46-
?IRootFolder $rootFolder = null
49+
?IRootFolder $rootFolder = null,
50+
private ?IRequest $request = null,
4751
) {
4852
$this->mountPoint = $parameters['mountPoint'];
4953
$this->trashManager = $trashManager;
@@ -151,26 +155,26 @@ protected function createMoveToTrashEvent(Node $node) {
151155
* @return bool true if the operation succeeded, false otherwise
152156
*/
153157
private function doDelete($path, $method) {
154-
if (
155-
!\OC::$server->getAppManager()->isEnabledForUser('files_trashbin')
156-
|| (pathinfo($path, PATHINFO_EXTENSION) === 'part')
157-
|| $this->shouldMoveToTrash($path) === false
158-
) {
159-
return call_user_func([$this->storage, $method], $path);
160-
}
158+
$isTrashbinEnabled = Server::get(IAppManager::class)->isEnabledForUser('files_trashbin');
159+
$isPartFile = pathinfo($path, PATHINFO_EXTENSION) === 'part';
160+
$isSkipTrashHeaderSet = $this->request !== null && $this->request->getHeader('X-NC-Skip-Trashbin') === 'true';
161+
// We keep the shouldMoveToTrash call at the end to prevent emitting unnecessary event.
162+
$shouldMoveToTrash = $isTrashbinEnabled && !$isPartFile && !$isSkipTrashHeaderSet && $this->shouldMoveToTrash($path);
163+
164+
if ($shouldMoveToTrash) {
165+
// check permissions before we continue, this is especially important for
166+
// shared files
167+
if (!$this->isDeletable($path)) {
168+
return false;
169+
}
161170

162-
// check permissions before we continue, this is especially important for
163-
// shared files
164-
if (!$this->isDeletable($path)) {
165-
return false;
171+
$isMovedToTrash = $this->trashManager->moveToTrash($this, $path);
172+
if ($isMovedToTrash) {
173+
return true;
174+
}
166175
}
167176

168-
$isMovedToTrash = $this->trashManager->moveToTrash($this, $path);
169-
if (!$isMovedToTrash) {
170-
return call_user_func([$this->storage, $method], $path);
171-
} else {
172-
return true;
173-
}
177+
return call_user_func([$this->storage, $method], $path);
174178
}
175179

176180
/**
@@ -182,16 +186,18 @@ public static function setupStorage() {
182186
$logger = \OC::$server->get(LoggerInterface::class);
183187
$eventDispatcher = \OC::$server->get(IEventDispatcher::class);
184188
$rootFolder = \OC::$server->get(IRootFolder::class);
189+
$request = \OC::$server->get(IRequest::class);
185190
Filesystem::addStorageWrapper(
186191
'oc_trashbin',
187-
function (string $mountPoint, IStorage $storage) use ($trashManager, $userManager, $logger, $eventDispatcher, $rootFolder) {
192+
function (string $mountPoint, IStorage $storage) use ($trashManager, $userManager, $logger, $eventDispatcher, $rootFolder, $request) {
188193
return new Storage(
189194
['storage' => $storage, 'mountPoint' => $mountPoint],
190195
$trashManager,
191196
$userManager,
192197
$logger,
193198
$eventDispatcher,
194199
$rootFolder,
200+
$request,
195201
);
196202
},
197203
1);

0 commit comments

Comments
 (0)