From 455ec5ff1965654b1146f11aa5c2d1e9b3715acd 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 | 34 ++++++++++---- src/settings/App.tsx | 2 + tests/Folder/FolderManagerTest.php | 74 ++++++++++++++++++++++++++++-- 3 files changed, 96 insertions(+), 14 deletions(-) diff --git a/lib/Folder/FolderManager.php b/lib/Folder/FolderManager.php index 620b7e97a..e47fe631a 100644 --- a/lib/Folder/FolderManager.php +++ b/lib/Folder/FolderManager.php @@ -33,6 +33,8 @@ use Psr\Log\LoggerInterface; class FolderManager { + public const SPACE_DEFAULT = -4; + public function __construct( private IDBConnection $connection, private IGroupManager $groupManager, @@ -64,7 +66,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 +122,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 +165,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 +272,7 @@ public function getFolder(int $id, int $rootStorageId = 0): ?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 +493,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 +548,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 +608,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 +619,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' => self::SPACE_DEFAULT, ]); $query->executeStatement(); $id = $query->getLastInsertId(); @@ -913,4 +913,18 @@ public function getCirclesManager(): ?CirclesManager { return null; } } + + private function getRealQuota(int $quota): int { + if ($quota === self::SPACE_DEFAULT) { + $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..39cedfc7f 100644 --- a/tests/Folder/FolderManagerTest.php +++ b/tests/Folder/FolderManagerTest.php @@ -39,10 +39,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 +85,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 +98,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 +115,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 +165,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 +198,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 +246,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 +262,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 +279,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 +303,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 +321,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 +446,24 @@ public function testGetFolderPermissionsForUserMerge(): void { $permissions = $manager->getFolderPermissionsForUser($this->getUser(['g1', 'g2', 'g3']), 2); $this->assertEquals(0, $permissions); } + + public function testQuotaDefaultValue(): void { + $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); + $this->assertEquals(1024 ** 3, $folder['quota']); + + /** @var array $folder */ + $folder = $this->manager->getFolder($folderId1); + $this->assertEquals(1024 ** 4, $folder['quota']); + } }