From 241fffdad5c73d367c5aae08efb7ea2956ee0980 Mon Sep 17 00:00:00 2001 From: provokateurin Date: Tue, 8 Oct 2024 12:45:38 +0200 Subject: [PATCH] fix(FolderManager): Use placeholder value for default quota instead of the current value on creation Signed-off-by: provokateurin --- lib/Folder/FolderManager.php | 32 +++++++++---- src/settings/App.tsx | 2 + tests/Folder/FolderManagerTest.php | 77 ++++++++++++++++++++++++++++-- 3 files changed, 97 insertions(+), 14 deletions(-) diff --git a/lib/Folder/FolderManager.php b/lib/Folder/FolderManager.php index 4197a4d52..3e8baf155 100644 --- a/lib/Folder/FolderManager.php +++ b/lib/Folder/FolderManager.php @@ -64,7 +64,7 @@ public function getAllFolders(): array { 'id' => $id, 'mount_point' => $row['mount_point'], 'groups' => $applicableMap[$id] ?? [], - 'quota' => (int)$row['quota'], + 'quota' => $this->getRealQuota((int)$row['quota']), 'size' => 0, 'acl' => (bool)$row['acl'] ]; @@ -120,7 +120,7 @@ public function getAllFoldersWithSize(int $rootStorageId): array { 'id' => $id, 'mount_point' => $row['mount_point'], 'groups' => $applicableMap[$id] ?? [], - 'quota' => (int)$row['quota'], + 'quota' => $this->getRealQuota((int)$row['quota']), 'size' => $row['size'] ? (int)$row['size'] : 0, 'acl' => (bool)$row['acl'], 'manage' => $this->getManageAcl($mappings) @@ -163,7 +163,7 @@ public function getAllFoldersForUserWithSize(int $rootStorageId, IUser $user): a 'id' => $id, 'mount_point' => $row['mount_point'], 'groups' => $applicableMap[$id] ?? [], - 'quota' => (int)$row['quota'], + 'quota' => $this->getRealQuota((int)$row['quota']), 'size' => $row['size'] ? (int)$row['size'] : 0, 'acl' => (bool)$row['acl'], 'manage' => $this->getManageAcl($mappings) @@ -270,7 +270,7 @@ public function getFolder(int $id, int $rootStorageId): ?array { 'id' => $id, 'mount_point' => (string)$row['mount_point'], 'groups' => $applicableMap[$id] ?? [], - 'quota' => (int)$row['quota'], + 'quota' => $this->getRealQuota((int)$row['quota']), 'size' => $row['size'] ?: 0, 'acl' => (bool)$row['acl'], 'manage' => $this->getManageAcl($folderMappings) @@ -491,7 +491,7 @@ public function getFoldersForGroup(string $groupId, int $rootStorageId = 0): arr 'folder_id' => (int)$folder['folder_id'], 'mount_point' => (string)$folder['mount_point'], 'permissions' => (int)$folder['group_permissions'], - 'quota' => (int)$folder['quota'], + 'quota' => $this->getRealQuota((int)$folder['quota']), 'acl' => (bool)$folder['acl'], 'rootCacheEntry' => (isset($folder['fileid'])) ? Cache::cacheEntryFromData($folder, $this->mimeTypeLoader) : null ], $result)); @@ -546,7 +546,7 @@ public function getFoldersForGroups(array $groupIds, int $rootStorageId = 0): ar 'folder_id' => (int)$folder['folder_id'], 'mount_point' => (string)$folder['mount_point'], 'permissions' => (int)$folder['group_permissions'], - 'quota' => (int)$folder['quota'], + 'quota' => $this->getRealQuota((int)$folder['quota']), 'acl' => (bool)$folder['acl'], 'rootCacheEntry' => (isset($folder['fileid'])) ? Cache::cacheEntryFromData($folder, $this->mimeTypeLoader) : null ], $result); @@ -606,7 +606,7 @@ public function getFoldersFromCircleMemberships(IUser $user, int $rootStorageId 'folder_id' => (int)$folder['folder_id'], 'mount_point' => (string)$folder['mount_point'], 'permissions' => (int)$folder['group_permissions'], - 'quota' => (int)$folder['quota'], + 'quota' => $this->getRealQuota((int)$folder['quota']), 'acl' => (bool)$folder['acl'], 'rootCacheEntry' => (isset($folder['fileid'])) ? Cache::cacheEntryFromData($folder, $this->mimeTypeLoader) : null ], $query->executeQuery()->fetchAll()); @@ -617,14 +617,12 @@ public function getFoldersFromCircleMemberships(IUser $user, int $rootStorageId * @throws Exception */ public function createFolder(string $mountPoint): int { - $defaultQuota = $this->config->getSystemValueInt('groupfolders.quota.default', FileInfo::SPACE_UNLIMITED); - $query = $this->connection->getQueryBuilder(); $query->insert('group_folders') ->values([ 'mount_point' => $query->createNamedParameter($mountPoint), - 'quota' => $defaultQuota, + 'quota' => -4, ]); $query->executeStatement(); $id = $query->getLastInsertId(); @@ -913,4 +911,18 @@ public function getCirclesManager(): ?CirclesManager { return null; } } + + private function getRealQuota(int $quota): int { + if ($quota === -4) { + $defaultQuota = $this->config->getSystemValueInt('groupfolders.quota.default', FileInfo::SPACE_UNLIMITED); + // Prevent setting the default quota option to be the default quota value creating an unresolvable self reference + if ($defaultQuota <= 0 && $defaultQuota !== FileInfo::SPACE_UNLIMITED) { + throw new \Exception('Default Groupfolder quota value ' . $defaultQuota . ' is not allowed'); + } + + return $defaultQuota; + } + + return $quota; + } } diff --git a/src/settings/App.tsx b/src/settings/App.tsx index aafc1595c..3a80ee966 100644 --- a/src/settings/App.tsx +++ b/src/settings/App.tsx @@ -16,9 +16,11 @@ import AsyncSelect from 'react-select/async' import AdminGroupSelect from './AdminGroupSelect' import SubAdminGroupSelect from './SubAdminGroupSelect' import { loadState } from '@nextcloud/initial-state' +import { t } from '@nextcloud/l10n' const bytesInOneGibibyte = Math.pow(1024, 3) const defaultQuotaOptions = { + Default: -4, '1 GB': bytesInOneGibibyte, '5 GB': bytesInOneGibibyte * 5, '10 GB': bytesInOneGibibyte * 10, diff --git a/tests/Folder/FolderManagerTest.php b/tests/Folder/FolderManagerTest.php index 416b3fdca..a1efd6970 100644 --- a/tests/Folder/FolderManagerTest.php +++ b/tests/Folder/FolderManagerTest.php @@ -11,6 +11,7 @@ use OCP\EventDispatcher\IEventDispatcher; use OCP\Files\FileInfo; use OCP\Files\IMimeTypeLoader; +use OCP\Files\IRootFolder; use OCP\IConfig; use OCP\IDBConnection; use OCP\IGroupManager; @@ -39,10 +40,6 @@ protected function setUp(): void { $this->logger = $this->createMock(LoggerInterface::class); $this->eventDispatcher = $this->createMock(IEventDispatcher::class); $this->config = $this->createMock(IConfig::class); - $this->config->expects($this->any()) - ->method('getSystemValueInt') - ->with('groupfolders.quota.default', FileInfo::SPACE_UNLIMITED) - ->willReturn(FileInfo::SPACE_UNLIMITED); $this->manager = new FolderManager( Server::get(IDBConnection::class), $this->groupManager, @@ -89,6 +86,11 @@ private function assertHasFolders(array $folders): void { } public function testCreateFolder(): void { + $this->config->expects($this->any()) + ->method('getSystemValueInt') + ->with('groupfolders.quota.default', FileInfo::SPACE_UNLIMITED) + ->willReturn(FileInfo::SPACE_UNLIMITED); + $this->manager->createFolder('foo'); $this->assertHasFolders([ @@ -97,6 +99,11 @@ public function testCreateFolder(): void { } public function testSetMountpoint(): void { + $this->config->expects($this->any()) + ->method('getSystemValueInt') + ->with('groupfolders.quota.default', FileInfo::SPACE_UNLIMITED) + ->willReturn(FileInfo::SPACE_UNLIMITED); + $folderId1 = $this->manager->createFolder('foo'); $this->manager->createFolder('bar'); @@ -109,6 +116,11 @@ public function testSetMountpoint(): void { } public function testAddApplicable(): void { + $this->config->expects($this->any()) + ->method('getSystemValueInt') + ->with('groupfolders.quota.default', FileInfo::SPACE_UNLIMITED) + ->willReturn(FileInfo::SPACE_UNLIMITED); + $folderId1 = $this->manager->createFolder('foo'); $folderId2 = $this->manager->createFolder('bar'); $this->manager->addApplicableGroup($folderId1, 'g1'); @@ -154,6 +166,11 @@ public function testAddApplicable(): void { } public function testSetPermissions(): void { + $this->config->expects($this->any()) + ->method('getSystemValueInt') + ->with('groupfolders.quota.default', FileInfo::SPACE_UNLIMITED) + ->willReturn(FileInfo::SPACE_UNLIMITED); + $folderId1 = $this->manager->createFolder('foo'); $this->manager->addApplicableGroup($folderId1, 'g1'); $this->manager->addApplicableGroup($folderId1, 'g2'); @@ -182,6 +199,11 @@ public function testSetPermissions(): void { } public function testRemoveApplicable(): void { + $this->config->expects($this->any()) + ->method('getSystemValueInt') + ->with('groupfolders.quota.default', FileInfo::SPACE_UNLIMITED) + ->willReturn(FileInfo::SPACE_UNLIMITED); + $folderId1 = $this->manager->createFolder('foo'); $folderId2 = $this->manager->createFolder('bar'); $this->manager->addApplicableGroup($folderId1, 'g1'); @@ -225,6 +247,11 @@ public function testRemoveApplicable(): void { } public function testRemoveFolder(): void { + $this->config->expects($this->any()) + ->method('getSystemValueInt') + ->with('groupfolders.quota.default', FileInfo::SPACE_UNLIMITED) + ->willReturn(FileInfo::SPACE_UNLIMITED); + $folderId1 = $this->manager->createFolder('foo'); $this->manager->createFolder('bar'); @@ -236,6 +263,11 @@ public function testRemoveFolder(): void { } public function testRenameFolder(): void { + $this->config->expects($this->any()) + ->method('getSystemValueInt') + ->with('groupfolders.quota.default', FileInfo::SPACE_UNLIMITED) + ->willReturn(FileInfo::SPACE_UNLIMITED); + $folderId1 = $this->manager->createFolder('foo'); $this->manager->createFolder('other'); @@ -248,6 +280,11 @@ public function testRenameFolder(): void { } public function testSetACL(): void { + $this->config->expects($this->any()) + ->method('getSystemValueInt') + ->with('groupfolders.quota.default', FileInfo::SPACE_UNLIMITED) + ->willReturn(FileInfo::SPACE_UNLIMITED); + $folderId1 = $this->manager->createFolder('foo'); $this->manager->createFolder('other'); @@ -267,6 +304,11 @@ public function testSetACL(): void { } public function testGetFoldersForGroup(): void { + $this->config->expects($this->any()) + ->method('getSystemValueInt') + ->with('groupfolders.quota.default', FileInfo::SPACE_UNLIMITED) + ->willReturn(FileInfo::SPACE_UNLIMITED); + $folderId1 = $this->manager->createFolder('foo'); $this->manager->addApplicableGroup($folderId1, 'g1'); $this->manager->addApplicableGroup($folderId1, 'g2'); @@ -280,6 +322,11 @@ public function testGetFoldersForGroup(): void { } public function testGetFoldersForGroups(): void { + $this->config->expects($this->any()) + ->method('getSystemValueInt') + ->with('groupfolders.quota.default', FileInfo::SPACE_UNLIMITED) + ->willReturn(FileInfo::SPACE_UNLIMITED); + $folderId1 = $this->manager->createFolder('foo'); $this->manager->addApplicableGroup($folderId1, 'g1'); $this->manager->addApplicableGroup($folderId1, 'g2'); @@ -400,4 +447,26 @@ public function testGetFolderPermissionsForUserMerge(): void { $permissions = $manager->getFolderPermissionsForUser($this->getUser(['g1', 'g2', 'g3']), 2); $this->assertEquals(0, $permissions); } + + public function testQuotaDefaultValue(): void { + /** @var int $rootStorageId */ + $rootStorageId = Server::get(IRootFolder::class)->getMountPoint()->getNumericStorageId(); + $folderId1 = $this->manager->createFolder('foo'); + + $exponent = 3; + $this->config->expects($this->any()) + ->method('getSystemValueInt') + ->with('groupfolders.quota.default', FileInfo::SPACE_UNLIMITED) + ->willReturnCallback(function () use (&$exponent) { + return 1024 ** ($exponent++); + }); + + /** @var array $folder */ + $folder = $this->manager->getFolder($folderId1, $rootStorageId); + $this->assertEquals(1024 ** 3, $folder['quota']); + + /** @var array $folder */ + $folder = $this->manager->getFolder($folderId1, $rootStorageId); + $this->assertEquals(1024 ** 4, $folder['quota']); + } }