Merge pull request #51812 from nextcloud/backport/51750/stable30

[stable30] fix(dav): Give proper HTTP status code on MKCOL when quota exceeded
This commit is contained in:
Marcel Klehr 2025-04-01 09:31:05 +02:00 committed by GitHub
commit b6d9d7628f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -14,6 +14,8 @@ use OCP\Files\StorageNotAvailableException;
use Sabre\DAV\Exception\InsufficientStorage;
use Sabre\DAV\Exception\ServiceUnavailable;
use Sabre\DAV\INode;
use Sabre\HTTP\RequestInterface;
use Sabre\HTTP\ResponseInterface;
/**
* This plugin check user quota and deny creating files when they exceeds the quota.
@ -56,6 +58,7 @@ class QuotaPlugin extends \Sabre\DAV\ServerPlugin {
$server->on('beforeWriteContent', [$this, 'beforeWriteContent'], 10);
$server->on('beforeCreateFile', [$this, 'beforeCreateFile'], 10);
$server->on('method:MKCOL', [$this, 'onCreateCollection'], 30);
$server->on('beforeMove', [$this, 'beforeMove'], 10);
$server->on('beforeCopy', [$this, 'beforeCopy'], 10);
}
@ -89,6 +92,31 @@ class QuotaPlugin extends \Sabre\DAV\ServerPlugin {
return $this->checkQuota($parent->getPath() . '/' . basename($uri));
}
/**
* Check quota before creating directory
*
* @param RequestInterface $request
* @param ResponseInterface $response
* @return bool
* @throws InsufficientStorage
* @throws \Sabre\DAV\Exception\Forbidden
*/
public function onCreateCollection(RequestInterface $request, ResponseInterface $response): bool {
try {
$destinationPath = $this->server->calculateUri($request->getUrl());
$quotaPath = $this->getPathForDestination($destinationPath);
} catch (\Exception $e) {
return true;
}
if ($quotaPath) {
// MKCOL does not have a Content-Length header, so we can use
// a fixed value for the quota check.
return $this->checkQuota($quotaPath, 4096, true);
}
return true;
}
/**
* Check quota before writing content
*
@ -175,7 +203,7 @@ class QuotaPlugin extends \Sabre\DAV\ServerPlugin {
* @throws InsufficientStorage
* @return bool
*/
public function checkQuota(string $path, $length = null) {
public function checkQuota(string $path, $length = null, $isDir = false) {
if ($length === null) {
$length = $this->getLength();
}
@ -192,6 +220,10 @@ class QuotaPlugin extends \Sabre\DAV\ServerPlugin {
$freeSpace = $this->getFreeSpace($path);
if ($freeSpace >= 0 && $length > $freeSpace) {
if ($isDir) {
throw new InsufficientStorage("Insufficient space in $path. $freeSpace available. Cannot create directory");
}
throw new InsufficientStorage("Insufficient space in $path, $length required, $freeSpace available");
}
}