From 56e255ecac08bcdde9392c4665ba258b3482a771 Mon Sep 17 00:00:00 2001 From: Christopher Ng Date: Tue, 25 Mar 2025 14:31:44 -0700 Subject: [PATCH] feat(provisioning_api): Add endpoint for fetching user groups with details Signed-off-by: Christopher Ng --- apps/provisioning_api/appinfo/routes.php | 1 + .../lib/Controller/UsersController.php | 79 +++++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/apps/provisioning_api/appinfo/routes.php b/apps/provisioning_api/appinfo/routes.php index 78526ce6402..35587e4536f 100644 --- a/apps/provisioning_api/appinfo/routes.php +++ b/apps/provisioning_api/appinfo/routes.php @@ -42,6 +42,7 @@ return [ ['root' => '/cloud', 'name' => 'Users#enableUser', 'url' => '/users/{userId}/enable', 'verb' => 'PUT'], ['root' => '/cloud', 'name' => 'Users#disableUser', 'url' => '/users/{userId}/disable', 'verb' => 'PUT'], ['root' => '/cloud', 'name' => 'Users#getUsersGroups', 'url' => '/users/{userId}/groups', 'verb' => 'GET'], + ['root' => '/cloud', 'name' => 'Users#getUsersGroupsDetails', 'url' => '/users/{userId}/groups/details', 'verb' => 'GET'], ['root' => '/cloud', 'name' => 'Users#addToGroup', 'url' => '/users/{userId}/groups', 'verb' => 'POST'], ['root' => '/cloud', 'name' => 'Users#removeFromGroup', 'url' => '/users/{userId}/groups', 'verb' => 'DELETE'], ['root' => '/cloud', 'name' => 'Users#getUserSubAdminGroups', 'url' => '/users/{userId}/subadmins', 'verb' => 'GET'], diff --git a/apps/provisioning_api/lib/Controller/UsersController.php b/apps/provisioning_api/lib/Controller/UsersController.php index de87827906f..a79763aaebf 100644 --- a/apps/provisioning_api/lib/Controller/UsersController.php +++ b/apps/provisioning_api/lib/Controller/UsersController.php @@ -12,6 +12,7 @@ namespace OCA\Provisioning_API\Controller; use InvalidArgumentException; use OC\Authentication\Token\RemoteWipe; +use OC\Group\Group; use OC\KnownUser\KnownUserService; use OC\User\Backend; use OCA\Provisioning_API\ResponseDefinitions; @@ -52,6 +53,7 @@ use OCP\Util; use Psr\Log\LoggerInterface; /** + * @psalm-import-type Provisioning_APIGroupDetails from ResponseDefinitions * @psalm-import-type Provisioning_APIUserDetails from ResponseDefinitions */ class UsersController extends AUserDataOCSController { @@ -1402,6 +1404,83 @@ class UsersController extends AUserDataOCSController { } } + /** + * @NoSubAdminRequired + * + * Get a list of groups with details + * + * @param string $userId ID of the user + * @return DataResponse}, array{}> + * @throws OCSException + * + * 200: Users groups returned + */ + #[NoAdminRequired] + public function getUsersGroupsDetails(string $userId): DataResponse { + $loggedInUser = $this->userSession->getUser(); + + $targetUser = $this->userManager->get($userId); + if ($targetUser === null) { + throw new OCSException('', OCSController::RESPOND_NOT_FOUND); + } + + $isAdmin = $this->groupManager->isAdmin($loggedInUser->getUID()); + $isDelegatedAdmin = $this->groupManager->isDelegatedAdmin($loggedInUser->getUID()); + if ($targetUser->getUID() === $loggedInUser->getUID() || $isAdmin || $isDelegatedAdmin) { + // Self lookup or admin lookup + $groups = array_map( + function (Group $group) { + return [ + 'id' => $group->getGID(), + 'displayname' => $group->getDisplayName(), + 'usercount' => $group->count(), + 'disabled' => $group->countDisabled(), + 'canAdd' => $group->canAddUser(), + 'canRemove' => $group->canRemoveUser(), + ]; + }, + array_values($this->groupManager->getUserGroups($targetUser)), + ); + return new DataResponse([ + 'groups' => $groups, + ]); + } else { + $subAdminManager = $this->groupManager->getSubAdmin(); + + // Looking up someone else + if ($subAdminManager->isUserAccessible($loggedInUser, $targetUser)) { + // Return the group that the method caller is subadmin of for the user in question + $gids = array_values(array_intersect( + array_map( + static fn (IGroup $group) => $group->getGID(), + $subAdminManager->getSubAdminsGroups($loggedInUser), + ), + $this->groupManager->getUserGroupIds($targetUser) + )); + $groups = array_map( + function (string $gid) { + $group = $this->groupManager->get($gid); + return [ + 'id' => $group->getGID(), + 'displayname' => $group->getDisplayName(), + 'usercount' => $group->count(), + 'disabled' => $group->countDisabled(), + 'canAdd' => $group->canAddUser(), + 'canRemove' => $group->canRemoveUser(), + ]; + }, + $gids, + ); + return new DataResponse([ + 'groups' => $groups, + ]); + } else { + // Not permitted + throw new OCSException('', OCSController::RESPOND_NOT_FOUND); + } + } + } + /** * Add a user to a group *