From 8b15ccd2015f563b1bb84dab51bbf6048545f8df Mon Sep 17 00:00:00 2001 From: Hafsa-Naeem Date: Thu, 5 Dec 2024 09:39:03 +0500 Subject: [PATCH] pkp/pkp-lib#10637 Added canLoginAs & canMergeUsers to users endpoint --- api/v1/users/PKPUserController.php | 116 ++++++++++++++++++++++++++++- 1 file changed, 112 insertions(+), 4 deletions(-) diff --git a/api/v1/users/PKPUserController.php b/api/v1/users/PKPUserController.php index 2f840223839..6139ca5e500 100644 --- a/api/v1/users/PKPUserController.php +++ b/api/v1/users/PKPUserController.php @@ -27,6 +27,7 @@ use Illuminate\Support\Facades\Route; use Illuminate\Support\LazyCollection; use PKP\context\Context; +use PKP\core\PKPApplication; use PKP\core\PKPBaseController; use PKP\core\PKPRequest; use PKP\facades\Locale; @@ -116,6 +117,93 @@ public function get(Request $request): JsonResponse return response()->json(Repo::user()->getSchemaMap()->map($user), Response::HTTP_OK); } + protected function getUserPermissions(array $userIds, Request $request): array + { + $currentUser = $request->user(); + $currentUserId = $currentUser->getId(); + + $permissions = []; + + // check if the current user is a Site Admin + $isSiteAdmin = $currentUser->hasRole([Role::ROLE_ID_SITE_ADMIN], PKPApplication::SITE_CONTEXT_ID); + + // fetch all user group assignments for current user and target users + $allUserIds = array_merge($userIds, [$currentUserId]); + $userGroupAssignments = Repo::userGroup()->getCollector() + ->filterByUserIds($allUserIds) + ->getMany() + ->groupBy(function ($item) { + return $item->getData('userId'); + }); + + // get context ids where the current user is a Manager + $managerContextIds = []; + if (!$isSiteAdmin) { + $currentUserGroups = $userGroupAssignments->get($currentUserId, collect()); + foreach ($currentUserGroups as $userGroup) { + if ($userGroup->getRoleId() === Role::ROLE_ID_MANAGER) { + $managerContextIds[] = $userGroup->getContextId(); + } + } + } + + foreach ($userIds as $userId) { + $permissions[$userId] = [ + 'canLoginAs' => false, + 'canMergeUser' => false, + ]; + + // skip if the user is the current user + if ($userId === $currentUserId) { + continue; + } + + // skip if logged in as another user + if (\PKP\security\Validation::loggedInAs()) { + continue; + } + + // site Admin can administer all users + if ($isSiteAdmin) { + $permissions[$userId]['canLoginAs'] = true; + $permissions[$userId]['canMergeUser'] = true; + continue; + } + + // check if the current user has full administrative rights over the target user + $targetUserGroups = $userGroupAssignments->get($userId, collect()); + + $canAdminister = true; + + foreach ($targetUserGroups as $userGroup) { + $roleId = $userGroup->getRoleId(); + $contextId = $userGroup->getContextId(); + + // if the target user is a Site Admin + if ($roleId === Role::ROLE_ID_SITE_ADMIN) { + $canAdminister = false; + break; + } + + // if the target user has roles in contexts the current user does not manage + if (!in_array($contextId, $managerContextIds)) { + $canAdminister = false; + break; + } + } + + if ($canAdminister) { + $permissions[$userId]['canLoginAs'] = true; + $permissions[$userId]['canMergeUser'] = true; + } + } + + return $permissions; + } + + + + /** * Get a collection of users * @@ -125,6 +213,8 @@ public function getMany(Request $request): JsonResponse { $context = $request->attributes->get('context'); /** @var Context $context */ + $includePermissions = $request->query('includePermissions', false); + $params = $this->_processAllowedParams($request->query(null), [ 'assignedToCategory', 'assignedToSection', @@ -180,14 +270,32 @@ public function getMany(Request $request): JsonResponse $users = $collector->getMany(); $map = Repo::user()->getSchemaMap(); - $items = []; + $usersArray = []; + $userIds = []; + foreach ($users as $user) { - $items[] = $map->summarize($user); + $userData = $map->summarize($user); + $usersArray[] = $userData; + + if ($includePermissions) { + $userIds[] = $user->getId(); + } } - + + // add permissions if requested + if ($includePermissions && !empty($userIds)) { + $permissions = $this->getUserPermissions($userIds, $request); + + foreach ($usersArray as &$userData) { + $userId = $userData['id']; + $userData['canLoginAs'] = $permissions[$userId]['canLoginAs'] ?? false; + $userData['canMergeUser'] = $permissions[$userId]['canMergeUser'] ?? false; + } + } + return response()->json([ 'itemsMax' => $collector->getCount(), - 'items' => $items, + 'items' => $usersArray, ], Response::HTTP_OK); }