From 0ee676cd5123dc13e7f4e31817e02d74d657c51a Mon Sep 17 00:00:00 2001 From: yemkareems Date: Mon, 6 May 2024 17:10:18 +0530 Subject: feat: add ability to sort users by last_login, uid or displayName. one of these needs to be passed as orderBy and sort can be ASC or DESC Signed-off-by: yemkareems --- .../lib/Controller/UsersController.php | 12 ++-- lib/private/Group/Manager.php | 4 +- lib/private/User/Manager.php | 76 +++++++++++++++++++--- lib/public/IUserManager.php | 2 +- 4 files changed, 78 insertions(+), 16 deletions(-) diff --git a/apps/provisioning_api/lib/Controller/UsersController.php b/apps/provisioning_api/lib/Controller/UsersController.php index 67293ae0033..04bf3a94421 100644 --- a/apps/provisioning_api/lib/Controller/UsersController.php +++ b/apps/provisioning_api/lib/Controller/UsersController.php @@ -94,7 +94,7 @@ class UsersController extends AUserData { * * 200: Users returned */ - public function getUsers(string $search = '', ?int $limit = null, int $offset = 0): DataResponse { + public function getUsers(string $search = '', ?int $limit = null, int $offset = 0, string $orderBy = 'last_login', string $sort = 'DESC'): DataResponse { $user = $this->userSession->getUser(); $users = []; @@ -102,7 +102,7 @@ class UsersController extends AUserData { $uid = $user->getUID(); $subAdminManager = $this->groupManager->getSubAdmin(); if ($this->groupManager->isAdmin($uid)) { - $users = $this->userManager->search($search, $limit, $offset); + $users = $this->userManager->search($search, $limit, $offset, $orderBy, $sort); } elseif ($subAdminManager->isSubAdmin($user)) { $subAdminOfGroups = $subAdminManager->getSubAdminsGroups($user); foreach ($subAdminOfGroups as $key => $group) { @@ -131,11 +131,13 @@ class UsersController extends AUserData { * @param string $search Text to search for * @param int|null $limit Limit the amount of groups returned * @param int $offset Offset for searching for groups + * @param string $orderBy Field to order the results with + * @param string $sort ASC or DESC * @return DataResponse}, array{}> * * 200: Users details returned */ - public function getUsersDetails(string $search = '', ?int $limit = null, int $offset = 0): DataResponse { + public function getUsersDetails(string $search = '', ?int $limit = null, int $offset = 0, string $orderBy = 'displayName', string $sort = 'ASC'): DataResponse { $currentUser = $this->userSession->getUser(); $users = []; @@ -143,7 +145,7 @@ class UsersController extends AUserData { $uid = $currentUser->getUID(); $subAdminManager = $this->groupManager->getSubAdmin(); if ($this->groupManager->isAdmin($uid)) { - $users = $this->userManager->search($search, $limit, $offset); + $users = $this->userManager->search($search, $limit, $offset, $orderBy, $sort); $users = array_keys($users); } elseif ($subAdminManager->isSubAdmin($currentUser)) { $subAdminOfGroups = $subAdminManager->getSubAdminsGroups($currentUser); @@ -153,7 +155,7 @@ class UsersController extends AUserData { $users = []; foreach ($subAdminOfGroups as $group) { - $users[] = array_keys($this->groupManager->displayNamesInGroup($group, $search, $limit, $offset)); + $users[] = array_keys($this->groupManager->displayNamesInGroup($group, $search, $limit, $offset, $orderBy, $sort)); } $users = array_merge(...$users); } diff --git a/lib/private/Group/Manager.php b/lib/private/Group/Manager.php index 0ab64907c8b..df4aa67cba4 100644 --- a/lib/private/Group/Manager.php +++ b/lib/private/Group/Manager.php @@ -401,7 +401,7 @@ class Manager extends PublicEmitter implements IGroupManager { * @param int $offset * @return array an array of display names (value) and user ids (key) */ - public function displayNamesInGroup($gid, $search = '', $limit = -1, $offset = 0) { + public function displayNamesInGroup($gid, $search = '', $limit = -1, $offset = 0, $orderBy = 'uid', $sort = 'ASC') { $group = $this->get($gid); if (is_null($group)) { return []; @@ -419,7 +419,7 @@ class Manager extends PublicEmitter implements IGroupManager { } do { - $filteredUsers = $this->userManager->searchDisplayName($search, $searchLimit, $searchOffset); + $filteredUsers = $this->userManager->searchDisplayName($search, $searchLimit, $searchOffset, $orderBy, $sort); foreach ($filteredUsers as $filteredUser) { if ($group->inGroup($filteredUser)) { $groupUsers[] = $filteredUser; diff --git a/lib/private/User/Manager.php b/lib/private/User/Manager.php index d93431a2699..6b0c0dbd1d3 100644 --- a/lib/private/User/Manager.php +++ b/lib/private/User/Manager.php @@ -262,7 +262,7 @@ class Manager extends PublicEmitter implements IUserManager { * @return IUser[] * @deprecated since 27.0.0, use searchDisplayName instead */ - public function search($pattern, $limit = null, $offset = null) { + public function search($pattern, $limit = null, $offset = null, $orderBy = 'uid', $sort = 'ASC') { $users = []; foreach ($this->backends as $backend) { $backendUsers = $backend->getUsers($pattern, $limit, $offset); @@ -272,10 +272,39 @@ class Manager extends PublicEmitter implements IUserManager { } } } + switch ($orderBy.' '.$sort) { + case 'uid DESC': + uasort($users, function (IUser $a, IUser $b) { + return strcasecmp($b->getUID(), $a->getUID()); + }); + break; + case 'last_login ASC': + uasort($users, function (IUser $a, IUser $b) { + return strcasecmp($a->getLastLogin(), $b->getLastLogin()); + }); + break; + case 'last_login DESC': + uasort($users, function (IUser $a, IUser $b) { + return strcasecmp($b->getLastLogin(), $a->getLastLogin()); + }); + break; + case 'displayName ASC': + uasort($users, function (IUser $a, IUser $b) { + return strcasecmp($a->getDisplayName(), $b->getDisplayName()); + }); + break; + case 'displayName DESC': + uasort($users, function (IUser $a, IUser $b) { + return strcasecmp($b->getDisplayName(), $a->getDisplayName()); + }); + break; + default: + uasort($users, function (IUser $a, IUser $b) { + return strcasecmp($a->getUID(), $b->getUID()); + }); + break; + } - uasort($users, function (IUser $a, IUser $b) { - return strcasecmp($a->getUID(), $b->getUID()); - }); return $users; } @@ -287,7 +316,7 @@ class Manager extends PublicEmitter implements IUserManager { * @param int $offset * @return IUser[] */ - public function searchDisplayName($pattern, $limit = null, $offset = null) { + public function searchDisplayName($pattern, $limit = null, $offset = null, $orderBy = 'displayName', $sort= 'ASC') { $users = []; foreach ($this->backends as $backend) { $backendUsers = $backend->getDisplayNames($pattern, $limit, $offset); @@ -298,9 +327,40 @@ class Manager extends PublicEmitter implements IUserManager { } } - usort($users, function (IUser $a, IUser $b) { - return strcasecmp($a->getDisplayName(), $b->getDisplayName()); - }); + switch ($orderBy.' '.$sort) { + case 'uid ASC': + uasort($users, function (IUser $a, IUser $b) { + return strcasecmp($a->getUID(), $b->getUID()); + }); + break; + case 'uid DESC': + uasort($users, function (IUser $a, IUser $b) { + return strcasecmp($b->getUID(), $a->getUID()); + }); + break; + case 'last_login ASC': + uasort($users, function (IUser $a, IUser $b) { + return strcasecmp($a->getLastLogin(), $b->getLastLogin()); + }); + break; + case 'last_login DESC': + uasort($users, function (IUser $a, IUser $b) { + return strcasecmp($b->getLastLogin(), $a->getLastLogin()); + }); + break; + case 'displayName DESC': + uasort($users, function (IUser $a, IUser $b) { + return strcasecmp($b->getDisplayName(), $a->getDisplayName()); + }); + break; + default: + uasort($users, function (IUser $a, IUser $b) { + return strcasecmp($a->getDisplayName(), $b->getDisplayName()); + }); + break; + } + + return $users; } diff --git a/lib/public/IUserManager.php b/lib/public/IUserManager.php index 851b565f617..89cd1f71899 100644 --- a/lib/public/IUserManager.php +++ b/lib/public/IUserManager.php @@ -104,7 +104,7 @@ interface IUserManager { * @return \OCP\IUser[] * @since 8.0.0 */ - public function search($pattern, $limit = null, $offset = null); + public function search($pattern, $limit = null, $offset = null, $orderBy = 'uid', $sort = 'ASC'); /** * search by displayName -- cgit v1.2.3 From 87a8013ee3d81a3ca8fb300db9fbb8d587c4ed38 Mon Sep 17 00:00:00 2001 From: yemkareems Date: Mon, 6 May 2024 17:29:56 +0530 Subject: feat: cs fix run on the changed files and default order by last_login desc. Also last_login sort logic changed Signed-off-by: yemkareems --- apps/provisioning_api/lib/Controller/UsersController.php | 2 +- lib/private/User/Manager.php | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/provisioning_api/lib/Controller/UsersController.php b/apps/provisioning_api/lib/Controller/UsersController.php index 04bf3a94421..fe8a17a6641 100644 --- a/apps/provisioning_api/lib/Controller/UsersController.php +++ b/apps/provisioning_api/lib/Controller/UsersController.php @@ -137,7 +137,7 @@ class UsersController extends AUserData { * * 200: Users details returned */ - public function getUsersDetails(string $search = '', ?int $limit = null, int $offset = 0, string $orderBy = 'displayName', string $sort = 'ASC'): DataResponse { + public function getUsersDetails(string $search = '', ?int $limit = null, int $offset = 0, string $orderBy = 'last_login', string $sort = 'DESC'): DataResponse { $currentUser = $this->userSession->getUser(); $users = []; diff --git a/lib/private/User/Manager.php b/lib/private/User/Manager.php index 6b0c0dbd1d3..87aa859408d 100644 --- a/lib/private/User/Manager.php +++ b/lib/private/User/Manager.php @@ -280,12 +280,12 @@ class Manager extends PublicEmitter implements IUserManager { break; case 'last_login ASC': uasort($users, function (IUser $a, IUser $b) { - return strcasecmp($a->getLastLogin(), $b->getLastLogin()); + return $a->getLastLogin() - $b->getLastLogin(); }); break; case 'last_login DESC': uasort($users, function (IUser $a, IUser $b) { - return strcasecmp($b->getLastLogin(), $a->getLastLogin()); + return $b->getLastLogin() - $a->getLastLogin(); }); break; case 'displayName ASC': @@ -316,7 +316,7 @@ class Manager extends PublicEmitter implements IUserManager { * @param int $offset * @return IUser[] */ - public function searchDisplayName($pattern, $limit = null, $offset = null, $orderBy = 'displayName', $sort= 'ASC') { + public function searchDisplayName($pattern, $limit = null, $offset = null, $orderBy = 'displayName', $sort = 'ASC') { $users = []; foreach ($this->backends as $backend) { $backendUsers = $backend->getDisplayNames($pattern, $limit, $offset); @@ -340,12 +340,12 @@ class Manager extends PublicEmitter implements IUserManager { break; case 'last_login ASC': uasort($users, function (IUser $a, IUser $b) { - return strcasecmp($a->getLastLogin(), $b->getLastLogin()); + return $a->getLastLogin() - $b->getLastLogin(); }); break; case 'last_login DESC': uasort($users, function (IUser $a, IUser $b) { - return strcasecmp($b->getLastLogin(), $a->getLastLogin()); + return $b->getLastLogin() - $a->getLastLogin(); }); break; case 'displayName DESC': -- cgit v1.2.3 From c8c68c3510d1d2ccd73ff5a351ac3b1e5c5a2c5a Mon Sep 17 00:00:00 2001 From: yemkareems Date: Wed, 8 May 2024 14:43:06 +0530 Subject: fix: sort the user getDisplayNames based on lastLogin. Default sort order is lastLogin DESC Signed-off-by: yemkareems --- .../lib/Controller/UsersController.php | 4 ++-- lib/private/User/Backend.php | 8 ++++++-- lib/private/User/Database.php | 19 +++++++++++++------ lib/private/User/Manager.php | 12 ++++++------ lib/public/UserInterface.php | 6 ++++-- 5 files changed, 31 insertions(+), 18 deletions(-) diff --git a/apps/provisioning_api/lib/Controller/UsersController.php b/apps/provisioning_api/lib/Controller/UsersController.php index fe8a17a6641..e0b5b7b28ac 100644 --- a/apps/provisioning_api/lib/Controller/UsersController.php +++ b/apps/provisioning_api/lib/Controller/UsersController.php @@ -94,7 +94,7 @@ class UsersController extends AUserData { * * 200: Users returned */ - public function getUsers(string $search = '', ?int $limit = null, int $offset = 0, string $orderBy = 'last_login', string $sort = 'DESC'): DataResponse { + public function getUsers(string $search = '', ?int $limit = null, int $offset = 0, string $orderBy = 'lastLogin', string $sort = 'DESC'): DataResponse { $user = $this->userSession->getUser(); $users = []; @@ -137,7 +137,7 @@ class UsersController extends AUserData { * * 200: Users details returned */ - public function getUsersDetails(string $search = '', ?int $limit = null, int $offset = 0, string $orderBy = 'last_login', string $sort = 'DESC'): DataResponse { + public function getUsersDetails(string $search = '', ?int $limit = null, int $offset = 0, string $orderBy = 'lastLogin', string $sort = 'DESC'): DataResponse { $currentUser = $this->userSession->getUser(); $users = []; diff --git a/lib/private/User/Backend.php b/lib/private/User/Backend.php index 98b291e5dee..b21db079d54 100644 --- a/lib/private/User/Backend.php +++ b/lib/private/User/Backend.php @@ -89,9 +89,11 @@ abstract class Backend implements UserInterface { * @param string $search * @param null|int $limit * @param null|int $offset + * @param string $orderBy + * @param string $sort * @return string[] an array of all uids */ - public function getUsers($search = '', $limit = null, $offset = null) { + public function getUsers($search = '', $limit = null, $offset = null, $orderBy = 'lastLogin', $sort = 'DESC'): array { return []; } @@ -128,9 +130,11 @@ abstract class Backend implements UserInterface { * @param string $search * @param int|null $limit * @param int|null $offset + * @param string $orderBy + * @param string $sort * @return array an array of all displayNames (value) and the corresponding uids (key) */ - public function getDisplayNames($search = '', $limit = null, $offset = null) { + public function getDisplayNames($search = '', $limit = null, $offset = null, string $orderBy = 'lastLogin', string $sort = 'DESC'): array { $displayNames = []; $users = $this->getUsers($search, $limit, $offset); foreach ($users as $user) { diff --git a/lib/private/User/Database.php b/lib/private/User/Database.php index cc7050f2da8..cb7988783e3 100644 --- a/lib/private/User/Database.php +++ b/lib/private/User/Database.php @@ -227,27 +227,34 @@ class Database extends ABackend implements * @param string $search * @param int|null $limit * @param int|null $offset + * @param string $orderBy + * @param string $sort * @return array an array of all displayNames (value) and the corresponding uids (key) */ - public function getDisplayNames($search = '', $limit = null, $offset = null) { + public function getDisplayNames($search = '', $limit = null, $offset = null, string $orderBy = 'lastLogin', string $sort = 'DESC'): array { $limit = $this->fixLimit($limit); $this->fixDI(); $query = $this->dbConn->getQueryBuilder(); + $appId = 'settings'; $configKey = 'email'; + if($orderBy == 'lastLogin') { + $appId = 'login'; $configKey = 'lastLogin'; + } + $query->select('uid', 'displayname') ->from($this->table, 'u') ->leftJoin('u', 'preferences', 'p', $query->expr()->andX( $query->expr()->eq('userid', 'uid'), - $query->expr()->eq('appid', $query->expr()->literal('settings')), - $query->expr()->eq('configkey', $query->expr()->literal('email'))) + $query->expr()->eq('appid', $query->expr()->literal($appId)), + $query->expr()->eq('configkey', $query->expr()->literal($configKey))) ) // sqlite doesn't like re-using a single named parameter here ->where($query->expr()->iLike('uid', $query->createPositionalParameter('%' . $this->dbConn->escapeLikeParameter($search) . '%'))) ->orWhere($query->expr()->iLike('displayname', $query->createPositionalParameter('%' . $this->dbConn->escapeLikeParameter($search) . '%'))) ->orWhere($query->expr()->iLike('configvalue', $query->createPositionalParameter('%' . $this->dbConn->escapeLikeParameter($search) . '%'))) - ->orderBy($query->func()->lower('displayname'), 'ASC') + ->orderBy($query->func()->lower('configvalue'), $sort) ->addOrderBy('uid_lower', 'ASC') ->setMaxResults($limit) ->setFirstResult($offset); @@ -381,10 +388,10 @@ class Database extends ABackend implements * @param null|int $offset * @return string[] an array of all uids */ - public function getUsers($search = '', $limit = null, $offset = null) { + public function getUsers($search = '', $limit = null, $offset = null, $orderBy = 'lastLogin', $sort = 'DESC'): array { $limit = $this->fixLimit($limit); - $users = $this->getDisplayNames($search, $limit, $offset); + $users = $this->getDisplayNames($search, $limit, $offset, $orderBy, $sort); $userIds = array_map(function ($uid) { return (string)$uid; }, array_keys($users)); diff --git a/lib/private/User/Manager.php b/lib/private/User/Manager.php index 87aa859408d..b28adb39774 100644 --- a/lib/private/User/Manager.php +++ b/lib/private/User/Manager.php @@ -262,10 +262,10 @@ class Manager extends PublicEmitter implements IUserManager { * @return IUser[] * @deprecated since 27.0.0, use searchDisplayName instead */ - public function search($pattern, $limit = null, $offset = null, $orderBy = 'uid', $sort = 'ASC') { + public function search($pattern, $limit = null, $offset = null, $orderBy = 'uid', $sort = 'ASC'): array { $users = []; foreach ($this->backends as $backend) { - $backendUsers = $backend->getUsers($pattern, $limit, $offset); + $backendUsers = $backend->getUsers($pattern, $limit, $offset, $orderBy, $sort); if (is_array($backendUsers)) { foreach ($backendUsers as $uid) { $users[$uid] = new LazyUser($uid, $this, null, $backend); @@ -278,12 +278,12 @@ class Manager extends PublicEmitter implements IUserManager { return strcasecmp($b->getUID(), $a->getUID()); }); break; - case 'last_login ASC': + case 'lastLogin ASC': uasort($users, function (IUser $a, IUser $b) { return $a->getLastLogin() - $b->getLastLogin(); }); break; - case 'last_login DESC': + case 'lastLogin DESC': uasort($users, function (IUser $a, IUser $b) { return $b->getLastLogin() - $a->getLastLogin(); }); @@ -338,12 +338,12 @@ class Manager extends PublicEmitter implements IUserManager { return strcasecmp($b->getUID(), $a->getUID()); }); break; - case 'last_login ASC': + case 'lastLogin ASC': uasort($users, function (IUser $a, IUser $b) { return $a->getLastLogin() - $b->getLastLogin(); }); break; - case 'last_login DESC': + case 'lastLogin DESC': uasort($users, function (IUser $a, IUser $b) { return $b->getLastLogin() - $a->getLastLogin(); }); diff --git a/lib/public/UserInterface.php b/lib/public/UserInterface.php index 34e7a09feb7..3f42d17383a 100644 --- a/lib/public/UserInterface.php +++ b/lib/public/UserInterface.php @@ -45,7 +45,7 @@ interface UserInterface { * @return string[] an array of all uids * @since 4.5.0 */ - public function getUsers($search = '', $limit = null, $offset = null); + public function getUsers($search = '', $limit = null, $offset = null, $orderBy = 'lastLogin', $sort = 'DESC'): array; /** * check if a user exists @@ -69,10 +69,12 @@ interface UserInterface { * @param string $search * @param int|null $limit * @param int|null $offset + * @param string $orderBy + * @param string $sort * @return array an array of all displayNames (value) and the corresponding uids (key) * @since 4.5.0 */ - public function getDisplayNames($search = '', $limit = null, $offset = null); + public function getDisplayNames($search = '', $limit = null, $offset = null, string $orderBy = 'lastLogin', string $sort = 'DESC'); /** * Check if a user list is available or not -- cgit v1.2.3 From 33b38c6573cbd197989539601ddfcb4524eb4c48 Mon Sep 17 00:00:00 2001 From: yemkareems Date: Wed, 8 May 2024 14:47:55 +0530 Subject: fix: cs fix and psalm ci related changes Signed-off-by: yemkareems --- lib/private/User/Backend.php | 2 +- lib/private/User/Database.php | 6 ++++-- lib/public/UserInterface.php | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/private/User/Backend.php b/lib/private/User/Backend.php index b21db079d54..d58092feac1 100644 --- a/lib/private/User/Backend.php +++ b/lib/private/User/Backend.php @@ -93,7 +93,7 @@ abstract class Backend implements UserInterface { * @param string $sort * @return string[] an array of all uids */ - public function getUsers($search = '', $limit = null, $offset = null, $orderBy = 'lastLogin', $sort = 'DESC'): array { + public function getUsers($search = '', $limit = null, $offset = null, $orderBy = 'lastLogin', $sort = 'DESC') { return []; } diff --git a/lib/private/User/Database.php b/lib/private/User/Database.php index cb7988783e3..6a1861e5dba 100644 --- a/lib/private/User/Database.php +++ b/lib/private/User/Database.php @@ -238,9 +238,11 @@ class Database extends ABackend implements $query = $this->dbConn->getQueryBuilder(); - $appId = 'settings'; $configKey = 'email'; + $appId = 'settings'; + $configKey = 'email'; if($orderBy == 'lastLogin') { - $appId = 'login'; $configKey = 'lastLogin'; + $appId = 'login'; + $configKey = 'lastLogin'; } $query->select('uid', 'displayname') diff --git a/lib/public/UserInterface.php b/lib/public/UserInterface.php index 3f42d17383a..765da3a87a2 100644 --- a/lib/public/UserInterface.php +++ b/lib/public/UserInterface.php @@ -45,7 +45,7 @@ interface UserInterface { * @return string[] an array of all uids * @since 4.5.0 */ - public function getUsers($search = '', $limit = null, $offset = null, $orderBy = 'lastLogin', $sort = 'DESC'): array; + public function getUsers($search = '', $limit = null, $offset = null, $orderBy = 'lastLogin', $sort = 'DESC'); /** * check if a user exists -- cgit v1.2.3 From 76c875a5882753e37ef39015a1711b68e7ea0d0b Mon Sep 17 00:00:00 2001 From: yemkareems Date: Tue, 28 May 2024 16:23:51 +0530 Subject: fix: change orderBy and sort to sortMode and sortOrder. default it to uid asc. enable email search by changing query Signed-off-by: yemkareems --- .../lib/Controller/UsersController.php | 14 ++++----- lib/private/Group/Manager.php | 4 +-- lib/private/User/Backend.php | 12 ++++---- lib/private/User/Database.php | 35 ++++++++++++---------- lib/private/User/Manager.php | 30 +++++++++---------- lib/public/IUserManager.php | 2 +- lib/public/UserInterface.php | 8 ++--- 7 files changed, 55 insertions(+), 50 deletions(-) diff --git a/apps/provisioning_api/lib/Controller/UsersController.php b/apps/provisioning_api/lib/Controller/UsersController.php index e0b5b7b28ac..eced881516f 100644 --- a/apps/provisioning_api/lib/Controller/UsersController.php +++ b/apps/provisioning_api/lib/Controller/UsersController.php @@ -94,7 +94,7 @@ class UsersController extends AUserData { * * 200: Users returned */ - public function getUsers(string $search = '', ?int $limit = null, int $offset = 0, string $orderBy = 'lastLogin', string $sort = 'DESC'): DataResponse { + public function getUsers(string $search = '', ?int $limit = null, int $offset = 0, string $sortMode = 'uid', string $sortOrder = 'asc'): DataResponse { $user = $this->userSession->getUser(); $users = []; @@ -102,7 +102,7 @@ class UsersController extends AUserData { $uid = $user->getUID(); $subAdminManager = $this->groupManager->getSubAdmin(); if ($this->groupManager->isAdmin($uid)) { - $users = $this->userManager->search($search, $limit, $offset, $orderBy, $sort); + $users = $this->userManager->search($search, $limit, $offset, $sortMode, $sortOrder); } elseif ($subAdminManager->isSubAdmin($user)) { $subAdminOfGroups = $subAdminManager->getSubAdminsGroups($user); foreach ($subAdminOfGroups as $key => $group) { @@ -131,13 +131,13 @@ class UsersController extends AUserData { * @param string $search Text to search for * @param int|null $limit Limit the amount of groups returned * @param int $offset Offset for searching for groups - * @param string $orderBy Field to order the results with - * @param string $sort ASC or DESC + * @param string $sortMode Field to order the results with + * @param string $sortOrder asc or desc * @return DataResponse}, array{}> * * 200: Users details returned */ - public function getUsersDetails(string $search = '', ?int $limit = null, int $offset = 0, string $orderBy = 'lastLogin', string $sort = 'DESC'): DataResponse { + public function getUsersDetails(string $search = '', ?int $limit = null, int $offset = 0, string $sortMode = 'uid', string $sortOrder = 'asc'): DataResponse { $currentUser = $this->userSession->getUser(); $users = []; @@ -145,7 +145,7 @@ class UsersController extends AUserData { $uid = $currentUser->getUID(); $subAdminManager = $this->groupManager->getSubAdmin(); if ($this->groupManager->isAdmin($uid)) { - $users = $this->userManager->search($search, $limit, $offset, $orderBy, $sort); + $users = $this->userManager->search($search, $limit, $offset, $sortMode, $sortOrder); $users = array_keys($users); } elseif ($subAdminManager->isSubAdmin($currentUser)) { $subAdminOfGroups = $subAdminManager->getSubAdminsGroups($currentUser); @@ -155,7 +155,7 @@ class UsersController extends AUserData { $users = []; foreach ($subAdminOfGroups as $group) { - $users[] = array_keys($this->groupManager->displayNamesInGroup($group, $search, $limit, $offset, $orderBy, $sort)); + $users[] = array_keys($this->groupManager->displayNamesInGroup($group, $search, $limit, $offset, $sortMode, $sortOrder)); } $users = array_merge(...$users); } diff --git a/lib/private/Group/Manager.php b/lib/private/Group/Manager.php index df4aa67cba4..362d7424e45 100644 --- a/lib/private/Group/Manager.php +++ b/lib/private/Group/Manager.php @@ -401,7 +401,7 @@ class Manager extends PublicEmitter implements IGroupManager { * @param int $offset * @return array an array of display names (value) and user ids (key) */ - public function displayNamesInGroup($gid, $search = '', $limit = -1, $offset = 0, $orderBy = 'uid', $sort = 'ASC') { + public function displayNamesInGroup($gid, $search = '', $limit = -1, $offset = 0, $sortMode = 'uid', $sortOrder = 'asc') { $group = $this->get($gid); if (is_null($group)) { return []; @@ -419,7 +419,7 @@ class Manager extends PublicEmitter implements IGroupManager { } do { - $filteredUsers = $this->userManager->searchDisplayName($search, $searchLimit, $searchOffset, $orderBy, $sort); + $filteredUsers = $this->userManager->searchDisplayName($search, $searchLimit, $searchOffset, $sortMode, $sortOrder); foreach ($filteredUsers as $filteredUser) { if ($group->inGroup($filteredUser)) { $groupUsers[] = $filteredUser; diff --git a/lib/private/User/Backend.php b/lib/private/User/Backend.php index d58092feac1..5d06b54c28b 100644 --- a/lib/private/User/Backend.php +++ b/lib/private/User/Backend.php @@ -89,11 +89,11 @@ abstract class Backend implements UserInterface { * @param string $search * @param null|int $limit * @param null|int $offset - * @param string $orderBy - * @param string $sort + * @param string $sortMode + * @param string $sortOrder * @return string[] an array of all uids */ - public function getUsers($search = '', $limit = null, $offset = null, $orderBy = 'lastLogin', $sort = 'DESC') { + public function getUsers($search = '', $limit = null, $offset = null, string $sortMode = 'uid', string $sortOrder = 'asc') { return []; } @@ -130,11 +130,11 @@ abstract class Backend implements UserInterface { * @param string $search * @param int|null $limit * @param int|null $offset - * @param string $orderBy - * @param string $sort + * @param string $sortMode + * @param string $sortOrder * @return array an array of all displayNames (value) and the corresponding uids (key) */ - public function getDisplayNames($search = '', $limit = null, $offset = null, string $orderBy = 'lastLogin', string $sort = 'DESC'): array { + public function getDisplayNames($search = '', $limit = null, $offset = null, string $sortMode = 'uid', string $sortOrder = 'asc'): array { $displayNames = []; $users = $this->getUsers($search, $limit, $offset); foreach ($users as $user) { diff --git a/lib/private/User/Database.php b/lib/private/User/Database.php index 6a1861e5dba..9a62bcf3e12 100644 --- a/lib/private/User/Database.php +++ b/lib/private/User/Database.php @@ -227,36 +227,43 @@ class Database extends ABackend implements * @param string $search * @param int|null $limit * @param int|null $offset - * @param string $orderBy - * @param string $sort + * @param string $sortMode + * @param string $sortOrder * @return array an array of all displayNames (value) and the corresponding uids (key) */ - public function getDisplayNames($search = '', $limit = null, $offset = null, string $orderBy = 'lastLogin', string $sort = 'DESC'): array { + public function getDisplayNames($search = '', $limit = null, $offset = null, string $sortMode = 'uid', string $sortOrder = 'asc'): array { $limit = $this->fixLimit($limit); $this->fixDI(); $query = $this->dbConn->getQueryBuilder(); - $appId = 'settings'; - $configKey = 'email'; - if($orderBy == 'lastLogin') { - $appId = 'login'; - $configKey = 'lastLogin'; + if ($sortMode === 'lastLogin') { + $lastLoginSubSelect = $this->dbConn->getQueryBuilder(); + $lastLoginSubSelect->select('configvalue') + ->from('preferences', 'p2') + ->where($lastLoginSubSelect->expr()->andX( + $lastLoginSubSelect->expr()->eq('p2.userid', 'uid'), + $lastLoginSubSelect->expr()->eq('p2.appid', $lastLoginSubSelect->expr()->literal('login')), + $lastLoginSubSelect->expr()->eq('p2.configkey', $lastLoginSubSelect->expr()->literal('lastLogin')), + )); + $orderByExpression = $query->createFunction('(' . $lastLoginSubSelect->getSQL() .')'); + } else { + $orderByExpression = $query->func()->lower('displayname'); } - $query->select('uid', 'displayname') + $query->select('uid', 'displayname', $orderByExpression) ->from($this->table, 'u') ->leftJoin('u', 'preferences', 'p', $query->expr()->andX( $query->expr()->eq('userid', 'uid'), - $query->expr()->eq('appid', $query->expr()->literal($appId)), - $query->expr()->eq('configkey', $query->expr()->literal($configKey))) + $query->expr()->eq('appid', $query->expr()->literal('settings')), + $query->expr()->eq('configkey', $query->expr()->literal('email'))) ) // sqlite doesn't like re-using a single named parameter here ->where($query->expr()->iLike('uid', $query->createPositionalParameter('%' . $this->dbConn->escapeLikeParameter($search) . '%'))) ->orWhere($query->expr()->iLike('displayname', $query->createPositionalParameter('%' . $this->dbConn->escapeLikeParameter($search) . '%'))) ->orWhere($query->expr()->iLike('configvalue', $query->createPositionalParameter('%' . $this->dbConn->escapeLikeParameter($search) . '%'))) - ->orderBy($query->func()->lower('configvalue'), $sort) + ->orderBy($orderByExpression, $sortOrder) ->addOrderBy('uid_lower', 'ASC') ->setMaxResults($limit) ->setFirstResult($offset); @@ -394,11 +401,9 @@ class Database extends ABackend implements $limit = $this->fixLimit($limit); $users = $this->getDisplayNames($search, $limit, $offset, $orderBy, $sort); - $userIds = array_map(function ($uid) { + return array_map(function ($uid) { return (string)$uid; }, array_keys($users)); - sort($userIds, SORT_STRING | SORT_FLAG_CASE); - return $userIds; } /** diff --git a/lib/private/User/Manager.php b/lib/private/User/Manager.php index b28adb39774..49f96c25a05 100644 --- a/lib/private/User/Manager.php +++ b/lib/private/User/Manager.php @@ -262,38 +262,38 @@ class Manager extends PublicEmitter implements IUserManager { * @return IUser[] * @deprecated since 27.0.0, use searchDisplayName instead */ - public function search($pattern, $limit = null, $offset = null, $orderBy = 'uid', $sort = 'ASC'): array { + public function search($pattern, $limit = null, $offset = null, $sortMode = 'uid', $sortOrder = 'asc'): array { $users = []; foreach ($this->backends as $backend) { - $backendUsers = $backend->getUsers($pattern, $limit, $offset, $orderBy, $sort); + $backendUsers = $backend->getUsers($pattern, $limit, $offset, $sortMode, $sortOrder); if (is_array($backendUsers)) { foreach ($backendUsers as $uid) { $users[$uid] = new LazyUser($uid, $this, null, $backend); } } } - switch ($orderBy.' '.$sort) { - case 'uid DESC': + switch ($sortMode.' '.$sortOrder) { + case 'uid desc': uasort($users, function (IUser $a, IUser $b) { return strcasecmp($b->getUID(), $a->getUID()); }); break; - case 'lastLogin ASC': + case 'lastLogin asc': uasort($users, function (IUser $a, IUser $b) { return $a->getLastLogin() - $b->getLastLogin(); }); break; - case 'lastLogin DESC': + case 'lastLogin desc': uasort($users, function (IUser $a, IUser $b) { return $b->getLastLogin() - $a->getLastLogin(); }); break; - case 'displayName ASC': + case 'displayName asc': uasort($users, function (IUser $a, IUser $b) { return strcasecmp($a->getDisplayName(), $b->getDisplayName()); }); break; - case 'displayName DESC': + case 'displayName desc': uasort($users, function (IUser $a, IUser $b) { return strcasecmp($b->getDisplayName(), $a->getDisplayName()); }); @@ -316,7 +316,7 @@ class Manager extends PublicEmitter implements IUserManager { * @param int $offset * @return IUser[] */ - public function searchDisplayName($pattern, $limit = null, $offset = null, $orderBy = 'displayName', $sort = 'ASC') { + public function searchDisplayName($pattern, $limit = null, $offset = null, $sortMode = 'uid', $sortOrder = 'asc') { $users = []; foreach ($this->backends as $backend) { $backendUsers = $backend->getDisplayNames($pattern, $limit, $offset); @@ -327,28 +327,28 @@ class Manager extends PublicEmitter implements IUserManager { } } - switch ($orderBy.' '.$sort) { - case 'uid ASC': + switch ($sortMode.' '.$sortOrder) { + case 'uid asc': uasort($users, function (IUser $a, IUser $b) { return strcasecmp($a->getUID(), $b->getUID()); }); break; - case 'uid DESC': + case 'uid desc': uasort($users, function (IUser $a, IUser $b) { return strcasecmp($b->getUID(), $a->getUID()); }); break; - case 'lastLogin ASC': + case 'lastLogin asc': uasort($users, function (IUser $a, IUser $b) { return $a->getLastLogin() - $b->getLastLogin(); }); break; - case 'lastLogin DESC': + case 'lastLogin desc': uasort($users, function (IUser $a, IUser $b) { return $b->getLastLogin() - $a->getLastLogin(); }); break; - case 'displayName DESC': + case 'displayName asc': uasort($users, function (IUser $a, IUser $b) { return strcasecmp($b->getDisplayName(), $a->getDisplayName()); }); diff --git a/lib/public/IUserManager.php b/lib/public/IUserManager.php index 89cd1f71899..b4fb265f6eb 100644 --- a/lib/public/IUserManager.php +++ b/lib/public/IUserManager.php @@ -104,7 +104,7 @@ interface IUserManager { * @return \OCP\IUser[] * @since 8.0.0 */ - public function search($pattern, $limit = null, $offset = null, $orderBy = 'uid', $sort = 'ASC'); + public function search($pattern, $limit = null, $offset = null, $sortMode = 'uid', $sortOrder = 'asc'); /** * search by displayName diff --git a/lib/public/UserInterface.php b/lib/public/UserInterface.php index 765da3a87a2..a28e9ffe726 100644 --- a/lib/public/UserInterface.php +++ b/lib/public/UserInterface.php @@ -45,7 +45,7 @@ interface UserInterface { * @return string[] an array of all uids * @since 4.5.0 */ - public function getUsers($search = '', $limit = null, $offset = null, $orderBy = 'lastLogin', $sort = 'DESC'); + public function getUsers($search = '', $limit = null, $offset = null, string $sortMode = 'uid', string $sortOrder = 'asc'); /** * check if a user exists @@ -69,12 +69,12 @@ interface UserInterface { * @param string $search * @param int|null $limit * @param int|null $offset - * @param string $orderBy - * @param string $sort + * @param string $sortMode + * @param string $sortOrder * @return array an array of all displayNames (value) and the corresponding uids (key) * @since 4.5.0 */ - public function getDisplayNames($search = '', $limit = null, $offset = null, string $orderBy = 'lastLogin', string $sort = 'DESC'); + public function getDisplayNames($search = '', $limit = null, $offset = null, string $sortMode = 'uid', string $sortOrder = 'asc'); /** * Check if a user list is available or not -- cgit v1.2.3 From 4cb85f7c9e37af742d170373602709f8db2d525d Mon Sep 17 00:00:00 2001 From: yemkareems Date: Thu, 6 Jun 2024 16:35:44 +0530 Subject: fix: rebased the branch with master and resolved conflicts fix: added a new endpoint users/recent and getting users based on last login info in the same. Reverted old code that was breaking LDAP Signed-off-by: yemkareems --- apps/provisioning_api/appinfo/routes.php | 1 + .../lib/Controller/UsersController.php | 102 +++++++++++++++++++-- lib/private/AllConfig.php | 43 +++++++++ lib/private/Group/Manager.php | 4 +- lib/private/User/Backend.php | 8 +- lib/private/User/Database.php | 30 ++---- lib/private/User/Manager.php | 27 ++++++ lib/public/IConfig.php | 2 + lib/public/IUserManager.php | 1 + lib/public/UserInterface.php | 6 +- 10 files changed, 183 insertions(+), 41 deletions(-) diff --git a/apps/provisioning_api/appinfo/routes.php b/apps/provisioning_api/appinfo/routes.php index b44685af175..78526ce6402 100644 --- a/apps/provisioning_api/appinfo/routes.php +++ b/apps/provisioning_api/appinfo/routes.php @@ -28,6 +28,7 @@ return [ ['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#getLastLoggedInUsers', 'url' => '/users/recent', '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 eced881516f..ec57d3e9b23 100644 --- a/apps/provisioning_api/lib/Controller/UsersController.php +++ b/apps/provisioning_api/lib/Controller/UsersController.php @@ -94,7 +94,7 @@ class UsersController extends AUserData { * * 200: Users returned */ - public function getUsers(string $search = '', ?int $limit = null, int $offset = 0, string $sortMode = 'uid', string $sortOrder = 'asc'): DataResponse { + public function getUsers(string $search = '', ?int $limit = null, int $offset = 0): DataResponse { $user = $this->userSession->getUser(); $users = []; @@ -102,7 +102,7 @@ class UsersController extends AUserData { $uid = $user->getUID(); $subAdminManager = $this->groupManager->getSubAdmin(); if ($this->groupManager->isAdmin($uid)) { - $users = $this->userManager->search($search, $limit, $offset, $sortMode, $sortOrder); + $users = $this->userManager->search($search, $limit, $offset); } elseif ($subAdminManager->isSubAdmin($user)) { $subAdminOfGroups = $subAdminManager->getSubAdminsGroups($user); foreach ($subAdminOfGroups as $key => $group) { @@ -131,13 +131,11 @@ class UsersController extends AUserData { * @param string $search Text to search for * @param int|null $limit Limit the amount of groups returned * @param int $offset Offset for searching for groups - * @param string $sortMode Field to order the results with - * @param string $sortOrder asc or desc * @return DataResponse}, array{}> * * 200: Users details returned */ - public function getUsersDetails(string $search = '', ?int $limit = null, int $offset = 0, string $sortMode = 'uid', string $sortOrder = 'asc'): DataResponse { + public function getUsersDetails(string $search = '', ?int $limit = null, int $offset = 0): DataResponse { $currentUser = $this->userSession->getUser(); $users = []; @@ -145,7 +143,7 @@ class UsersController extends AUserData { $uid = $currentUser->getUID(); $subAdminManager = $this->groupManager->getSubAdmin(); if ($this->groupManager->isAdmin($uid)) { - $users = $this->userManager->search($search, $limit, $offset, $sortMode, $sortOrder); + $users = $this->userManager->search($search, $limit, $offset); $users = array_keys($users); } elseif ($subAdminManager->isSubAdmin($currentUser)) { $subAdminOfGroups = $subAdminManager->getSubAdminsGroups($currentUser); @@ -155,7 +153,7 @@ class UsersController extends AUserData { $users = []; foreach ($subAdminOfGroups as $group) { - $users[] = array_keys($this->groupManager->displayNamesInGroup($group, $search, $limit, $offset, $sortMode, $sortOrder)); + $users[] = array_keys($this->groupManager->displayNamesInGroup($group, $search, $limit, $offset)); } $users = array_merge(...$users); } @@ -267,6 +265,96 @@ class UsersController extends AUserData { ]); } + /** + * @NoAdminRequired + * @NoCSRFRequired + * + * Get the list of disabled users and their details + * + * @param string $search Text to search for + * @param ?int $limit Limit the amount of users returned + * @param int $offset Offset + * @param string $sortMode Field to order the results with + * @param string $sortOrder asc or desc + * @return DataResponse}, array{}> + * + * 200: Users details returned based on last logged in information + */ + public function getLastLoggedInUsers(string $search = '', + ?int $limit = null, + int $offset = 0, + string $sortMode = 'lastLogin', + string $sortOrder = 'desc' + ): DataResponse { + $currentUser = $this->userSession->getUser(); + if ($currentUser === null) { + return new DataResponse(['users' => []]); + } + if ($limit !== null && $limit < 0) { + throw new InvalidArgumentException("Invalid limit value: $limit"); + } + if ($offset < 0) { + throw new InvalidArgumentException("Invalid offset value: $offset"); + } + + $users = []; + + // Admin? Or SubAdmin? + $uid = $currentUser->getUID(); + $subAdminManager = $this->groupManager->getSubAdmin(); + if ($this->groupManager->isAdmin($uid)) { + $users = $this->userManager->getUsersSortedByLastLogin($limit, $offset, $search, $sortMode, $sortOrder); + $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($search, ($tempLimit === null ? null : $tempLimit - count($users))), + fn (IUser $user): bool => !$user->isEnabled() + ) + ) + ); + if (($tempLimit !== null) && (count($users) >= $tempLimit)) { + break; + } + } + $users = array_slice($users, $offset); + } + + $usersDetails = []; + foreach ($users as $userId) { + try { + $userData = $this->getUserData($userId); + } catch (OCSNotFoundException $e) { + // We still want to return all other accounts, but this one was removed from the backends + // yet they are still in our database. Might be a LDAP remnant. + $userData = null; + $this->logger->warning('Found one disabled account that was removed from its backend, but still exists in Nextcloud database', ['accountId' => $userId]); + } + // Do not insert empty entry + if ($userData !== null) { + $usersDetails[$userId] = $userData; + } else { + // Currently logged in user does not have permissions to see this user + // only showing its id + $usersDetails[$userId] = ['id' => $userId]; + } + } + + return new DataResponse([ + 'users' => $usersDetails + ]); + } + + /** * @NoAdminRequired diff --git a/lib/private/AllConfig.php b/lib/private/AllConfig.php index d05fe440202..7fbc4c1e148 100644 --- a/lib/private/AllConfig.php +++ b/lib/private/AllConfig.php @@ -491,6 +491,49 @@ class AllConfig implements IConfig { return $userIDs; } + public function getLastLoggedInUsers($search, $sortMode, $sortOrder): array { + // TODO - FIXME + $this->fixDIInit(); + + $query = $this->connection->getQueryBuilder(); + + if ($sortMode === 'lastLogin') { + $lastLoginSubSelect = $this->connection->getQueryBuilder(); + $lastLoginSubSelect->select('configvalue') + ->from('preferences', 'p2') + ->where($lastLoginSubSelect->expr()->andX( + $lastLoginSubSelect->expr()->eq('p2.userid', 'uid'), + $lastLoginSubSelect->expr()->eq('p2.appid', $lastLoginSubSelect->expr()->literal('login')), + $lastLoginSubSelect->expr()->eq('p2.configkey', $lastLoginSubSelect->expr()->literal('lastLogin')), + )); + $orderByExpression = $query->createFunction('(' . $lastLoginSubSelect->getSQL() .')'); + } else { + $orderByExpression = $query->func()->lower('displayname'); + } + + $query->select('uid', 'displayname', $orderByExpression) + ->from('users', 'u') + ->leftJoin('u', 'preferences', 'p', $query->expr()->andX( + $query->expr()->eq('userid', 'uid'), + $query->expr()->eq('appid', $query->expr()->literal('settings')), + $query->expr()->eq('configkey', $query->expr()->literal('email'))) + ) + // sqlite doesn't like re-using a single named parameter here + ->where($query->expr()->iLike('uid', $query->createPositionalParameter('%' . $this->connection->escapeLikeParameter($search) . '%'))) + ->orWhere($query->expr()->iLike('displayname', $query->createPositionalParameter('%' . $this->connection->escapeLikeParameter($search) . '%'))) + ->orWhere($query->expr()->iLike('configvalue', $query->createPositionalParameter('%' . $this->connection->escapeLikeParameter($search) . '%'))) + ->orderBy($orderByExpression, $sortOrder) + ->addOrderBy('uid_lower', 'ASC'); + + $result = $query->executeQuery(); + $displayNames = []; + while ($row = $result->fetch()) { + $displayNames[(string)$row['uid']] = (string)$row['uid']; + } + + return $displayNames; + } + /** * Determines the users that have the given value set for a specific app-key-pair * diff --git a/lib/private/Group/Manager.php b/lib/private/Group/Manager.php index 362d7424e45..0ab64907c8b 100644 --- a/lib/private/Group/Manager.php +++ b/lib/private/Group/Manager.php @@ -401,7 +401,7 @@ class Manager extends PublicEmitter implements IGroupManager { * @param int $offset * @return array an array of display names (value) and user ids (key) */ - public function displayNamesInGroup($gid, $search = '', $limit = -1, $offset = 0, $sortMode = 'uid', $sortOrder = 'asc') { + public function displayNamesInGroup($gid, $search = '', $limit = -1, $offset = 0) { $group = $this->get($gid); if (is_null($group)) { return []; @@ -419,7 +419,7 @@ class Manager extends PublicEmitter implements IGroupManager { } do { - $filteredUsers = $this->userManager->searchDisplayName($search, $searchLimit, $searchOffset, $sortMode, $sortOrder); + $filteredUsers = $this->userManager->searchDisplayName($search, $searchLimit, $searchOffset); foreach ($filteredUsers as $filteredUser) { if ($group->inGroup($filteredUser)) { $groupUsers[] = $filteredUser; diff --git a/lib/private/User/Backend.php b/lib/private/User/Backend.php index 5d06b54c28b..98b291e5dee 100644 --- a/lib/private/User/Backend.php +++ b/lib/private/User/Backend.php @@ -89,11 +89,9 @@ abstract class Backend implements UserInterface { * @param string $search * @param null|int $limit * @param null|int $offset - * @param string $sortMode - * @param string $sortOrder * @return string[] an array of all uids */ - public function getUsers($search = '', $limit = null, $offset = null, string $sortMode = 'uid', string $sortOrder = 'asc') { + public function getUsers($search = '', $limit = null, $offset = null) { return []; } @@ -130,11 +128,9 @@ abstract class Backend implements UserInterface { * @param string $search * @param int|null $limit * @param int|null $offset - * @param string $sortMode - * @param string $sortOrder * @return array an array of all displayNames (value) and the corresponding uids (key) */ - public function getDisplayNames($search = '', $limit = null, $offset = null, string $sortMode = 'uid', string $sortOrder = 'asc'): array { + public function getDisplayNames($search = '', $limit = null, $offset = null) { $displayNames = []; $users = $this->getUsers($search, $limit, $offset); foreach ($users as $user) { diff --git a/lib/private/User/Database.php b/lib/private/User/Database.php index 9a62bcf3e12..cc7050f2da8 100644 --- a/lib/private/User/Database.php +++ b/lib/private/User/Database.php @@ -227,32 +227,16 @@ class Database extends ABackend implements * @param string $search * @param int|null $limit * @param int|null $offset - * @param string $sortMode - * @param string $sortOrder * @return array an array of all displayNames (value) and the corresponding uids (key) */ - public function getDisplayNames($search = '', $limit = null, $offset = null, string $sortMode = 'uid', string $sortOrder = 'asc'): array { + public function getDisplayNames($search = '', $limit = null, $offset = null) { $limit = $this->fixLimit($limit); $this->fixDI(); $query = $this->dbConn->getQueryBuilder(); - if ($sortMode === 'lastLogin') { - $lastLoginSubSelect = $this->dbConn->getQueryBuilder(); - $lastLoginSubSelect->select('configvalue') - ->from('preferences', 'p2') - ->where($lastLoginSubSelect->expr()->andX( - $lastLoginSubSelect->expr()->eq('p2.userid', 'uid'), - $lastLoginSubSelect->expr()->eq('p2.appid', $lastLoginSubSelect->expr()->literal('login')), - $lastLoginSubSelect->expr()->eq('p2.configkey', $lastLoginSubSelect->expr()->literal('lastLogin')), - )); - $orderByExpression = $query->createFunction('(' . $lastLoginSubSelect->getSQL() .')'); - } else { - $orderByExpression = $query->func()->lower('displayname'); - } - - $query->select('uid', 'displayname', $orderByExpression) + $query->select('uid', 'displayname') ->from($this->table, 'u') ->leftJoin('u', 'preferences', 'p', $query->expr()->andX( $query->expr()->eq('userid', 'uid'), @@ -263,7 +247,7 @@ class Database extends ABackend implements ->where($query->expr()->iLike('uid', $query->createPositionalParameter('%' . $this->dbConn->escapeLikeParameter($search) . '%'))) ->orWhere($query->expr()->iLike('displayname', $query->createPositionalParameter('%' . $this->dbConn->escapeLikeParameter($search) . '%'))) ->orWhere($query->expr()->iLike('configvalue', $query->createPositionalParameter('%' . $this->dbConn->escapeLikeParameter($search) . '%'))) - ->orderBy($orderByExpression, $sortOrder) + ->orderBy($query->func()->lower('displayname'), 'ASC') ->addOrderBy('uid_lower', 'ASC') ->setMaxResults($limit) ->setFirstResult($offset); @@ -397,13 +381,15 @@ class Database extends ABackend implements * @param null|int $offset * @return string[] an array of all uids */ - public function getUsers($search = '', $limit = null, $offset = null, $orderBy = 'lastLogin', $sort = 'DESC'): array { + public function getUsers($search = '', $limit = null, $offset = null) { $limit = $this->fixLimit($limit); - $users = $this->getDisplayNames($search, $limit, $offset, $orderBy, $sort); - return array_map(function ($uid) { + $users = $this->getDisplayNames($search, $limit, $offset); + $userIds = array_map(function ($uid) { return (string)$uid; }, array_keys($users)); + sort($userIds, SORT_STRING | SORT_FLAG_CASE); + return $userIds; } /** diff --git a/lib/private/User/Manager.php b/lib/private/User/Manager.php index 49f96c25a05..2efb93e65be 100644 --- a/lib/private/User/Manager.php +++ b/lib/private/User/Manager.php @@ -402,6 +402,33 @@ class Manager extends PublicEmitter implements IUserManager { return array_slice($users, $offset, $limit); } + public function getUsersSortedByLastLogin(?int $limit = null, int $offset = 0, $search = '', $sortMode = 'lastLogin', $sortOrder = 'desc'): array { + $users = $this->config->getLastLoggedInUsers($search, $sortMode, $sortOrder); + $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/IConfig.php b/lib/public/IConfig.php index b7feabd0ef5..39f9ecff94c 100644 --- a/lib/public/IConfig.php +++ b/lib/public/IConfig.php @@ -249,4 +249,6 @@ interface IConfig { * @since 8.0.0 */ public function getUsersForUserValue($appName, $key, $value); + + public function getLastLoggedInUsers($search, $sortMode, $sortOrder); } diff --git a/lib/public/IUserManager.php b/lib/public/IUserManager.php index b4fb265f6eb..70420dc7c7a 100644 --- a/lib/public/IUserManager.php +++ b/lib/public/IUserManager.php @@ -124,6 +124,7 @@ interface IUserManager { */ public function getDisabledUsers(?int $limit = null, int $offset = 0, string $search = ''): array; + public function getUsersSortedByLastLogin(?int $limit = null, int $offset = 0, $search = '', $sortMode = 'lastLogin', $sortOrder = 'desc'): array; /** * Search known users (from phonebook sync) by displayName * diff --git a/lib/public/UserInterface.php b/lib/public/UserInterface.php index a28e9ffe726..34e7a09feb7 100644 --- a/lib/public/UserInterface.php +++ b/lib/public/UserInterface.php @@ -45,7 +45,7 @@ interface UserInterface { * @return string[] an array of all uids * @since 4.5.0 */ - public function getUsers($search = '', $limit = null, $offset = null, string $sortMode = 'uid', string $sortOrder = 'asc'); + public function getUsers($search = '', $limit = null, $offset = null); /** * check if a user exists @@ -69,12 +69,10 @@ interface UserInterface { * @param string $search * @param int|null $limit * @param int|null $offset - * @param string $sortMode - * @param string $sortOrder * @return array an array of all displayNames (value) and the corresponding uids (key) * @since 4.5.0 */ - public function getDisplayNames($search = '', $limit = null, $offset = null, string $sortMode = 'uid', string $sortOrder = 'asc'); + public function getDisplayNames($search = '', $limit = null, $offset = null); /** * Check if a user list is available or not -- cgit v1.2.3 From 3615b1f9280bd55fddfc26af2ad45cdd7e7ddf3d Mon Sep 17 00:00:00 2001 From: yemkareems Date: Wed, 26 Jun 2024 13:13:47 +0530 Subject: fix: removed csrf check for the recent end point and ran cs fix Signed-off-by: yemkareems --- apps/provisioning_api/lib/Controller/UsersController.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/apps/provisioning_api/lib/Controller/UsersController.php b/apps/provisioning_api/lib/Controller/UsersController.php index ec57d3e9b23..a68bcfa6b29 100644 --- a/apps/provisioning_api/lib/Controller/UsersController.php +++ b/apps/provisioning_api/lib/Controller/UsersController.php @@ -267,7 +267,6 @@ class UsersController extends AUserData { /** * @NoAdminRequired - * @NoCSRFRequired * * Get the list of disabled users and their details * @@ -281,10 +280,10 @@ class UsersController extends AUserData { * 200: Users details returned based on last logged in information */ public function getLastLoggedInUsers(string $search = '', - ?int $limit = null, - int $offset = 0, - string $sortMode = 'lastLogin', - string $sortOrder = 'desc' + ?int $limit = null, + int $offset = 0, + string $sortMode = 'lastLogin', + string $sortOrder = 'desc' ): DataResponse { $currentUser = $this->userSession->getUser(); if ($currentUser === null) { -- cgit v1.2.3 From dc6e8c9c0ab272eb802975674538eed8466f4aa9 Mon Sep 17 00:00:00 2001 From: yemkareems Date: Wed, 26 Jun 2024 13:23:22 +0530 Subject: fix: search and searchDisplayNames reverted to how it was initially as sort and order are not required here Signed-off-by: yemkareems --- lib/private/User/Manager.php | 77 ++++++-------------------------------------- lib/public/IUserManager.php | 2 +- 2 files changed, 10 insertions(+), 69 deletions(-) diff --git a/lib/private/User/Manager.php b/lib/private/User/Manager.php index 2efb93e65be..08ca8a13943 100644 --- a/lib/private/User/Manager.php +++ b/lib/private/User/Manager.php @@ -262,48 +262,19 @@ class Manager extends PublicEmitter implements IUserManager { * @return IUser[] * @deprecated since 27.0.0, use searchDisplayName instead */ - public function search($pattern, $limit = null, $offset = null, $sortMode = 'uid', $sortOrder = 'asc'): array { + public function search($pattern, $limit = null, $offset = null) { $users = []; foreach ($this->backends as $backend) { - $backendUsers = $backend->getUsers($pattern, $limit, $offset, $sortMode, $sortOrder); + $backendUsers = $backend->getUsers($pattern, $limit, $offset); if (is_array($backendUsers)) { foreach ($backendUsers as $uid) { $users[$uid] = new LazyUser($uid, $this, null, $backend); } } } - switch ($sortMode.' '.$sortOrder) { - case 'uid desc': - uasort($users, function (IUser $a, IUser $b) { - return strcasecmp($b->getUID(), $a->getUID()); - }); - break; - case 'lastLogin asc': - uasort($users, function (IUser $a, IUser $b) { - return $a->getLastLogin() - $b->getLastLogin(); - }); - break; - case 'lastLogin desc': - uasort($users, function (IUser $a, IUser $b) { - return $b->getLastLogin() - $a->getLastLogin(); - }); - break; - case 'displayName asc': - uasort($users, function (IUser $a, IUser $b) { - return strcasecmp($a->getDisplayName(), $b->getDisplayName()); - }); - break; - case 'displayName desc': - uasort($users, function (IUser $a, IUser $b) { - return strcasecmp($b->getDisplayName(), $a->getDisplayName()); - }); - break; - default: - uasort($users, function (IUser $a, IUser $b) { - return strcasecmp($a->getUID(), $b->getUID()); - }); - break; - } + uasort($users, function (IUser $a, IUser $b) { + return strcasecmp($a->getUID(), $b->getUID()); + }); return $users; } @@ -316,7 +287,7 @@ class Manager extends PublicEmitter implements IUserManager { * @param int $offset * @return IUser[] */ - public function searchDisplayName($pattern, $limit = null, $offset = null, $sortMode = 'uid', $sortOrder = 'asc') { + public function searchDisplayName($pattern, $limit = null, $offset = null) { $users = []; foreach ($this->backends as $backend) { $backendUsers = $backend->getDisplayNames($pattern, $limit, $offset); @@ -327,39 +298,9 @@ class Manager extends PublicEmitter implements IUserManager { } } - switch ($sortMode.' '.$sortOrder) { - case 'uid asc': - uasort($users, function (IUser $a, IUser $b) { - return strcasecmp($a->getUID(), $b->getUID()); - }); - break; - case 'uid desc': - uasort($users, function (IUser $a, IUser $b) { - return strcasecmp($b->getUID(), $a->getUID()); - }); - break; - case 'lastLogin asc': - uasort($users, function (IUser $a, IUser $b) { - return $a->getLastLogin() - $b->getLastLogin(); - }); - break; - case 'lastLogin desc': - uasort($users, function (IUser $a, IUser $b) { - return $b->getLastLogin() - $a->getLastLogin(); - }); - break; - case 'displayName asc': - uasort($users, function (IUser $a, IUser $b) { - return strcasecmp($b->getDisplayName(), $a->getDisplayName()); - }); - break; - default: - uasort($users, function (IUser $a, IUser $b) { - return strcasecmp($a->getDisplayName(), $b->getDisplayName()); - }); - break; - } - + usort($users, function (IUser $a, IUser $b) { + return strcasecmp($a->getDisplayName(), $b->getDisplayName()); + }); return $users; } diff --git a/lib/public/IUserManager.php b/lib/public/IUserManager.php index 70420dc7c7a..83422c51dfc 100644 --- a/lib/public/IUserManager.php +++ b/lib/public/IUserManager.php @@ -104,7 +104,7 @@ interface IUserManager { * @return \OCP\IUser[] * @since 8.0.0 */ - public function search($pattern, $limit = null, $offset = null, $sortMode = 'uid', $sortOrder = 'asc'); + public function search($pattern, $limit = null, $offset = null); /** * search by displayName -- cgit v1.2.3 From 695bd042d7c447a6ba040bee4ab45bbb3e8122ca Mon Sep 17 00:00:00 2001 From: yemkareems Date: Wed, 26 Jun 2024 13:27:52 +0530 Subject: fix: search and searchDisplayNames reverted to how it was initially as sort and order are not required here Signed-off-by: yemkareems --- lib/private/User/Manager.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/private/User/Manager.php b/lib/private/User/Manager.php index 08ca8a13943..3c2fd5b5098 100644 --- a/lib/private/User/Manager.php +++ b/lib/private/User/Manager.php @@ -272,10 +272,10 @@ class Manager extends PublicEmitter implements IUserManager { } } } + uasort($users, function (IUser $a, IUser $b) { return strcasecmp($a->getUID(), $b->getUID()); }); - return $users; } @@ -301,7 +301,6 @@ class Manager extends PublicEmitter implements IUserManager { usort($users, function (IUser $a, IUser $b) { return strcasecmp($a->getDisplayName(), $b->getDisplayName()); }); - return $users; } -- cgit v1.2.3 From 5b249df6866c3434740d08827eeabcf2cb6eb2e9 Mon Sep 17 00:00:00 2001 From: yemkareems Date: Wed, 26 Jun 2024 14:04:57 +0530 Subject: fix: doc blocks added Signed-off-by: yemkareems --- lib/private/AllConfig.php | 8 ++++++++ lib/private/User/Manager.php | 3 +++ lib/public/IConfig.php | 8 ++++++++ lib/public/IUserManager.php | 3 +++ 4 files changed, 22 insertions(+) diff --git a/lib/private/AllConfig.php b/lib/private/AllConfig.php index 7fbc4c1e148..a096fed61db 100644 --- a/lib/private/AllConfig.php +++ b/lib/private/AllConfig.php @@ -491,6 +491,14 @@ class AllConfig implements IConfig { return $userIDs; } + /** + * Gets the list of users based on their lastLogin info asc or desc + * + * @param string $search search users based on search params + * @param string $sortMode can be lastLogin or any key in preferences + * @param string $sortOrder asc or desc + * @return array of user IDs + */ public function getLastLoggedInUsers($search, $sortMode, $sortOrder): array { // TODO - FIXME $this->fixDIInit(); diff --git a/lib/private/User/Manager.php b/lib/private/User/Manager.php index 3c2fd5b5098..57dadfea194 100644 --- a/lib/private/User/Manager.php +++ b/lib/private/User/Manager.php @@ -342,6 +342,9 @@ class Manager extends PublicEmitter implements IUserManager { return array_slice($users, $offset, $limit); } + /** + * @return IUser[] + */ public function getUsersSortedByLastLogin(?int $limit = null, int $offset = 0, $search = '', $sortMode = 'lastLogin', $sortOrder = 'desc'): array { $users = $this->config->getLastLoggedInUsers($search, $sortMode, $sortOrder); $users = array_combine( diff --git a/lib/public/IConfig.php b/lib/public/IConfig.php index 39f9ecff94c..093c0ecbd37 100644 --- a/lib/public/IConfig.php +++ b/lib/public/IConfig.php @@ -250,5 +250,13 @@ interface IConfig { */ public function getUsersForUserValue($appName, $key, $value); + /** + * Gets the list of users based on their lastLogin info asc or desc + * + * @param string $search search users based on search params + * @param string $sortMode can be lastLogin or any key in preferences + * @param string $sortOrder asc or desc + * @return array of user IDs + */ public function getLastLoggedInUsers($search, $sortMode, $sortOrder); } diff --git a/lib/public/IUserManager.php b/lib/public/IUserManager.php index 83422c51dfc..e614619eec8 100644 --- a/lib/public/IUserManager.php +++ b/lib/public/IUserManager.php @@ -124,6 +124,9 @@ interface IUserManager { */ public function getDisabledUsers(?int $limit = null, int $offset = 0, string $search = ''): array; + /** + * @return IUser[] + */ public function getUsersSortedByLastLogin(?int $limit = null, int $offset = 0, $search = '', $sortMode = 'lastLogin', $sortOrder = 'desc'): array; /** * Search known users (from phonebook sync) by displayName -- cgit v1.2.3 From c701ef1ed5b75cf454a261fa2e74b98662b28b7b Mon Sep 17 00:00:00 2001 From: yemkareems Date: Wed, 26 Jun 2024 14:41:03 +0530 Subject: fix: since added to doc blocks Signed-off-by: yemkareems --- lib/public/IConfig.php | 1 + lib/public/IUserManager.php | 1 + 2 files changed, 2 insertions(+) diff --git a/lib/public/IConfig.php b/lib/public/IConfig.php index 093c0ecbd37..f8efd5c7e80 100644 --- a/lib/public/IConfig.php +++ b/lib/public/IConfig.php @@ -257,6 +257,7 @@ interface IConfig { * @param string $sortMode can be lastLogin or any key in preferences * @param string $sortOrder asc or desc * @return array of user IDs + * @since 30.0.0 */ public function getLastLoggedInUsers($search, $sortMode, $sortOrder); } diff --git a/lib/public/IUserManager.php b/lib/public/IUserManager.php index e614619eec8..5cf2aeef061 100644 --- a/lib/public/IUserManager.php +++ b/lib/public/IUserManager.php @@ -126,6 +126,7 @@ interface IUserManager { /** * @return IUser[] + * @since 30.0.0 */ public function getUsersSortedByLastLogin(?int $limit = null, int $offset = 0, $search = '', $sortMode = 'lastLogin', $sortOrder = 'desc'): array; /** -- cgit v1.2.3 From afa51365ffc6d514a96ea6af73e6079726033fb6 Mon Sep 17 00:00:00 2001 From: yemkareems Date: Tue, 2 Jul 2024 10:18:09 +0530 Subject: fix: removed the params related to sortMode and order since it sorts by lastLogin Signed-off-by: yemkareems --- .../lib/Controller/UsersController.php | 9 +++---- lib/private/AllConfig.php | 28 +++++++++------------- lib/private/User/Manager.php | 4 ++-- lib/public/IConfig.php | 4 +--- lib/public/IUserManager.php | 2 +- 5 files changed, 18 insertions(+), 29 deletions(-) diff --git a/apps/provisioning_api/lib/Controller/UsersController.php b/apps/provisioning_api/lib/Controller/UsersController.php index a68bcfa6b29..f494311923e 100644 --- a/apps/provisioning_api/lib/Controller/UsersController.php +++ b/apps/provisioning_api/lib/Controller/UsersController.php @@ -267,14 +267,13 @@ class UsersController extends AUserData { /** * @NoAdminRequired + * @NoCSRFRequired * - * Get the list of disabled users and their details + * Get the list of last logged-in users and their details * * @param string $search Text to search for * @param ?int $limit Limit the amount of users returned * @param int $offset Offset - * @param string $sortMode Field to order the results with - * @param string $sortOrder asc or desc * @return DataResponse}, array{}> * * 200: Users details returned based on last logged in information @@ -282,8 +281,6 @@ class UsersController extends AUserData { public function getLastLoggedInUsers(string $search = '', ?int $limit = null, int $offset = 0, - string $sortMode = 'lastLogin', - string $sortOrder = 'desc' ): DataResponse { $currentUser = $this->userSession->getUser(); if ($currentUser === null) { @@ -302,7 +299,7 @@ class UsersController extends AUserData { $uid = $currentUser->getUID(); $subAdminManager = $this->groupManager->getSubAdmin(); if ($this->groupManager->isAdmin($uid)) { - $users = $this->userManager->getUsersSortedByLastLogin($limit, $offset, $search, $sortMode, $sortOrder); + $users = $this->userManager->getUsersSortedByLastLogin($limit, $offset, $search); $users = array_map(fn (IUser $user): string => $user->getUID(), $users); } elseif ($subAdminManager->isSubAdmin($currentUser)) { $subAdminOfGroups = $subAdminManager->getSubAdminsGroups($currentUser); diff --git a/lib/private/AllConfig.php b/lib/private/AllConfig.php index a096fed61db..756ceabdbea 100644 --- a/lib/private/AllConfig.php +++ b/lib/private/AllConfig.php @@ -495,29 +495,23 @@ class AllConfig implements IConfig { * Gets the list of users based on their lastLogin info asc or desc * * @param string $search search users based on search params - * @param string $sortMode can be lastLogin or any key in preferences - * @param string $sortOrder asc or desc * @return array of user IDs */ - public function getLastLoggedInUsers($search, $sortMode, $sortOrder): array { + public function getLastLoggedInUsers($search): array { // TODO - FIXME $this->fixDIInit(); $query = $this->connection->getQueryBuilder(); - if ($sortMode === 'lastLogin') { - $lastLoginSubSelect = $this->connection->getQueryBuilder(); - $lastLoginSubSelect->select('configvalue') - ->from('preferences', 'p2') - ->where($lastLoginSubSelect->expr()->andX( - $lastLoginSubSelect->expr()->eq('p2.userid', 'uid'), - $lastLoginSubSelect->expr()->eq('p2.appid', $lastLoginSubSelect->expr()->literal('login')), - $lastLoginSubSelect->expr()->eq('p2.configkey', $lastLoginSubSelect->expr()->literal('lastLogin')), - )); - $orderByExpression = $query->createFunction('(' . $lastLoginSubSelect->getSQL() .')'); - } else { - $orderByExpression = $query->func()->lower('displayname'); - } + $lastLoginSubSelect = $this->connection->getQueryBuilder(); + $lastLoginSubSelect->select('configvalue') + ->from('preferences', 'p2') + ->where($lastLoginSubSelect->expr()->andX( + $lastLoginSubSelect->expr()->eq('p2.userid', 'uid'), + $lastLoginSubSelect->expr()->eq('p2.appid', $lastLoginSubSelect->expr()->literal('login')), + $lastLoginSubSelect->expr()->eq('p2.configkey', $lastLoginSubSelect->expr()->literal('lastLogin')), + )); + $orderByExpression = $query->createFunction('(' . $lastLoginSubSelect->getSQL() .')'); $query->select('uid', 'displayname', $orderByExpression) ->from('users', 'u') @@ -530,7 +524,7 @@ class AllConfig implements IConfig { ->where($query->expr()->iLike('uid', $query->createPositionalParameter('%' . $this->connection->escapeLikeParameter($search) . '%'))) ->orWhere($query->expr()->iLike('displayname', $query->createPositionalParameter('%' . $this->connection->escapeLikeParameter($search) . '%'))) ->orWhere($query->expr()->iLike('configvalue', $query->createPositionalParameter('%' . $this->connection->escapeLikeParameter($search) . '%'))) - ->orderBy($orderByExpression, $sortOrder) + ->orderBy($orderByExpression, 'DESC') ->addOrderBy('uid_lower', 'ASC'); $result = $query->executeQuery(); diff --git a/lib/private/User/Manager.php b/lib/private/User/Manager.php index 57dadfea194..0ae24397f5f 100644 --- a/lib/private/User/Manager.php +++ b/lib/private/User/Manager.php @@ -345,8 +345,8 @@ class Manager extends PublicEmitter implements IUserManager { /** * @return IUser[] */ - public function getUsersSortedByLastLogin(?int $limit = null, int $offset = 0, $search = '', $sortMode = 'lastLogin', $sortOrder = 'desc'): array { - $users = $this->config->getLastLoggedInUsers($search, $sortMode, $sortOrder); + public function getUsersSortedByLastLogin(?int $limit = null, int $offset = 0, $search = ''): array { + $users = $this->config->getLastLoggedInUsers($search); $users = array_combine( $users, array_map( diff --git a/lib/public/IConfig.php b/lib/public/IConfig.php index f8efd5c7e80..a91fe1e62b0 100644 --- a/lib/public/IConfig.php +++ b/lib/public/IConfig.php @@ -254,10 +254,8 @@ interface IConfig { * Gets the list of users based on their lastLogin info asc or desc * * @param string $search search users based on search params - * @param string $sortMode can be lastLogin or any key in preferences - * @param string $sortOrder asc or desc * @return array of user IDs * @since 30.0.0 */ - public function getLastLoggedInUsers($search, $sortMode, $sortOrder); + public function getLastLoggedInUsers($search); } diff --git a/lib/public/IUserManager.php b/lib/public/IUserManager.php index 5cf2aeef061..8b080fd75c5 100644 --- a/lib/public/IUserManager.php +++ b/lib/public/IUserManager.php @@ -128,7 +128,7 @@ interface IUserManager { * @return IUser[] * @since 30.0.0 */ - public function getUsersSortedByLastLogin(?int $limit = null, int $offset = 0, $search = '', $sortMode = 'lastLogin', $sortOrder = 'desc'): array; + public function getUsersSortedByLastLogin(?int $limit = null, int $offset = 0, $search = ''): array; /** * Search known users (from phonebook sync) by displayName * -- cgit v1.2.3 From 4c62f78a253c0dba05493bc6a325ab8c4083d65b Mon Sep 17 00:00:00 2001 From: yemkareems Date: Tue, 2 Jul 2024 10:20:25 +0530 Subject: fix: removed NoCSRFRequired used for testing locally Signed-off-by: yemkareems --- apps/provisioning_api/lib/Controller/UsersController.php | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/provisioning_api/lib/Controller/UsersController.php b/apps/provisioning_api/lib/Controller/UsersController.php index f494311923e..18c24f47cae 100644 --- a/apps/provisioning_api/lib/Controller/UsersController.php +++ b/apps/provisioning_api/lib/Controller/UsersController.php @@ -267,7 +267,6 @@ class UsersController extends AUserData { /** * @NoAdminRequired - * @NoCSRFRequired * * Get the list of last logged-in users and their details * -- cgit v1.2.3 From cfafbc84157a70557deca66e969b57912b66dc8f Mon Sep 17 00:00:00 2001 From: yemkareems Date: Thu, 4 Jul 2024 12:38:40 +0530 Subject: fix: removed references to old disabled users code. refactored query as per getDisplayNames function. limit and offset added to query. default limit set to 25. Signed-off-by: yemkareems --- .../lib/Controller/UsersController.php | 31 +++------------------- lib/private/AllConfig.php | 26 +++++++----------- lib/private/User/Manager.php | 21 +++------------ lib/public/IConfig.php | 4 ++- 4 files changed, 20 insertions(+), 62 deletions(-) diff --git a/apps/provisioning_api/lib/Controller/UsersController.php b/apps/provisioning_api/lib/Controller/UsersController.php index 18c24f47cae..beb240681d0 100644 --- a/apps/provisioning_api/lib/Controller/UsersController.php +++ b/apps/provisioning_api/lib/Controller/UsersController.php @@ -278,7 +278,7 @@ class UsersController extends AUserData { * 200: Users details returned based on last logged in information */ public function getLastLoggedInUsers(string $search = '', - ?int $limit = null, + ?int $limit = 25, int $offset = 0, ): DataResponse { $currentUser = $this->userSession->getUser(); @@ -294,34 +294,11 @@ class UsersController extends AUserData { $users = []; - // Admin? Or SubAdmin? + // For Admin alone user sorting based on lastLogin. For sub admin and groups this is not supported $uid = $currentUser->getUID(); - $subAdminManager = $this->groupManager->getSubAdmin(); if ($this->groupManager->isAdmin($uid)) { $users = $this->userManager->getUsersSortedByLastLogin($limit, $offset, $search); $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($search, ($tempLimit === null ? null : $tempLimit - count($users))), - fn (IUser $user): bool => !$user->isEnabled() - ) - ) - ); - if (($tempLimit !== null) && (count($users) >= $tempLimit)) { - break; - } - } - $users = array_slice($users, $offset); } $usersDetails = []; @@ -332,13 +309,13 @@ class UsersController extends AUserData { // We still want to return all other accounts, but this one was removed from the backends // yet they are still in our database. Might be a LDAP remnant. $userData = null; - $this->logger->warning('Found one disabled account that was removed from its backend, but still exists in Nextcloud database', ['accountId' => $userId]); + $this->logger->warning('Found one account that was removed from its backend, but still exists in Nextcloud database', ['accountId' => $userId]); } // Do not insert empty entry if ($userData !== null) { $usersDetails[$userId] = $userData; } else { - // Currently logged in user does not have permissions to see this user + // Currently logged-in user does not have permissions to see this user // only showing its id $usersDetails[$userId] = ['id' => $userId]; } diff --git a/lib/private/AllConfig.php b/lib/private/AllConfig.php index 756ceabdbea..87b9c795f49 100644 --- a/lib/private/AllConfig.php +++ b/lib/private/AllConfig.php @@ -494,38 +494,32 @@ class AllConfig implements IConfig { /** * Gets the list of users based on their lastLogin info asc or desc * + * @param int $limit how many users to fetch + * @param int $offset from which offset to fetch * @param string $search search users based on search params * @return array of user IDs */ - public function getLastLoggedInUsers($search): array { + public function getLastLoggedInUsers(int $limit = 25, int $offset = 0, string $search = ''): array { // TODO - FIXME $this->fixDIInit(); $query = $this->connection->getQueryBuilder(); - $lastLoginSubSelect = $this->connection->getQueryBuilder(); - $lastLoginSubSelect->select('configvalue') - ->from('preferences', 'p2') - ->where($lastLoginSubSelect->expr()->andX( - $lastLoginSubSelect->expr()->eq('p2.userid', 'uid'), - $lastLoginSubSelect->expr()->eq('p2.appid', $lastLoginSubSelect->expr()->literal('login')), - $lastLoginSubSelect->expr()->eq('p2.configkey', $lastLoginSubSelect->expr()->literal('lastLogin')), - )); - $orderByExpression = $query->createFunction('(' . $lastLoginSubSelect->getSQL() .')'); - - $query->select('uid', 'displayname', $orderByExpression) + $query->select('uid', 'displayname') ->from('users', 'u') ->leftJoin('u', 'preferences', 'p', $query->expr()->andX( $query->expr()->eq('userid', 'uid'), - $query->expr()->eq('appid', $query->expr()->literal('settings')), - $query->expr()->eq('configkey', $query->expr()->literal('email'))) + $query->expr()->eq('appid', $query->expr()->literal('login')), + $query->expr()->eq('configkey', $query->expr()->literal('lastLogin'))) ) // sqlite doesn't like re-using a single named parameter here ->where($query->expr()->iLike('uid', $query->createPositionalParameter('%' . $this->connection->escapeLikeParameter($search) . '%'))) ->orWhere($query->expr()->iLike('displayname', $query->createPositionalParameter('%' . $this->connection->escapeLikeParameter($search) . '%'))) ->orWhere($query->expr()->iLike('configvalue', $query->createPositionalParameter('%' . $this->connection->escapeLikeParameter($search) . '%'))) - ->orderBy($orderByExpression, 'DESC') - ->addOrderBy('uid_lower', 'ASC'); + ->orderBy($query->func()->lower('configvalue'), 'DESC') + ->addOrderBy('uid_lower', 'ASC') + ->setFirstResult($offset) + ->setMaxResults($limit); $result = $query->executeQuery(); $displayNames = []; diff --git a/lib/private/User/Manager.php b/lib/private/User/Manager.php index 0ae24397f5f..93ba7f0eb6e 100644 --- a/lib/private/User/Manager.php +++ b/lib/private/User/Manager.php @@ -345,30 +345,15 @@ class Manager extends PublicEmitter implements IUserManager { /** * @return IUser[] */ - public function getUsersSortedByLastLogin(?int $limit = null, int $offset = 0, $search = ''): array { - $users = $this->config->getLastLoggedInUsers($search); - $users = array_combine( + public function getUsersSortedByLastLogin(?int $limit = 25, int $offset = 0, $search = ''): array { + $users = $this->config->getLastLoggedInUsers($limit, $offset, $search); + return 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); } diff --git a/lib/public/IConfig.php b/lib/public/IConfig.php index a91fe1e62b0..b74292855a8 100644 --- a/lib/public/IConfig.php +++ b/lib/public/IConfig.php @@ -253,9 +253,11 @@ interface IConfig { /** * Gets the list of users based on their lastLogin info asc or desc * + * @param int $limit how many records to fetch + * @param int $offset from which offset to fetch * @param string $search search users based on search params * @return array of user IDs * @since 30.0.0 */ - public function getLastLoggedInUsers($search); + public function getLastLoggedInUsers(int $limit, int $offset, string $search): array; } -- cgit v1.2.3 From ceedfb46162e53d39460d25b781ddc21c5a9313f Mon Sep 17 00:00:00 2001 From: yemkareems Date: Thu, 4 Jul 2024 13:42:37 +0530 Subject: fix: removed default limit of 25. if null is given all users are fetched or if limit is given limit number of users are fetched Signed-off-by: yemkareems --- apps/provisioning_api/lib/Controller/UsersController.php | 2 +- lib/private/AllConfig.php | 13 +++++++++++-- lib/private/User/Manager.php | 2 +- lib/public/IConfig.php | 4 ++-- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/apps/provisioning_api/lib/Controller/UsersController.php b/apps/provisioning_api/lib/Controller/UsersController.php index beb240681d0..66cce405335 100644 --- a/apps/provisioning_api/lib/Controller/UsersController.php +++ b/apps/provisioning_api/lib/Controller/UsersController.php @@ -278,7 +278,7 @@ class UsersController extends AUserData { * 200: Users details returned based on last logged in information */ public function getLastLoggedInUsers(string $search = '', - ?int $limit = 25, + ?int $limit = null, int $offset = 0, ): DataResponse { $currentUser = $this->userSession->getUser(); diff --git a/lib/private/AllConfig.php b/lib/private/AllConfig.php index 87b9c795f49..78546531dc6 100644 --- a/lib/private/AllConfig.php +++ b/lib/private/AllConfig.php @@ -494,12 +494,13 @@ class AllConfig implements IConfig { /** * Gets the list of users based on their lastLogin info asc or desc * - * @param int $limit how many users to fetch + * @param int|null $limit how many users to fetch * @param int $offset from which offset to fetch * @param string $search search users based on search params * @return array of user IDs */ - public function getLastLoggedInUsers(int $limit = 25, int $offset = 0, string $search = ''): array { + public function getLastLoggedInUsers(?int $limit = null, int $offset = 0, string $search = ''): array { + $limit = $this->fixLimit($limit); // TODO - FIXME $this->fixDIInit(); @@ -573,4 +574,12 @@ class AllConfig implements IConfig { public function getSystemConfig() { return $this->systemConfig; } + + private function fixLimit($limit) { + if (is_int($limit) && $limit >= 0) { + return $limit; + } + + return null; + } } diff --git a/lib/private/User/Manager.php b/lib/private/User/Manager.php index 93ba7f0eb6e..aeadb338ea0 100644 --- a/lib/private/User/Manager.php +++ b/lib/private/User/Manager.php @@ -345,7 +345,7 @@ class Manager extends PublicEmitter implements IUserManager { /** * @return IUser[] */ - public function getUsersSortedByLastLogin(?int $limit = 25, int $offset = 0, $search = ''): array { + public function getUsersSortedByLastLogin(?int $limit = null, int $offset = 0, $search = ''): array { $users = $this->config->getLastLoggedInUsers($limit, $offset, $search); return array_combine( $users, diff --git a/lib/public/IConfig.php b/lib/public/IConfig.php index b74292855a8..92dcfe7f8bc 100644 --- a/lib/public/IConfig.php +++ b/lib/public/IConfig.php @@ -253,11 +253,11 @@ interface IConfig { /** * Gets the list of users based on their lastLogin info asc or desc * - * @param int $limit how many records to fetch + * @param int|null $limit how many records to fetch * @param int $offset from which offset to fetch * @param string $search search users based on search params * @return array of user IDs * @since 30.0.0 */ - public function getLastLoggedInUsers(int $limit, int $offset, string $search): array; + public function getLastLoggedInUsers(?int $limit = null, int $offset = 0, string $search = ''): array; } -- cgit v1.2.3 From ae95e467871cbf54df55b1b4f3f512d66b8b8880 Mon Sep 17 00:00:00 2001 From: yemkareems Date: Thu, 4 Jul 2024 14:41:05 +0530 Subject: fix: limit and fixLimit removed. negative limit handled in controller. removed getUsersSortedByLastLogin from Manager and instead used the config in controller Signed-off-by: yemkareems --- apps/provisioning_api/lib/Controller/UsersController.php | 14 ++++---------- lib/private/AllConfig.php | 11 +---------- lib/private/User/Manager.php | 15 --------------- lib/public/IUserManager.php | 5 ----- 4 files changed, 5 insertions(+), 40 deletions(-) diff --git a/apps/provisioning_api/lib/Controller/UsersController.php b/apps/provisioning_api/lib/Controller/UsersController.php index 66cce405335..1d3c1006a59 100644 --- a/apps/provisioning_api/lib/Controller/UsersController.php +++ b/apps/provisioning_api/lib/Controller/UsersController.php @@ -266,9 +266,7 @@ class UsersController extends AUserData { } /** - * @NoAdminRequired - * - * Get the list of last logged-in users and their details + * Gets the list of users sorted by lastLogin, from most recent to least recent * * @param string $search Text to search for * @param ?int $limit Limit the amount of users returned @@ -278,8 +276,8 @@ class UsersController extends AUserData { * 200: Users details returned based on last logged in information */ public function getLastLoggedInUsers(string $search = '', - ?int $limit = null, - int $offset = 0, + ?int $limit = null, + int $offset = 0, ): DataResponse { $currentUser = $this->userSession->getUser(); if ($currentUser === null) { @@ -295,11 +293,7 @@ class UsersController extends AUserData { $users = []; // For Admin alone user sorting based on lastLogin. For sub admin and groups this is not supported - $uid = $currentUser->getUID(); - if ($this->groupManager->isAdmin($uid)) { - $users = $this->userManager->getUsersSortedByLastLogin($limit, $offset, $search); - $users = array_map(fn (IUser $user): string => $user->getUID(), $users); - } + $users = $this->config->getLastLoggedInUsers($limit, $offset, $search); $usersDetails = []; foreach ($users as $userId) { diff --git a/lib/private/AllConfig.php b/lib/private/AllConfig.php index 78546531dc6..f39182683f5 100644 --- a/lib/private/AllConfig.php +++ b/lib/private/AllConfig.php @@ -492,7 +492,7 @@ class AllConfig implements IConfig { } /** - * Gets the list of users based on their lastLogin info asc or desc + * Gets the list of user ids sorted by lastLogin, from most recent to least recent * * @param int|null $limit how many users to fetch * @param int $offset from which offset to fetch @@ -500,7 +500,6 @@ class AllConfig implements IConfig { * @return array of user IDs */ public function getLastLoggedInUsers(?int $limit = null, int $offset = 0, string $search = ''): array { - $limit = $this->fixLimit($limit); // TODO - FIXME $this->fixDIInit(); @@ -574,12 +573,4 @@ class AllConfig implements IConfig { public function getSystemConfig() { return $this->systemConfig; } - - private function fixLimit($limit) { - if (is_int($limit) && $limit >= 0) { - return $limit; - } - - return null; - } } diff --git a/lib/private/User/Manager.php b/lib/private/User/Manager.php index aeadb338ea0..d93431a2699 100644 --- a/lib/private/User/Manager.php +++ b/lib/private/User/Manager.php @@ -342,21 +342,6 @@ class Manager extends PublicEmitter implements IUserManager { return array_slice($users, $offset, $limit); } - /** - * @return IUser[] - */ - public function getUsersSortedByLastLogin(?int $limit = null, int $offset = 0, $search = ''): array { - $users = $this->config->getLastLoggedInUsers($limit, $offset, $search); - return array_combine( - $users, - array_map( - fn (string $uid): IUser => new LazyUser($uid, $this), - $users - ) - ); - } - - /** * Search known users (from phonebook sync) by displayName * diff --git a/lib/public/IUserManager.php b/lib/public/IUserManager.php index 8b080fd75c5..851b565f617 100644 --- a/lib/public/IUserManager.php +++ b/lib/public/IUserManager.php @@ -124,11 +124,6 @@ interface IUserManager { */ public function getDisabledUsers(?int $limit = null, int $offset = 0, string $search = ''): array; - /** - * @return IUser[] - * @since 30.0.0 - */ - public function getUsersSortedByLastLogin(?int $limit = null, int $offset = 0, $search = ''): array; /** * Search known users (from phonebook sync) by displayName * -- cgit v1.2.3 From 0e6040289f05b80501d6610977b6da8ec157b763 Mon Sep 17 00:00:00 2001 From: yemkareems Date: Thu, 4 Jul 2024 17:56:24 +0530 Subject: fix: query refactored to support both the search by email and sort by login Signed-off-by: yemkareems --- lib/private/AllConfig.php | 24 +++++++++++++----------- lib/public/IConfig.php | 2 +- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/lib/private/AllConfig.php b/lib/private/AllConfig.php index f39182683f5..398ac9a6567 100644 --- a/lib/private/AllConfig.php +++ b/lib/private/AllConfig.php @@ -505,29 +505,31 @@ class AllConfig implements IConfig { $query = $this->connection->getQueryBuilder(); - $query->select('uid', 'displayname') + $query->selectDistinct('uid') ->from('users', 'u') ->leftJoin('u', 'preferences', 'p', $query->expr()->andX( - $query->expr()->eq('userid', 'uid'), - $query->expr()->eq('appid', $query->expr()->literal('login')), - $query->expr()->eq('configkey', $query->expr()->literal('lastLogin'))) + $query->expr()->eq('p.userid', 'uid'), + $query->expr()->eq('p.appid', $query->expr()->literal('login')), + $query->expr()->eq('p.configkey', $query->expr()->literal('lastLogin'))) + )->leftJoin('u', 'preferences', 'p1', $query->expr()->andX( + $query->expr()->eq('p1.userid', 'uid'), + $query->expr()->eq('p1.appid', $query->expr()->literal('settings')), + $query->expr()->eq('p1.configkey', $query->expr()->literal('email'))) ) // sqlite doesn't like re-using a single named parameter here ->where($query->expr()->iLike('uid', $query->createPositionalParameter('%' . $this->connection->escapeLikeParameter($search) . '%'))) ->orWhere($query->expr()->iLike('displayname', $query->createPositionalParameter('%' . $this->connection->escapeLikeParameter($search) . '%'))) - ->orWhere($query->expr()->iLike('configvalue', $query->createPositionalParameter('%' . $this->connection->escapeLikeParameter($search) . '%'))) - ->orderBy($query->func()->lower('configvalue'), 'DESC') + ->orWhere($query->expr()->iLike('p1.configvalue', $query->createPositionalParameter('%' . $this->connection->escapeLikeParameter($search) . '%'))) + ->orderBy($query->func()->lower('p.configvalue'), 'DESC') ->addOrderBy('uid_lower', 'ASC') ->setFirstResult($offset) ->setMaxResults($limit); $result = $query->executeQuery(); - $displayNames = []; - while ($row = $result->fetch()) { - $displayNames[(string)$row['uid']] = (string)$row['uid']; - } + $uids = $result->fetchAll(\PDO::FETCH_COLUMN); + $result->closeCursor(); - return $displayNames; + return $uids; } /** diff --git a/lib/public/IConfig.php b/lib/public/IConfig.php index 92dcfe7f8bc..175f0e90c49 100644 --- a/lib/public/IConfig.php +++ b/lib/public/IConfig.php @@ -256,7 +256,7 @@ interface IConfig { * @param int|null $limit how many records to fetch * @param int $offset from which offset to fetch * @param string $search search users based on search params - * @return array of user IDs + * @return list list of user IDs * @since 30.0.0 */ public function getLastLoggedInUsers(?int $limit = null, int $offset = 0, string $search = ''): array; -- cgit v1.2.3 From 3dee8a213db5cb44a5c37e14cf71d82182aa54e9 Mon Sep 17 00:00:00 2001 From: yemkareems Date: Thu, 4 Jul 2024 18:18:06 +0530 Subject: fix: second join and where conditions added only when search param is available Signed-off-by: yemkareems --- lib/private/AllConfig.php | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/lib/private/AllConfig.php b/lib/private/AllConfig.php index 398ac9a6567..0d7973ab0e5 100644 --- a/lib/private/AllConfig.php +++ b/lib/private/AllConfig.php @@ -504,23 +504,26 @@ class AllConfig implements IConfig { $this->fixDIInit(); $query = $this->connection->getQueryBuilder(); - $query->selectDistinct('uid') ->from('users', 'u') ->leftJoin('u', 'preferences', 'p', $query->expr()->andX( $query->expr()->eq('p.userid', 'uid'), $query->expr()->eq('p.appid', $query->expr()->literal('login')), $query->expr()->eq('p.configkey', $query->expr()->literal('lastLogin'))) - )->leftJoin('u', 'preferences', 'p1', $query->expr()->andX( - $query->expr()->eq('p1.userid', 'uid'), - $query->expr()->eq('p1.appid', $query->expr()->literal('settings')), - $query->expr()->eq('p1.configkey', $query->expr()->literal('email'))) - ) - // sqlite doesn't like re-using a single named parameter here - ->where($query->expr()->iLike('uid', $query->createPositionalParameter('%' . $this->connection->escapeLikeParameter($search) . '%'))) - ->orWhere($query->expr()->iLike('displayname', $query->createPositionalParameter('%' . $this->connection->escapeLikeParameter($search) . '%'))) - ->orWhere($query->expr()->iLike('p1.configvalue', $query->createPositionalParameter('%' . $this->connection->escapeLikeParameter($search) . '%'))) - ->orderBy($query->func()->lower('p.configvalue'), 'DESC') + ); + if($search !== '') { + $query->leftJoin('u', 'preferences', 'p1', $query->expr()->andX( + $query->expr()->eq('p1.userid', 'uid'), + $query->expr()->eq('p1.appid', $query->expr()->literal('settings')), + $query->expr()->eq('p1.configkey', $query->expr()->literal('email'))) + ) + // sqlite doesn't like re-using a single named parameter here + ->where($query->expr()->iLike('uid', $query->createPositionalParameter('%' . $this->connection->escapeLikeParameter($search) . '%'))) + ->orWhere($query->expr()->iLike('displayname', $query->createPositionalParameter('%' . $this->connection->escapeLikeParameter($search) . '%'))) + ->orWhere($query->expr()->iLike('p1.configvalue', $query->createPositionalParameter('%' . $this->connection->escapeLikeParameter($search) . '%')) + ); + } + $query->orderBy($query->func()->lower('p.configvalue'), 'DESC') ->addOrderBy('uid_lower', 'ASC') ->setFirstResult($offset) ->setMaxResults($limit); -- cgit v1.2.3 From 0df1a29cf0583c249db3b440e7a44b2033d93bc5 Mon Sep 17 00:00:00 2001 From: yemkareems Date: Thu, 4 Jul 2024 18:38:03 +0530 Subject: fix: return type doc block added as per psalm Signed-off-by: yemkareems --- lib/private/AllConfig.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/private/AllConfig.php b/lib/private/AllConfig.php index 0d7973ab0e5..b1b23ce1dd1 100644 --- a/lib/private/AllConfig.php +++ b/lib/private/AllConfig.php @@ -497,7 +497,7 @@ class AllConfig implements IConfig { * @param int|null $limit how many users to fetch * @param int $offset from which offset to fetch * @param string $search search users based on search params - * @return array of user IDs + * @return list list of user IDs */ public function getLastLoggedInUsers(?int $limit = null, int $offset = 0, string $search = ''): array { // TODO - FIXME -- cgit v1.2.3 From 53e3644ffb74351ebb9d9d4d87e47867e7d30612 Mon Sep 17 00:00:00 2001 From: yemkareems Date: Thu, 4 Jul 2024 19:13:41 +0530 Subject: fix: return type doc block added as per psalm Signed-off-by: yemkareems --- lib/private/AllConfig.php | 2 +- lib/public/IConfig.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/private/AllConfig.php b/lib/private/AllConfig.php index b1b23ce1dd1..6b93fc9f637 100644 --- a/lib/private/AllConfig.php +++ b/lib/private/AllConfig.php @@ -497,7 +497,7 @@ class AllConfig implements IConfig { * @param int|null $limit how many users to fetch * @param int $offset from which offset to fetch * @param string $search search users based on search params - * @return list list of user IDs + * @return array list of user IDs */ public function getLastLoggedInUsers(?int $limit = null, int $offset = 0, string $search = ''): array { // TODO - FIXME diff --git a/lib/public/IConfig.php b/lib/public/IConfig.php index 175f0e90c49..01d513fc2b1 100644 --- a/lib/public/IConfig.php +++ b/lib/public/IConfig.php @@ -256,7 +256,7 @@ interface IConfig { * @param int|null $limit how many records to fetch * @param int $offset from which offset to fetch * @param string $search search users based on search params - * @return list list of user IDs + * @return array list of user IDs * @since 30.0.0 */ public function getLastLoggedInUsers(?int $limit = null, int $offset = 0, string $search = ''): array; -- cgit v1.2.3 From 357786f36a55e7f0b4a490d9f8d6f9881c362982 Mon Sep 17 00:00:00 2001 From: yemkareems Date: Thu, 4 Jul 2024 19:18:16 +0530 Subject: fix: return type doc block added as per psalm Signed-off-by: yemkareems --- lib/private/AllConfig.php | 13 +++++++------ lib/public/IConfig.php | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/lib/private/AllConfig.php b/lib/private/AllConfig.php index 6b93fc9f637..c2fff700e10 100644 --- a/lib/private/AllConfig.php +++ b/lib/private/AllConfig.php @@ -497,7 +497,7 @@ class AllConfig implements IConfig { * @param int|null $limit how many users to fetch * @param int $offset from which offset to fetch * @param string $search search users based on search params - * @return array list of user IDs + * @return list list of user IDs */ public function getLastLoggedInUsers(?int $limit = null, int $offset = 0, string $search = ''): array { // TODO - FIXME @@ -513,15 +513,15 @@ class AllConfig implements IConfig { ); if($search !== '') { $query->leftJoin('u', 'preferences', 'p1', $query->expr()->andX( - $query->expr()->eq('p1.userid', 'uid'), - $query->expr()->eq('p1.appid', $query->expr()->literal('settings')), - $query->expr()->eq('p1.configkey', $query->expr()->literal('email'))) - ) + $query->expr()->eq('p1.userid', 'uid'), + $query->expr()->eq('p1.appid', $query->expr()->literal('settings')), + $query->expr()->eq('p1.configkey', $query->expr()->literal('email'))) + ) // sqlite doesn't like re-using a single named parameter here ->where($query->expr()->iLike('uid', $query->createPositionalParameter('%' . $this->connection->escapeLikeParameter($search) . '%'))) ->orWhere($query->expr()->iLike('displayname', $query->createPositionalParameter('%' . $this->connection->escapeLikeParameter($search) . '%'))) ->orWhere($query->expr()->iLike('p1.configvalue', $query->createPositionalParameter('%' . $this->connection->escapeLikeParameter($search) . '%')) - ); + ); } $query->orderBy($query->func()->lower('p.configvalue'), 'DESC') ->addOrderBy('uid_lower', 'ASC') @@ -529,6 +529,7 @@ class AllConfig implements IConfig { ->setMaxResults($limit); $result = $query->executeQuery(); + /** @var list $uids */ $uids = $result->fetchAll(\PDO::FETCH_COLUMN); $result->closeCursor(); diff --git a/lib/public/IConfig.php b/lib/public/IConfig.php index 01d513fc2b1..175f0e90c49 100644 --- a/lib/public/IConfig.php +++ b/lib/public/IConfig.php @@ -256,7 +256,7 @@ interface IConfig { * @param int|null $limit how many records to fetch * @param int $offset from which offset to fetch * @param string $search search users based on search params - * @return array list of user IDs + * @return list list of user IDs * @since 30.0.0 */ public function getLastLoggedInUsers(?int $limit = null, int $offset = 0, string $search = ''): array; -- cgit v1.2.3 From 710dc43309c36241962c7f0c777b0d6b12b73105 Mon Sep 17 00:00:00 2001 From: yemkareems Date: Fri, 5 Jul 2024 08:13:43 +0530 Subject: fix: doc block corrected Signed-off-by: yemkareems --- lib/public/IConfig.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/public/IConfig.php b/lib/public/IConfig.php index 175f0e90c49..a2973dbe3ba 100644 --- a/lib/public/IConfig.php +++ b/lib/public/IConfig.php @@ -251,7 +251,7 @@ interface IConfig { public function getUsersForUserValue($appName, $key, $value); /** - * Gets the list of users based on their lastLogin info asc or desc + * Gets the list of users sorted by lastLogin, from most recent to least recent * * @param int|null $limit how many records to fetch * @param int $offset from which offset to fetch -- cgit v1.2.3 From 6ac49e549b2f22cccb35c3c7b02ac1a310536f3d Mon Sep 17 00:00:00 2001 From: yemkareems Date: Fri, 5 Jul 2024 15:41:07 +0530 Subject: fix: ran bash build/openapi-checker.sh and commit the result Signed-off-by: yemkareems --- apps/provisioning_api/openapi-administration.json | 379 ++++++++++++++++++++++ apps/provisioning_api/openapi-full.json | 117 +++++++ 2 files changed, 496 insertions(+) diff --git a/apps/provisioning_api/openapi-administration.json b/apps/provisioning_api/openapi-administration.json index abf799a1688..cc219f465b2 100644 --- a/apps/provisioning_api/openapi-administration.json +++ b/apps/provisioning_api/openapi-administration.json @@ -75,6 +75,268 @@ "type": "string" } } + }, + "UserDetails": { + "type": "object", + "required": [ + "additional_mail", + "address", + "backend", + "backendCapabilities", + "biography", + "display-name", + "displayname", + "email", + "fediverse", + "groups", + "headline", + "id", + "language", + "lastLogin", + "locale", + "manager", + "notify_email", + "organisation", + "phone", + "profile_enabled", + "quota", + "role", + "subadmin", + "twitter", + "website" + ], + "properties": { + "additional_mail": { + "type": "array", + "items": { + "type": "string" + } + }, + "additional_mailScope": { + "type": "array", + "items": { + "$ref": "#/components/schemas/UserDetailsScope" + } + }, + "address": { + "type": "string" + }, + "addressScope": { + "$ref": "#/components/schemas/UserDetailsScope" + }, + "avatarScope": { + "$ref": "#/components/schemas/UserDetailsScope" + }, + "backend": { + "type": "string" + }, + "backendCapabilities": { + "type": "object", + "required": [ + "setDisplayName", + "setPassword" + ], + "properties": { + "setDisplayName": { + "type": "boolean" + }, + "setPassword": { + "type": "boolean" + } + } + }, + "biography": { + "type": "string" + }, + "biographyScope": { + "$ref": "#/components/schemas/UserDetailsScope" + }, + "display-name": { + "type": "string" + }, + "displayname": { + "type": "string" + }, + "displaynameScope": { + "$ref": "#/components/schemas/UserDetailsScope" + }, + "email": { + "type": "string", + "nullable": true + }, + "emailScope": { + "$ref": "#/components/schemas/UserDetailsScope" + }, + "enabled": { + "type": "boolean" + }, + "fediverse": { + "type": "string" + }, + "fediverseScope": { + "$ref": "#/components/schemas/UserDetailsScope" + }, + "groups": { + "type": "array", + "items": { + "type": "string" + } + }, + "headline": { + "type": "string" + }, + "headlineScope": { + "$ref": "#/components/schemas/UserDetailsScope" + }, + "id": { + "type": "string" + }, + "language": { + "type": "string" + }, + "lastLogin": { + "type": "integer", + "format": "int64" + }, + "locale": { + "type": "string" + }, + "manager": { + "type": "string" + }, + "notify_email": { + "type": "string", + "nullable": true + }, + "organisation": { + "type": "string" + }, + "organisationScope": { + "$ref": "#/components/schemas/UserDetailsScope" + }, + "phone": { + "type": "string" + }, + "phoneScope": { + "$ref": "#/components/schemas/UserDetailsScope" + }, + "profile_enabled": { + "type": "string" + }, + "profile_enabledScope": { + "$ref": "#/components/schemas/UserDetailsScope" + }, + "quota": { + "$ref": "#/components/schemas/UserDetailsQuota" + }, + "role": { + "type": "string" + }, + "roleScope": { + "$ref": "#/components/schemas/UserDetailsScope" + }, + "storageLocation": { + "type": "string" + }, + "subadmin": { + "type": "array", + "items": { + "type": "string" + } + }, + "twitter": { + "type": "string" + }, + "twitterScope": { + "$ref": "#/components/schemas/UserDetailsScope" + }, + "website": { + "type": "string" + }, + "websiteScope": { + "$ref": "#/components/schemas/UserDetailsScope" + } + } + }, + "UserDetailsQuota": { + "type": "object", + "properties": { + "free": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "type": "integer", + "format": "int64" + } + ] + }, + "quota": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "type": "integer", + "format": "int64" + }, + { + "type": "string" + } + ] + }, + "relative": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "type": "integer", + "format": "int64" + } + ] + }, + "total": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "type": "integer", + "format": "int64" + } + ] + }, + "used": { + "anyOf": [ + { + "type": "number", + "format": "double" + }, + { + "type": "integer", + "format": "int64" + } + ] + } + } + }, + "UserDetailsScope": { + "type": "string", + "enum": [ + "v2-private", + "v2-local", + "v2-federated", + "v2-published", + "private", + "contacts", + "public" + ] } } }, @@ -699,6 +961,123 @@ } } }, + "/ocs/v2.php/cloud/users/recent": { + "get": { + "operationId": "users-get-last-logged-in-users", + "summary": "Gets the list of users sorted by lastLogin, from most recent to least recent", + "description": "This endpoint requires admin access", + "tags": [ + "users" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "search", + "in": "query", + "description": "Text to search for", + "schema": { + "type": "string", + "default": "" + } + }, + { + "name": "limit", + "in": "query", + "description": "Limit the amount of users returned", + "schema": { + "type": "integer", + "format": "int64", + "nullable": true + } + }, + { + "name": "offset", + "in": "query", + "description": "Offset", + "schema": { + "type": "integer", + "format": "int64", + "default": 0 + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Users details returned based on last logged in information", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "type": "object", + "required": [ + "users" + ], + "properties": { + "users": { + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "$ref": "#/components/schemas/UserDetails" + }, + { + "type": "object", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "string" + } + } + } + ] + } + } + } + } + } + } + } + } + } + } + } + } + } + }, "/ocs/v2.php/cloud/users/{userId}/subadmins": { "get": { "operationId": "users-get-user-sub-admin-groups", diff --git a/apps/provisioning_api/openapi-full.json b/apps/provisioning_api/openapi-full.json index e7c094c214d..ce916732cae 100644 --- a/apps/provisioning_api/openapi-full.json +++ b/apps/provisioning_api/openapi-full.json @@ -946,6 +946,123 @@ } } }, + "/ocs/v2.php/cloud/users/recent": { + "get": { + "operationId": "users-get-last-logged-in-users", + "summary": "Gets the list of users sorted by lastLogin, from most recent to least recent", + "description": "This endpoint requires admin access", + "tags": [ + "users" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "search", + "in": "query", + "description": "Text to search for", + "schema": { + "type": "string", + "default": "" + } + }, + { + "name": "limit", + "in": "query", + "description": "Limit the amount of users returned", + "schema": { + "type": "integer", + "format": "int64", + "nullable": true + } + }, + { + "name": "offset", + "in": "query", + "description": "Offset", + "schema": { + "type": "integer", + "format": "int64", + "default": 0 + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "Users details returned based on last logged in information", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "type": "object", + "required": [ + "users" + ], + "properties": { + "users": { + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "$ref": "#/components/schemas/UserDetails" + }, + { + "type": "object", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "string" + } + } + } + ] + } + } + } + } + } + } + } + } + } + } + } + } + } + }, "/ocs/v2.php/cloud/users/{userId}/subadmins": { "get": { "operationId": "users-get-user-sub-admin-groups", -- cgit v1.2.3 From 4eba967d63e8445cf98b968c43728c0e2ff8dd3c Mon Sep 17 00:00:00 2001 From: yemkareems Date: Mon, 8 Jul 2024 15:14:56 +0530 Subject: fix: getLastLoggedInUsers moved from AllConfig/IConfig to IUserManager/Manager Signed-off-by: yemkareems --- .../lib/Controller/UsersController.php | 2 +- lib/private/AllConfig.php | 45 ---------------------- lib/private/User/Manager.php | 43 +++++++++++++++++++++ lib/public/IConfig.php | 11 ------ lib/public/IUserManager.php | 11 ++++++ 5 files changed, 55 insertions(+), 57 deletions(-) diff --git a/apps/provisioning_api/lib/Controller/UsersController.php b/apps/provisioning_api/lib/Controller/UsersController.php index 1d3c1006a59..1cdc1392596 100644 --- a/apps/provisioning_api/lib/Controller/UsersController.php +++ b/apps/provisioning_api/lib/Controller/UsersController.php @@ -293,7 +293,7 @@ class UsersController extends AUserData { $users = []; // For Admin alone user sorting based on lastLogin. For sub admin and groups this is not supported - $users = $this->config->getLastLoggedInUsers($limit, $offset, $search); + $users = $this->userManager->getLastLoggedInUsers($limit, $offset, $search); $usersDetails = []; foreach ($users as $userId) { diff --git a/lib/private/AllConfig.php b/lib/private/AllConfig.php index c2fff700e10..d05fe440202 100644 --- a/lib/private/AllConfig.php +++ b/lib/private/AllConfig.php @@ -491,51 +491,6 @@ class AllConfig implements IConfig { return $userIDs; } - /** - * Gets the list of user ids sorted by lastLogin, from most recent to least recent - * - * @param int|null $limit how many users to fetch - * @param int $offset from which offset to fetch - * @param string $search search users based on search params - * @return list list of user IDs - */ - public function getLastLoggedInUsers(?int $limit = null, int $offset = 0, string $search = ''): array { - // TODO - FIXME - $this->fixDIInit(); - - $query = $this->connection->getQueryBuilder(); - $query->selectDistinct('uid') - ->from('users', 'u') - ->leftJoin('u', 'preferences', 'p', $query->expr()->andX( - $query->expr()->eq('p.userid', 'uid'), - $query->expr()->eq('p.appid', $query->expr()->literal('login')), - $query->expr()->eq('p.configkey', $query->expr()->literal('lastLogin'))) - ); - if($search !== '') { - $query->leftJoin('u', 'preferences', 'p1', $query->expr()->andX( - $query->expr()->eq('p1.userid', 'uid'), - $query->expr()->eq('p1.appid', $query->expr()->literal('settings')), - $query->expr()->eq('p1.configkey', $query->expr()->literal('email'))) - ) - // sqlite doesn't like re-using a single named parameter here - ->where($query->expr()->iLike('uid', $query->createPositionalParameter('%' . $this->connection->escapeLikeParameter($search) . '%'))) - ->orWhere($query->expr()->iLike('displayname', $query->createPositionalParameter('%' . $this->connection->escapeLikeParameter($search) . '%'))) - ->orWhere($query->expr()->iLike('p1.configvalue', $query->createPositionalParameter('%' . $this->connection->escapeLikeParameter($search) . '%')) - ); - } - $query->orderBy($query->func()->lower('p.configvalue'), 'DESC') - ->addOrderBy('uid_lower', 'ASC') - ->setFirstResult($offset) - ->setMaxResults($limit); - - $result = $query->executeQuery(); - /** @var list $uids */ - $uids = $result->fetchAll(\PDO::FETCH_COLUMN); - $result->closeCursor(); - - return $uids; - } - /** * Determines the users that have the given value set for a specific app-key-pair * diff --git a/lib/private/User/Manager.php b/lib/private/User/Manager.php index d93431a2699..639ce507f4d 100644 --- a/lib/private/User/Manager.php +++ b/lib/private/User/Manager.php @@ -733,6 +733,49 @@ class Manager extends PublicEmitter implements IUserManager { } } + /** + * Gets the list of user ids sorted by lastLogin, from most recent to least recent + * + * @param int|null $limit how many users to fetch + * @param int $offset from which offset to fetch + * @param string $search search users based on search params + * @return list list of user IDs + */ + public function getLastLoggedInUsers(?int $limit = null, int $offset = 0, string $search = ''): array { + $connection = \OC::$server->getDatabaseConnection(); + $queryBuilder = $connection->getQueryBuilder(); + $queryBuilder->selectDistinct('uid') + ->from('users', 'u') + ->leftJoin('u', 'preferences', 'p', $queryBuilder->expr()->andX( + $queryBuilder->expr()->eq('p.userid', 'uid'), + $queryBuilder->expr()->eq('p.appid', $queryBuilder->expr()->literal('login')), + $queryBuilder->expr()->eq('p.configkey', $queryBuilder->expr()->literal('lastLogin'))) + ); + if($search !== '') { + $queryBuilder->leftJoin('u', 'preferences', 'p1', $queryBuilder->expr()->andX( + $queryBuilder->expr()->eq('p1.userid', 'uid'), + $queryBuilder->expr()->eq('p1.appid', $queryBuilder->expr()->literal('settings')), + $queryBuilder->expr()->eq('p1.configkey', $queryBuilder->expr()->literal('email'))) + ) + // sqlite doesn't like re-using a single named parameter here + ->where($queryBuilder->expr()->iLike('uid', $queryBuilder->createPositionalParameter('%' . $connection->escapeLikeParameter($search) . '%'))) + ->orWhere($queryBuilder->expr()->iLike('displayname', $queryBuilder->createPositionalParameter('%' . $connection->escapeLikeParameter($search) . '%'))) + ->orWhere($queryBuilder->expr()->iLike('p1.configvalue', $queryBuilder->createPositionalParameter('%' . $connection->escapeLikeParameter($search) . '%')) + ); + } + $queryBuilder->orderBy($queryBuilder->func()->lower('p.configvalue'), 'DESC') + ->addOrderBy('uid_lower', 'ASC') + ->setFirstResult($offset) + ->setMaxResults($limit); + + $result = $queryBuilder->executeQuery(); + /** @var list $uids */ + $uids = $result->fetchAll(\PDO::FETCH_COLUMN); + $result->closeCursor(); + + return $uids; + } + private function verifyUid(string $uid, bool $checkDataDirectory = false): bool { $appdata = 'appdata_' . $this->config->getSystemValueString('instanceid'); diff --git a/lib/public/IConfig.php b/lib/public/IConfig.php index a2973dbe3ba..b7feabd0ef5 100644 --- a/lib/public/IConfig.php +++ b/lib/public/IConfig.php @@ -249,15 +249,4 @@ interface IConfig { * @since 8.0.0 */ public function getUsersForUserValue($appName, $key, $value); - - /** - * Gets the list of users sorted by lastLogin, from most recent to least recent - * - * @param int|null $limit how many records to fetch - * @param int $offset from which offset to fetch - * @param string $search search users based on search params - * @return list list of user IDs - * @since 30.0.0 - */ - public function getLastLoggedInUsers(?int $limit = null, int $offset = 0, string $search = ''): array; } diff --git a/lib/public/IUserManager.php b/lib/public/IUserManager.php index 851b565f617..091ccd89048 100644 --- a/lib/public/IUserManager.php +++ b/lib/public/IUserManager.php @@ -210,4 +210,15 @@ interface IUserManager { * @since 26.0.0 */ public function validateUserId(string $uid, bool $checkDataDirectory = false): void; + + /** + * Gets the list of users sorted by lastLogin, from most recent to least recent + * + * @param int|null $limit how many records to fetch + * @param int $offset from which offset to fetch + * @param string $search search users based on search params + * @return list list of user IDs + * @since 30.0.0 + */ + public function getLastLoggedInUsers(?int $limit = null, int $offset = 0, string $search = ''): array; } -- cgit v1.2.3 From 68d60fcd2692cd36f10c3973986af6966493d5f4 Mon Sep 17 00:00:00 2001 From: provokateurin Date: Mon, 8 Jul 2024 12:21:17 +0200 Subject: fix(OpenAPI): Regenerate Signed-off-by: provokateurin --- apps/provisioning_api/openapi-administration.json | 58 +++++++++++------------ apps/provisioning_api/openapi-full.json | 58 +++++++++++------------ 2 files changed, 58 insertions(+), 58 deletions(-) diff --git a/apps/provisioning_api/openapi-administration.json b/apps/provisioning_api/openapi-administration.json index cc219f465b2..532bf684976 100644 --- a/apps/provisioning_api/openapi-administration.json +++ b/apps/provisioning_api/openapi-administration.json @@ -977,36 +977,36 @@ "basic_auth": [] } ], - "parameters": [ - { - "name": "search", - "in": "query", - "description": "Text to search for", - "schema": { - "type": "string", - "default": "" - } - }, - { - "name": "limit", - "in": "query", - "description": "Limit the amount of users returned", - "schema": { - "type": "integer", - "format": "int64", - "nullable": true - } - }, - { - "name": "offset", - "in": "query", - "description": "Offset", - "schema": { - "type": "integer", - "format": "int64", - "default": 0 + "requestBody": { + "required": false, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "search": { + "type": "string", + "default": "", + "description": "Text to search for" + }, + "limit": { + "type": "integer", + "format": "int64", + "nullable": true, + "description": "Limit the amount of users returned" + }, + "offset": { + "type": "integer", + "format": "int64", + "default": 0, + "description": "Offset" + } + } + } } - }, + } + }, + "parameters": [ { "name": "OCS-APIRequest", "in": "header", diff --git a/apps/provisioning_api/openapi-full.json b/apps/provisioning_api/openapi-full.json index ce916732cae..4c7b1b2e29a 100644 --- a/apps/provisioning_api/openapi-full.json +++ b/apps/provisioning_api/openapi-full.json @@ -962,36 +962,36 @@ "basic_auth": [] } ], - "parameters": [ - { - "name": "search", - "in": "query", - "description": "Text to search for", - "schema": { - "type": "string", - "default": "" - } - }, - { - "name": "limit", - "in": "query", - "description": "Limit the amount of users returned", - "schema": { - "type": "integer", - "format": "int64", - "nullable": true - } - }, - { - "name": "offset", - "in": "query", - "description": "Offset", - "schema": { - "type": "integer", - "format": "int64", - "default": 0 + "requestBody": { + "required": false, + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "search": { + "type": "string", + "default": "", + "description": "Text to search for" + }, + "limit": { + "type": "integer", + "format": "int64", + "nullable": true, + "description": "Limit the amount of users returned" + }, + "offset": { + "type": "integer", + "format": "int64", + "default": 0, + "description": "Offset" + } + } + } } - }, + } + }, + "parameters": [ { "name": "OCS-APIRequest", "in": "header", -- cgit v1.2.3