Merge pull request #28009 from nextcloud/enh/21045/quota-restrictions

Add quota restrictions options
This commit is contained in:
Julien Veyssier 2021-07-30 10:26:56 +02:00 committed by GitHub
commit 7170c03f0e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 115 additions and 10 deletions

View file

@ -162,5 +162,12 @@ class AppConfigController extends OCSController {
if ($app === 'core' && (strpos($key, 'public_') === 0 || strpos($key, 'remote_') === 0)) {
throw new \InvalidArgumentException('The given key can not be set');
}
if ($app === 'files'
&& $key === 'default_quota'
&& $value === 'none'
&& $this->config->getAppValue('files', 'allow_unlimited_quota', '1') === '0') {
throw new \InvalidArgumentException('The given key can not be set, unlimited quota is forbidden on this instance');
}
}
}

View file

@ -798,9 +798,20 @@ class UsersController extends AUserData {
if ($quota === -1) {
$quota = 'none';
} else {
$maxQuota = (int) $this->config->getAppValue('files', 'max_quota', '-1');
if ($maxQuota !== -1 && $quota > $maxQuota) {
throw new OCSException('Invalid quota value. ' . $value . ' is exceeding the maximum quota', 102);
}
$quota = \OCP\Util::humanFileSize($quota);
}
}
// no else block because quota can be set to 'none' in previous if
if ($quota === 'none') {
$allowUnlimitedQuota = $this->config->getAppValue('files', 'allow_unlimited_quota', '1') === '1';
if (!$allowUnlimitedQuota) {
throw new OCSException('Unlimited quota is forbidden on this instance', 102);
}
}
$targetUser->setQuota($quota);
break;
case 'password':

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -243,7 +243,12 @@ class UsersController extends Controller {
/* QUOTAS PRESETS */
$quotaPreset = $this->parseQuotaPreset($this->config->getAppValue('files', 'quota_preset', '1 GB, 5 GB, 10 GB'));
$defaultQuota = $this->config->getAppValue('files', 'default_quota', 'none');
$allowUnlimitedQuota = $this->config->getAppValue('files', 'allow_unlimited_quota', '1') === '1';
if (!$allowUnlimitedQuota && count($quotaPreset) > 0) {
$defaultQuota = $this->config->getAppValue('files', 'default_quota', $quotaPreset[0]);
} else {
$defaultQuota = $this->config->getAppValue('files', 'default_quota', 'none');
}
$event = new BeforeTemplateRenderedEvent();
$this->dispatcher->dispatch('OC\Settings\Users::loadAdditionalScripts', $event);
@ -260,6 +265,7 @@ class UsersController extends Controller {
$serverData['isAdmin'] = $this->isAdmin;
$serverData['sortGroups'] = $sortGroupsBy;
$serverData['quotaPreset'] = $quotaPreset;
$serverData['allowUnlimitedQuota'] = $allowUnlimitedQuota;
$serverData['userCount'] = $userCount;
$serverData['languages'] = $languages;
$serverData['defaultLanguage'] = $this->config->getSystemValue('default_language', 'en');

View file

@ -345,7 +345,9 @@ export default {
label: cur,
}), [])
// add default presets
quotaPreset.unshift(this.unlimitedQuota)
if (this.settings.allowUnlimitedQuota) {
quotaPreset.unshift(this.unlimitedQuota)
}
quotaPreset.unshift(this.defaultQuota)
return quotaPreset
},

View file

@ -274,7 +274,9 @@ export default {
// convert the preset array into objects
const quotaPreset = this.settings.quotaPreset.reduce((acc, cur) => acc.concat({ id: cur, label: cur }), [])
// add default presets
quotaPreset.unshift(this.unlimitedQuota)
if (this.settings.allowUnlimitedQuota) {
quotaPreset.unshift(this.unlimitedQuota)
}
return quotaPreset
},
// mapping saved values to objects

View file

@ -411,6 +411,18 @@ class User implements IUser {
}
if ($quota === 'default') {
$quota = $this->config->getAppValue('files', 'default_quota', 'none');
// if unlimited quota is not allowed => avoid getting 'unlimited' as default_quota fallback value
// use the first preset instead
$allowUnlimitedQuota = $this->config->getAppValue('files', 'allow_unlimited_quota', '1') === '1';
if (!$allowUnlimitedQuota) {
$presets = $this->config->getAppValue('files', 'quota_preset', '1 GB, 5 GB, 10 GB');
$presets = array_filter(array_map('trim', explode(',', $presets)));
$quotaPreset = array_values(array_diff($presets, ['default', 'none']));
if (count($quotaPreset) > 0) {
$quota = $this->config->getAppValue('files', 'default_quota', $quotaPreset[0]);
}
}
}
return $quota;
}

View file

@ -724,6 +724,71 @@ class UserTest extends TestCase {
$user->setQuota('23 TB');
}
public function testGetDefaultUnlimitedQuota() {
/**
* @var UserInterface | \PHPUnit\Framework\MockObject\MockObject $backend
*/
$backend = $this->createMock(\Test\Util\User\Dummy::class);
/** @var PublicEmitter|\PHPUnit\Framework\MockObject\MockObject $emitter */
$emitter = $this->createMock(PublicEmitter::class);
$emitter->expects($this->never())
->method('emit');
$config = $this->createMock(IConfig::class);
$user = new User('foo', $backend, $this->dispatcher, $emitter, $config);
$userValueMap = [
['foo', 'files', 'quota', 'default', 'default'],
];
$appValueMap = [
['files', 'default_quota', 'none', 'none'],
// allow unlimited quota
['files', 'allow_unlimited_quota', '1', '1'],
];
$config->method('getUserValue')
->will($this->returnValueMap($userValueMap));
$config->method('getAppValue')
->will($this->returnValueMap($appValueMap));
$quota = $user->getQuota();
$this->assertEquals('none', $quota);
}
public function testGetDefaultUnlimitedQuotaForbidden() {
/**
* @var UserInterface | \PHPUnit\Framework\MockObject\MockObject $backend
*/
$backend = $this->createMock(\Test\Util\User\Dummy::class);
/** @var PublicEmitter|\PHPUnit\Framework\MockObject\MockObject $emitter */
$emitter = $this->createMock(PublicEmitter::class);
$emitter->expects($this->never())
->method('emit');
$config = $this->createMock(IConfig::class);
$user = new User('foo', $backend, $this->dispatcher, $emitter, $config);
$userValueMap = [
['foo', 'files', 'quota', 'default', 'default'],
];
$appValueMap = [
['files', 'default_quota', 'none', 'none'],
// do not allow unlimited quota
['files', 'allow_unlimited_quota', '1', '0'],
['files', 'quota_preset', '1 GB, 5 GB, 10 GB', '1 GB, 5 GB, 10 GB'],
// expect seeing 1 GB used as fallback value
['files', 'default_quota', '1 GB', '1 GB'],
];
$config->method('getUserValue')
->will($this->returnValueMap($userValueMap));
$config->method('getAppValue')
->will($this->returnValueMap($appValueMap));
$quota = $user->getQuota();
$this->assertEquals('1 GB', $quota);
}
public function testSetQuotaAddressNoChange() {
/**
* @var UserInterface | \PHPUnit\Framework\MockObject\MockObject $backend