From 441d9f16618abf2d51c888b476a7fada3a976558 Mon Sep 17 00:00:00 2001 From: Ferdinand Thiessen Date: Thu, 24 Apr 2025 13:10:37 +0200 Subject: [PATCH] fix(settings): group admins only can add users to their groups Signed-off-by: Ferdinand Thiessen --- .../lib/Controller/UsersController.php | 25 ++- .../src/components/AppNavigationGroupList.vue | 18 +- apps/settings/src/components/UserList.vue | 6 +- .../src/components/Users/NewUserDialog.vue | 17 +- apps/settings/src/store/users.js | 20 +- cypress/e2e/settings/users-group-admin.cy.ts | 186 ++++++++++++++++++ 6 files changed, 242 insertions(+), 30 deletions(-) create mode 100644 cypress/e2e/settings/users-group-admin.cy.ts diff --git a/apps/settings/lib/Controller/UsersController.php b/apps/settings/lib/Controller/UsersController.php index 3072f2072f3..a720425ab3c 100644 --- a/apps/settings/lib/Controller/UsersController.php +++ b/apps/settings/lib/Controller/UsersController.php @@ -40,10 +40,12 @@ use OCP\AppFramework\Services\IInitialState; use OCP\BackgroundJob\IJobList; use OCP\Encryption\IManager; use OCP\EventDispatcher\IEventDispatcher; +use OCP\Group\ISubAdmin; use OCP\IConfig; use OCP\IGroup; use OCP\IGroupManager; use OCP\IL10N; +use OCP\INavigationManager; use OCP\IRequest; use OCP\IUser; use OCP\IUserSession; @@ -87,8 +89,8 @@ class UsersController extends Controller { */ #[NoAdminRequired] #[NoCSRFRequired] - public function usersListByGroup(): TemplateResponse { - return $this->usersList(); + public function usersListByGroup(INavigationManager $navigationManager, ISubAdmin $subAdmin): TemplateResponse { + return $this->usersList($navigationManager, $subAdmin); } /** @@ -98,13 +100,13 @@ class UsersController extends Controller { */ #[NoAdminRequired] #[NoCSRFRequired] - public function usersList(): TemplateResponse { + public function usersList(INavigationManager $navigationManager, ISubAdmin $subAdmin): TemplateResponse { $user = $this->userSession->getUser(); $uid = $user->getUID(); $isAdmin = $this->groupManager->isAdmin($uid); $isDelegatedAdmin = $this->groupManager->isDelegatedAdmin($uid); - \OC::$server->getNavigationManager()->setActiveEntry('core_users'); + $navigationManager->setActiveEntry('core_users'); /* SORT OPTION: SORT_USERCOUNT or SORT_GROUPNAME */ $sortGroupsBy = MetaData::SORT_USERCOUNT; @@ -180,6 +182,14 @@ class UsersController extends Controller { 'usercount' => $disabledUsers ]; + if (!$isAdmin && !$isDelegatedAdmin) { + $subAdminGroups = array_map( + fn (IGroup $group) => ['id' => $group->getGID(), 'name' => $group->getDisplayName()], + $subAdmin->getSubAdminsGroups($user), + ); + $subAdminGroups = array_values($subAdminGroups); + } + /* QUOTAS PRESETS */ $quotaPreset = $this->parseQuotaPreset($this->config->getAppValue('files', 'quota_preset', '1 GB, 5 GB, 10 GB')); $allowUnlimitedQuota = $this->config->getAppValue('files', 'allow_unlimited_quota', '1') === '1'; @@ -203,12 +213,7 @@ class UsersController extends Controller { $serverData = []; // groups $serverData['systemGroups'] = [$adminGroupData, $recentUsersGroup, $disabledUsersGroup]; - $serverData['userGroups'] = array_values( - array_map( - fn (IGroup $group) => ['id' => $group->getGID(), 'name' => $group->getDisplayName()], - $this->groupManager->getUserGroups($user), - ), - ); + $serverData['subAdminGroups'] = $subAdminGroups ?? []; // Various data $serverData['isAdmin'] = $isAdmin; $serverData['isDelegatedAdmin'] = $isDelegatedAdmin; diff --git a/apps/settings/src/components/AppNavigationGroupList.vue b/apps/settings/src/components/AppNavigationGroupList.vue index b32a07bc9b8..5c648a17098 100644 --- a/apps/settings/src/components/AppNavigationGroupList.vue +++ b/apps/settings/src/components/AppNavigationGroupList.vue @@ -57,12 +57,16 @@