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

Extend room admin api with additional attributes #7225

Merged
merged 11 commits into from
Apr 22, 2020
1 change: 1 addition & 0 deletions changelog.d/7225.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Extend room admin api (`GET /_synapse/admin/v1/rooms`) with additional attributes.
73 changes: 68 additions & 5 deletions docs/admin_api/rooms.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ The following query parameters are available:
* `order_by` - The method in which to sort the returned list of rooms. Valid values are:
- `alphabetical` - Rooms are ordered alphabetically by room name. This is the default.
- `size` - Rooms are ordered by the number of members. Largest to smallest.
- `name`, `canonical_alias`, `joined_members`, `joined_local_members`, `version`, `creator`,
`encryption`, `federatable`, `public`, `join_rules`, `guest_access`, `history_visibility`,
`state_events` - ordered by this column
clokep marked this conversation as resolved.
Show resolved Hide resolved
* `dir` - Direction of room order. Either `f` for forwards or `b` for backwards. Setting
this value to `b` will reverse the above sort order. Defaults to `f`.
* `search_term` - Filter rooms by their room name. Search term can be contained in any
Expand All @@ -26,6 +29,16 @@ The following fields are possible in the JSON response body:
- `name` - The name of the room.
- `canonical_alias` - The canonical (main) alias address of the room.
- `joined_members` - How many users are currently in the room.
- `joined_local_members` - How many local users are currently in the room.
- `version` - Version of the room.
dklimpel marked this conversation as resolved.
Show resolved Hide resolved
- `creator` - The `user_id` of the room creator..
dklimpel marked this conversation as resolved.
Show resolved Hide resolved
- `encryption` - Algorithm of end-to-end encryption of messages.
clokep marked this conversation as resolved.
Show resolved Hide resolved
- `federatable` -Whether users on other servers can join this room.
dklimpel marked this conversation as resolved.
Show resolved Hide resolved
- `public` - If rooms is public or not on the server. Visibility in room directory.
dklimpel marked this conversation as resolved.
Show resolved Hide resolved
- `join_rules` - The type of rules used for users wishing to join this room. One of: ["public", "knock", "invite", "private"]
- `guest_access` - Whether guests can join the room. One of: ["can_join", "forbidden"]
- `history_visibility` - Who can see the room history. One of: ["invited", "joined", "shared", "world_readable"]
dklimpel marked this conversation as resolved.
Show resolved Hide resolved
- `state_events` - Total number of state_events of a room. Complexity of the room.
* `offset` - The current pagination offset in rooms. This parameter should be
used instead of `next_token` for room offset as `next_token` is
not intended to be parsed.
Expand Down Expand Up @@ -60,14 +73,34 @@ Response:
"room_id": "!OGEhHVWSdvArJzumhm:matrix.org",
"name": "Matrix HQ",
"canonical_alias": "#matrix:matrix.org",
"joined_members": 8326
"joined_members": 8326,
"joined_local_members": 2,
"version": "1",
"creator": "@foo:matrix.org",
"encryption": null,
"federatable": true,
"public": true,
"join_rules": "invite",
"guest_access": null,
"history_visibility": "shared",
"state_events": 93534
},
... (8 hidden items) ...
{
"room_id": "!xYvNcQPhnkrdUmYczI:matrix.org",
"name": "This Week In Matrix (TWIM)",
"canonical_alias": "#twim:matrix.org",
"joined_members": 314
"joined_members": 314,
"joined_local_members": 20,
"version": "4",
"creator": "@foo:matrix.org",
"encryption": "m.megolm.v1.aes-sha2",
"federatable": true,
"public": false,
"join_rules": "invite",
"guest_access": null,
"history_visibility": "shared",
"state_events": 8345
}
],
"offset": 0,
Expand All @@ -92,7 +125,17 @@ Response:
"room_id": "!xYvNcQPhnkrdUmYczI:matrix.org",
"name": "This Week In Matrix (TWIM)",
"canonical_alias": "#twim:matrix.org",
"joined_members": 314
"joined_members": 314,
"joined_local_members": 20,
"version": "4",
"creator": "@foo:matrix.org",
"encryption": "m.megolm.v1.aes-sha2",
"federatable": true,
"public": false,
"join_rules": "invite",
"guest_access": null,
"history_visibility": "shared",
"state_events": 8
}
],
"offset": 0,
Expand All @@ -117,14 +160,34 @@ Response:
"room_id": "!OGEhHVWSdvArJzumhm:matrix.org",
"name": "Matrix HQ",
"canonical_alias": "#matrix:matrix.org",
"joined_members": 8326
"joined_members": 8326,
"joined_local_members": 2,
"version": "1",
"creator": "@foo:matrix.org",
"encryption": null,
"federatable": true,
"public": true,
"join_rules": "invite",
"guest_access": null,
"history_visibility": "shared",
"state_events": 93534
},
... (98 hidden items) ...
{
"room_id": "!xYvNcQPhnkrdUmYczI:matrix.org",
"name": "This Week In Matrix (TWIM)",
"canonical_alias": "#twim:matrix.org",
"joined_members": 314
"joined_members": 314,
"joined_local_members": 20,
"version": "4",
"creator": "@foo:matrix.org",
"encryption": "m.megolm.v1.aes-sha2",
"federatable": true,
"public": false,
"join_rules": "invite",
"guest_access": null,
"history_visibility": "shared",
"state_events": 8345
}
],
"offset": 0,
Expand Down
13 changes: 13 additions & 0 deletions synapse/rest/admin/rooms.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,19 @@ async def on_GET(self, request):
if order_by not in (
RoomSortOrder.ALPHABETICAL.value,
RoomSortOrder.SIZE.value,
RoomSortOrder.NAME.value,
RoomSortOrder.CANONICAL_ALIAS.value,
RoomSortOrder.JOINED_MEMBERS.value,
RoomSortOrder.JOINED_LOCAL_MEMBERS.value,
RoomSortOrder.VERSION.value,
RoomSortOrder.CREATOR.value,
RoomSortOrder.ENCRYPTION.value,
RoomSortOrder.FEDERATABLE.value,
RoomSortOrder.PUBLIC.value,
RoomSortOrder.JOIN_RULES.value,
RoomSortOrder.GUEST_ACCESS.value,
RoomSortOrder.HISTORY_VISIBILITY.value,
RoomSortOrder.STATE_EVENTS.value,
):
raise SynapseError(
400,
Expand Down
70 changes: 68 additions & 2 deletions synapse/storage/data_stores/main/room.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,19 @@ class RoomSortOrder(Enum):

ALPHABETICAL = "alphabetical"
anoadragon453 marked this conversation as resolved.
Show resolved Hide resolved
SIZE = "size"
NAME = "name"
CANONICAL_ALIAS = "canonical_alias"
JOINED_MEMBERS = "joined_members"
JOINED_LOCAL_MEMBERS = "joined_local_members"
VERSION = "version"
CREATOR = "creator"
ENCRYPTION = "encryption"
FEDERATABLE = "federatable"
PUBLIC = "public"
JOIN_RULES = "join_rules"
GUEST_ACCESS = "guest_access"
HISTORY_VISIBILITY = "history_visibility"
STATE_EVENTS = "state_events"


class RoomWorkerStore(SQLBaseStore):
Expand Down Expand Up @@ -335,6 +348,45 @@ async def get_rooms_paginate(
# Sort alphabetically
order_by_column = "state.name"
order_by_asc = True
elif RoomSortOrder(order_by) == RoomSortOrder.NAME:
order_by_column = "state.name"
order_by_asc = True
clokep marked this conversation as resolved.
Show resolved Hide resolved
elif RoomSortOrder(order_by) == RoomSortOrder.CANONICAL_ALIAS:
order_by_column = "state.canonical_alias"
order_by_asc = True
elif RoomSortOrder(order_by) == RoomSortOrder.JOINED_MEMBERS:
order_by_column = "curr.joined_members"
order_by_asc = False
elif RoomSortOrder(order_by) == RoomSortOrder.JOINED_LOCAL_MEMBERS:
order_by_column = "curr.local_users_in_room"
order_by_asc = False
elif RoomSortOrder(order_by) == RoomSortOrder.VERSION:
order_by_column = "rooms.room_version"
order_by_asc = False
elif RoomSortOrder(order_by) == RoomSortOrder.CREATOR:
order_by_column = "rooms.creator"
order_by_asc = True
elif RoomSortOrder(order_by) == RoomSortOrder.ENCRYPTION:
order_by_column = "state.encryption"
order_by_asc = True
elif RoomSortOrder(order_by) == RoomSortOrder.FEDERATABLE:
order_by_column = "state.is_federatable"
order_by_asc = True
elif RoomSortOrder(order_by) == RoomSortOrder.PUBLIC:
order_by_column = "rooms.is_public"
order_by_asc = True
elif RoomSortOrder(order_by) == RoomSortOrder.JOIN_RULES:
order_by_column = "state.join_rules"
order_by_asc = True
elif RoomSortOrder(order_by) == RoomSortOrder.GUEST_ACCESS:
order_by_column = "state.guest_access"
order_by_asc = True
elif RoomSortOrder(order_by) == RoomSortOrder.HISTORY_VISIBILITY:
order_by_column = "state.history_visibility"
order_by_asc = True
elif RoomSortOrder(order_by) == RoomSortOrder.STATE_EVENTS:
order_by_column = "curr.current_state_events"
order_by_asc = False
else:
raise StoreError(
500, "Incorrect value for order_by provided: %s" % order_by
Expand All @@ -349,9 +401,13 @@ async def get_rooms_paginate(
# for, and another query for getting the total number of events that could be
# returned. Thus allowing us to see if there are more events to paginate through
info_sql = """
SELECT state.room_id, state.name, state.canonical_alias, curr.joined_members
SELECT state.room_id, state.name, state.canonical_alias, state.encryption,
state.guest_access, state.is_federatable, state.history_visibility,
state.join_rules, rooms.room_version, rooms.is_public, rooms.creator,
curr.joined_members, curr.current_state_events, curr.local_users_in_room
FROM room_stats_state state
INNER JOIN room_stats_current curr USING (room_id)
INNER JOIN rooms USING (room_id)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any idea if there are performance impacts to joining rooms here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not know it. I am not a SQL specialist.

Copy link
Member

@anoadragon453 anoadragon453 Apr 22, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

explain for the previous version with some example values:

synapse=# explain SELECT state.room_id, state.name, state.canonical_alias, curr.joined_members
synapse-# FROM room_stats_state state
synapse-# INNER JOIN room_stats_current curr USING (room_id)
synapse-# ORDER BY state.name
synapse-# LIMIT 200
synapse-# OFFSET 5;
                                             QUERY PLAN                                             
----------------------------------------------------------------------------------------------------
 Limit  (cost=255.31..255.81 rows=200 width=90)
   ->  Sort  (cost=255.30..260.44 rows=2058 width=90)
         Sort Key: state.name
         ->  Hash Join  (cost=76.99..165.99 rows=2058 width=90)
               Hash Cond: (state.room_id = curr.room_id)
               ->  Seq Scan on room_stats_state state  (cost=0.00..83.58 rows=2058 width=86)
               ->  Hash  (cost=50.33..50.33 rows=2133 width=36)
                     ->  Seq Scan on room_stats_current curr  (cost=0.00..50.33 rows=2133 width=36)
(8 rows)

synapse=# 

and with the new version:

synapse=# explain SELECT state.room_id, state.name, state.canonical_alias, curr.joined_members,
synapse-# curr.local_users_in_room, rooms.room_version, rooms.creator,
synapse-# state.encryption, state.is_federatable, rooms.is_public, state.join_rules,
synapse-# state.guest_access, state.history_visibility, curr.current_state_events
synapse-# FROM room_stats_state state
synapse-# INNER JOIN room_stats_current curr USING (room_id)
synapse-# INNER JOIN rooms USING (room_id)
synapse-# ORDER BY rooms.room_version
synapse-# LIMIT 200
synapse-# OFFSET 5;
                                             QUERY PLAN                                             
----------------------------------------------------------------------------------------------------
 Limit  (cost=331.68..332.18 rows=200 width=162)
   ->  Sort  (cost=331.67..336.44 rows=1907 width=162)
         Sort Key: rooms.room_version
         ->  Hash Join  (cost=154.90..248.91 rows=1907 width=162)
               Hash Cond: (state.room_id = curr.room_id)
               ->  Hash Join  (cost=77.91..166.90 rows=1907 width=182)
                     Hash Cond: (state.room_id = rooms.room_id)
                     ->  Seq Scan on room_stats_state state  (cost=0.00..83.58 rows=2058 width=131)
                     ->  Hash  (cost=54.07..54.07 rows=1907 width=51)
                           ->  Seq Scan on rooms  (cost=0.00..54.07 rows=1907 width=51)
               ->  Hash  (cost=50.33..50.33 rows=2133 width=44)
                     ->  Seq Scan on room_stats_current curr  (cost=0.00..50.33 rows=2133 width=44)
(12 rows)

synapse=# 

So a ~30% increase on the upper bound, but this query is currently only run by the admin API, and as we're getting much more information as a result of it I don't think this is too much of an issue.

%s
ORDER BY %s %s
LIMIT ?
Expand Down Expand Up @@ -388,7 +444,17 @@ def _get_rooms_paginate_txn(txn):
"room_id": room[0],
"name": room[1],
"canonical_alias": room[2],
"joined_members": room[3],
"joined_members": room[11],
"joined_local_members": room[13],
"version": room[8],
"creator": room[10],
"encryption": room[3],
"federatable": room[5],
"public": room[9],
"join_rules": room[7],
"guest_access": room[4],
"history_visibility": room[6],
"state_events": room[12],
dklimpel marked this conversation as resolved.
Show resolved Hide resolved
}
)

Expand Down
Loading