Skip to content

Commit 30b49cd

Browse files
committed
fix(files_trashbin): check if there is enough space before restoring
Signed-off-by: Kent Delante <kent.delante@proton.me>
1 parent 158b3ef commit 30b49cd

File tree

4 files changed

+46
-3
lines changed

4 files changed

+46
-3
lines changed

apps/files_trashbin/lib/Sabre/TrashbinPlugin.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
*/
99
namespace OCA\Files_Trashbin\Sabre;
1010

11+
use OC\Files\Filesystem;
1112
use OCA\DAV\Connector\Sabre\FilesPlugin;
1213
use OCA\Files_Trashbin\Trash\ITrashItem;
1314
use OCP\IPreview;
@@ -40,6 +41,7 @@ public function initialize(Server $server) {
4041

4142
$this->server->on('propFind', [$this, 'propFind']);
4243
$this->server->on('afterMethod:GET', [$this,'httpGet']);
44+
$this->server->on('beforeMove', [$this, 'beforeMove']);
4345
}
4446

4547

@@ -129,4 +131,41 @@ public function httpGet(RequestInterface $request, ResponseInterface $response):
129131
$response->addHeader('Content-Disposition', 'attachment; filename="' . $node->getFilename() . '"');
130132
}
131133
}
134+
135+
/**
136+
* Check if a user has available space before attempting to
137+
* restore from trashbin unless they have unlimited quota.
138+
*
139+
* @param string $sourcePath
140+
* @param string $destinationPath
141+
* @return bool
142+
*/
143+
public function beforeMove(string $sourcePath, string $destinationPath): bool {
144+
try {
145+
$node = $this->server->tree->getNodeForPath($sourcePath);
146+
$destinationNode = $this->server->tree->getNodeForPath(dirname($destinationPath));
147+
} catch (\Exception $e) {
148+
return true;
149+
}
150+
151+
// Since we're concerned with restoring from trash, the source must
152+
// come from the trashbin and go into the restore folder. Check if that
153+
// is the operation being attempted before checking for quota and free space.
154+
if (!$node instanceof ITrash || !$destinationNode instanceof RestoreFolder) {
155+
return true;
156+
}
157+
158+
$fileInfo = $node->getFileInfo();
159+
if (!$fileInfo instanceof ITrashItem) {
160+
return true;
161+
}
162+
$freeSpace = Filesystem::free_space($fileInfo->getOriginalLocation());
163+
$filesize = $fileInfo->getSize();
164+
if ($freeSpace >= 0 && $freeSpace < $filesize) {
165+
$this->server->httpResponse->setStatus(507);
166+
return false;
167+
}
168+
169+
return true;
170+
}
132171
}

apps/files_trashbin/src/files_actions/restoreAction.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* SPDX-License-Identifier: AGPL-3.0-or-later
44
*/
55
import { getCurrentUser } from '@nextcloud/auth'
6+
import { showError } from '@nextcloud/dialogs'
67
import { emit } from '@nextcloud/event-bus'
78
import { Permission, Node, View, FileAction } from '@nextcloud/files'
89
import { t } from '@nextcloud/l10n'
@@ -52,6 +53,9 @@ export const restoreAction = new FileAction({
5253
emit('files:node:deleted', node)
5354
return true
5455
} catch (error) {
56+
if (error.response?.status === 507) {
57+
showError(t('files_trashbin', 'Not enough free space to restore the file/folder'))
58+
}
5559
logger.error('Failed to restore node', { error, node })
5660
return false
5761
}

dist/files_trashbin-init.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/files_trashbin-init.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)