diff --git a/apps/provisioning_api/appinfo/routes.php b/apps/provisioning_api/appinfo/routes.php index ab404ff8459..6d9be753d45 100644 --- a/apps/provisioning_api/appinfo/routes.php +++ b/apps/provisioning_api/appinfo/routes.php @@ -47,6 +47,7 @@ return [ // Users ['root' => '/cloud', 'name' => 'Users#getUsers', 'url' => '/users', 'verb' => 'GET'], ['root' => '/cloud', 'name' => 'Users#getUsersDetails', 'url' => '/users/details', 'verb' => 'GET'], + ['root' => '/cloud', 'name' => 'Users#getDisabledUsersDetails', 'url' => '/users/disabled', 'verb' => 'GET'], ['root' => '/cloud', 'name' => 'Users#searchByPhoneNumbers', 'url' => '/users/search/by-phone', 'verb' => 'POST'], ['root' => '/cloud', 'name' => 'Users#addUser', 'url' => '/users', 'verb' => 'POST'], ['root' => '/cloud', 'name' => 'Users#getUser', 'url' => '/users/{userId}', 'verb' => 'GET'], diff --git a/apps/provisioning_api/lib/Controller/UsersController.php b/apps/provisioning_api/lib/Controller/UsersController.php index b7e9b5d0de0..7d8f949b244 100644 --- a/apps/provisioning_api/lib/Controller/UsersController.php +++ b/apps/provisioning_api/lib/Controller/UsersController.php @@ -231,6 +231,71 @@ class UsersController extends AUserData { ]); } + /** + * @NoAdminRequired + * + * Get the list of disabled users and their details + * + * @param ?int $limit Limit the amount of users returned + * @param int $offset Offset + * @return DataResponse}, array{}> + */ + public function getDisabledUsersDetails(?int $limit = null, int $offset = 0): DataResponse { + $currentUser = $this->userSession->getUser(); + if ($currentUser === null) { + return new DataResponse(['users' => []]); + } + $users = []; + + // Admin? Or SubAdmin? + $uid = $currentUser->getUID(); + $subAdminManager = $this->groupManager->getSubAdmin(); + if ($this->groupManager->isAdmin($uid)) { + $users = $this->userManager->getDisabledUsers($limit, $offset); + $users = array_map(fn (IUser $user): string => $user->getUID(), $users); + } elseif ($subAdminManager->isSubAdmin($currentUser)) { + $subAdminOfGroups = $subAdminManager->getSubAdminsGroups($currentUser); + + $users = []; + /* We have to handle offset ourselve for correctness */ + $tempLimit = ($limit === null ? null : $limit + $offset); + foreach ($subAdminOfGroups as $group) { + $users = array_merge( + $users, + array_map( + fn (IUser $user): string => $user->getUID(), + array_filter( + $group->searchUsers('', ($tempLimit === null ? null : $tempLimit - count($users))), + fn (IUser $user): bool => $user->isEnabled() + ) + ) + ); + if (($tempLimit !== null) && (count($users) >= $tempLimit)) { + break; + } + } + $users = array_slice($users, $offset); + } + + /** @var array $usersDetails */ + $usersDetails = []; + foreach ($users as $userId) { + $userData = $this->getUserData($userId); + // Do not insert empty entry + if ($userData !== null) { + $usersDetails[$userId] = $userData; + } else { + // Logged user does not have permissions to see this user + // only showing its id + $usersDetails[$userId] = ['id' => $userId]; + } + } + + return new DataResponse([ + 'users' => $usersDetails + ]); + } + /** * @NoAdminRequired @@ -852,7 +917,6 @@ class UsersController extends AUserData { if ($this->groupManager->isAdmin($currentLoggedInUser->getUID())) { $permittedFields[] = self::USER_FIELD_QUOTA; $permittedFields[] = self::USER_FIELD_MANAGER; - } } else { // Check if admin / subadmin diff --git a/lib/private/User/Manager.php b/lib/private/User/Manager.php index fb1afb65825..8ec8ef0c4be 100644 --- a/lib/private/User/Manager.php +++ b/lib/private/User/Manager.php @@ -52,6 +52,7 @@ use OCP\User\Backend\IGetRealUIDBackend; use OCP\User\Backend\ISearchKnownUsersBackend; use OCP\User\Backend\ICheckPasswordBackend; use OCP\User\Backend\ICountUsersBackend; +use OCP\User\Backend\IProvideEnabledStateBackend; use OCP\User\Events\BeforeUserCreatedEvent; use OCP\User\Events\UserCreatedEvent; use OCP\UserInterface; @@ -337,6 +338,35 @@ class Manager extends PublicEmitter implements IUserManager { return $users; } + /** + * @return IUser[] + */ + public function getDisabledUsers(?int $limit = null, int $offset = 0): array { + $users = $this->config->getUsersForUserValue('core', 'enabled', 'false'); + $users = array_combine( + $users, + array_map( + fn (string $uid): IUser => new LazyUser($uid, $this), + $users + ) + ); + + $tempLimit = ($limit === null ? null : $limit + $offset); + foreach ($this->backends as $backend) { + if (($tempLimit !== null) && (count($users) >= $tempLimit)) { + break; + } + if ($backend instanceof IProvideEnabledStateBackend) { + $backendUsers = $backend->getDisabledUserList(($tempLimit === null ? null : $tempLimit - count($users))); + foreach ($backendUsers as $uid) { + $users[$uid] = new LazyUser($uid, $this, null, $backend); + } + } + } + + return array_slice($users, $offset, $limit); + } + /** * Search known users (from phonebook sync) by displayName * diff --git a/lib/public/IUserManager.php b/lib/public/IUserManager.php index 1efb3d5f0c2..0a94c5ad928 100644 --- a/lib/public/IUserManager.php +++ b/lib/public/IUserManager.php @@ -139,6 +139,12 @@ interface IUserManager { */ public function searchDisplayName($pattern, $limit = null, $offset = null); + /** + * @return IUser[] + * @since 28.0.0 + */ + public function getDisabledUsers(?int $limit = null, int $offset = 0): array; + /** * Search known users (from phonebook sync) by displayName *