Allow filtering for admins in the list accounts admin API (#16114)

pull/16139/head
Alexander Fechler 2023-08-18 13:26:38 +02:00 committed by GitHub
parent 6130afb862
commit 54317d34b7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 54 additions and 0 deletions

View File

@ -0,0 +1 @@
Add an `admins` query parameter to the [List Accounts](https://matrix-org.github.io/synapse/v1.91/admin_api/user_admin_api.html#list-accounts) [admin API](https://matrix-org.github.io/synapse/v1.91/usage/administration/admin_api/index.html), to include only admins or to exclude admins in user queries.

View File

@ -219,6 +219,8 @@ The following parameters should be set in the URL:
**or** displaynames that contain this value. **or** displaynames that contain this value.
- `guests` - string representing a bool - Is optional and if `false` will **exclude** guest users. - `guests` - string representing a bool - Is optional and if `false` will **exclude** guest users.
Defaults to `true` to include guest users. Defaults to `true` to include guest users.
- `admins` - Optional flag to filter admins. If `true`, only admins are queried. If `false`, admins are excluded from
the query. When the flag is absent (the default), **both** admins and non-admins are included in the search results.
- `deactivated` - string representing a bool - Is optional and if `true` will **include** deactivated users. - `deactivated` - string representing a bool - Is optional and if `true` will **include** deactivated users.
Defaults to `false` to exclude deactivated users. Defaults to `false` to exclude deactivated users.
- `limit` - string representing a positive integer - Is optional but is used for pagination, - `limit` - string representing a positive integer - Is optional but is used for pagination,

View File

@ -109,6 +109,8 @@ class UsersRestServletV2(RestServlet):
) )
deactivated = parse_boolean(request, "deactivated", default=False) deactivated = parse_boolean(request, "deactivated", default=False)
admins = parse_boolean(request, "admins")
# If support for MSC3866 is not enabled, apply no filtering based on the # If support for MSC3866 is not enabled, apply no filtering based on the
# `approved` column. # `approved` column.
if self._msc3866_enabled: if self._msc3866_enabled:
@ -146,6 +148,7 @@ class UsersRestServletV2(RestServlet):
name, name,
guests, guests,
deactivated, deactivated,
admins,
order_by, order_by,
direction, direction,
approved, approved,

View File

@ -168,6 +168,7 @@ class DataStore(
name: Optional[str] = None, name: Optional[str] = None,
guests: bool = True, guests: bool = True,
deactivated: bool = False, deactivated: bool = False,
admins: Optional[bool] = None,
order_by: str = UserSortOrder.NAME.value, order_by: str = UserSortOrder.NAME.value,
direction: Direction = Direction.FORWARDS, direction: Direction = Direction.FORWARDS,
approved: bool = True, approved: bool = True,
@ -184,6 +185,9 @@ class DataStore(
name: search for local part of user_id or display name name: search for local part of user_id or display name
guests: whether to in include guest users guests: whether to in include guest users
deactivated: whether to include deactivated users deactivated: whether to include deactivated users
admins: Optional flag to filter admins. If true, only admins are queried.
if false, admins are excluded from the query. When it is
none (the default), both admins and none-admins are queried.
order_by: the sort order of the returned list order_by: the sort order of the returned list
direction: sort ascending or descending direction: sort ascending or descending
approved: whether to include approved users approved: whether to include approved users
@ -220,6 +224,12 @@ class DataStore(
if not deactivated: if not deactivated:
filters.append("deactivated = 0") filters.append("deactivated = 0")
if admins is not None:
if admins:
filters.append("admin = 1")
else:
filters.append("admin = 0")
if not approved: if not approved:
# We ignore NULL values for the approved flag because these should only # We ignore NULL values for the approved flag because these should only
# be already existing users that we consider as already approved. # be already existing users that we consider as already approved.

View File

@ -879,6 +879,44 @@ class UsersListTestCase(unittest.HomeserverTestCase):
self._order_test([self.admin_user, user1, user2], "creation_ts", "f") self._order_test([self.admin_user, user1, user2], "creation_ts", "f")
self._order_test([user2, user1, self.admin_user], "creation_ts", "b") self._order_test([user2, user1, self.admin_user], "creation_ts", "b")
def test_filter_admins(self) -> None:
"""
Tests whether the various values of the query parameter `admins` lead to the
expected result set.
"""
# Register an additional non admin user
self.register_user("user", "pass", admin=False)
# Query all users
channel = self.make_request(
"GET",
f"{self.url}",
access_token=self.admin_user_tok,
)
self.assertEqual(200, channel.code, channel.result)
self.assertEqual(2, channel.json_body["total"])
# Query only admin users
channel = self.make_request(
"GET",
f"{self.url}?admins=true",
access_token=self.admin_user_tok,
)
self.assertEqual(200, channel.code, channel.result)
self.assertEqual(1, channel.json_body["total"])
self.assertEqual(1, channel.json_body["users"][0]["admin"])
# Query only non admin users
channel = self.make_request(
"GET",
f"{self.url}?admins=false",
access_token=self.admin_user_tok,
)
self.assertEqual(200, channel.code, channel.result)
self.assertEqual(1, channel.json_body["total"])
self.assertFalse(channel.json_body["users"][0]["admin"])
@override_config( @override_config(
{ {
"experimental_features": { "experimental_features": {