Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Filter locked users in the admin API #16328

Merged
merged 6 commits into from
Sep 18, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/16328.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Enables filtering locked users in list users admin API.
hanadi92 marked this conversation as resolved.
Show resolved Hide resolved
6 changes: 5 additions & 1 deletion synapse/rest/admin/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class UsersRestServletV2(RestServlet):
The parameter `deactivated` can be used to include deactivated users.
The parameter `order_by` can be used to order the result.
The parameter `not_user_type` can be used to exclude certain user types.
The parameter `locked` can be used to include locked users.
Possible values are `bot`, `support` or "empty string".
"empty string" here means to exclude users without a type.
"""
Expand Down Expand Up @@ -107,8 +108,9 @@ async def on_GET(self, request: SynapseRequest) -> Tuple[int, JsonDict]:
"The guests parameter is not supported when MSC3861 is enabled.",
errcode=Codes.INVALID_PARAM,
)
deactivated = parse_boolean(request, "deactivated", default=False)

deactivated = parse_boolean(request, "deactivated", default=False)
locked = parse_boolean(request, "locked", default=False)
admins = parse_boolean(request, "admins")

# If support for MSC3866 is not enabled, apply no filtering based on the
Expand All @@ -133,6 +135,7 @@ async def on_GET(self, request: SynapseRequest) -> Tuple[int, JsonDict]:
UserSortOrder.SHADOW_BANNED.value,
UserSortOrder.CREATION_TS.value,
UserSortOrder.LAST_SEEN_TS.value,
UserSortOrder.LOCKED.value,
),
)

Expand All @@ -154,6 +157,7 @@ async def on_GET(self, request: SynapseRequest) -> Tuple[int, JsonDict]:
direction,
approved,
not_user_types,
locked,
)

# If support for MSC3866 is not enabled, don't show the approval flag.
Expand Down
7 changes: 6 additions & 1 deletion synapse/storage/databases/main/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ async def get_users_paginate(
direction: Direction = Direction.FORWARDS,
approved: bool = True,
not_user_types: Optional[List[str]] = None,
locked: bool = False,
) -> Tuple[List[JsonDict], int]:
"""Function to retrieve a paginated list of users from
users list. This will return a json list of users and the
Expand All @@ -194,6 +195,7 @@ async def get_users_paginate(
direction: sort ascending or descending
approved: whether to include approved users
not_user_types: list of user types to exclude
locked: whether to include locked users
Returns:
A tuple of a list of mappings from user to information and a count of total users.
"""
Expand Down Expand Up @@ -226,6 +228,9 @@ def get_users_paginate_txn(
if not deactivated:
filters.append("deactivated = 0")

if not locked:
filters.append("locked IS FALSE")

if admins is not None:
if admins:
filters.append("admin = 1")
Expand Down Expand Up @@ -290,7 +295,7 @@ def get_users_paginate_txn(
sql = f"""
SELECT name, user_type, is_guest, admin, deactivated, shadow_banned,
displayname, avatar_url, creation_ts * 1000 as creation_ts, approved,
eu.user_id is not null as erased, last_seen_ts
eu.user_id is not null as erased, last_seen_ts, locked
{sql_base}
ORDER BY {order_by_column} {order}, u.name ASC
LIMIT ? OFFSET ?
Expand Down
1 change: 1 addition & 0 deletions synapse/storage/databases/main/stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ class UserSortOrder(Enum):
SHADOW_BANNED = "shadow_banned"
CREATION_TS = "creation_ts"
LAST_SEEN_TS = "last_seen_ts"
LOCKED = "locked"


class StatsStore(StateDeltasStore):
Expand Down
26 changes: 26 additions & 0 deletions tests/rest/admin/test_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -1146,6 +1146,32 @@ def test_erasure_status(self) -> None:
users = {user["name"]: user for user in channel.json_body["users"]}
self.assertIs(users[user_id]["erased"], True)

def test_filter_locked(self) -> None:
# Create a new user.
user_id = self.register_user("lockme", "lockme")

# Lock them
self.get_success(self.store.set_user_locked_status(user_id, True))

# Locked user should appear in list users API
channel = self.make_request(
"GET",
self.url + "?locked=true",
access_token=self.admin_user_tok,
)
users = {user["name"]: user for user in channel.json_body["users"]}
self.assertIn(user_id, users)
self.assertTrue(users[user_id]["locked"])

# Locked user should not appear in list users API
channel = self.make_request(
"GET",
self.url + "?locked=false",
access_token=self.admin_user_tok,
)
users = {user["name"]: user for user in channel.json_body["users"]}
self.assertNotIn(user_id, users)

def _order_test(
self,
expected_user_list: List[str],
Expand Down
Loading