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

Commit 7537201

Browse files
authored
Add search by room ID and room alias to List Room admin API (#11099)
Fixes: #10874 Signed-off-by: Dirk Klimpel [email protected]
1 parent 46d0937 commit 7537201

File tree

4 files changed

+76
-53
lines changed

4 files changed

+76
-53
lines changed

changelog.d/11099.feature

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add search by room ID and room alias to List Room admin API.

docs/admin_api/rooms.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,14 @@ The following query parameters are available:
3838
- `history_visibility` - Rooms are ordered alphabetically by visibility of history of the room.
3939
- `state_events` - Rooms are ordered by number of state events. Largest to smallest.
4040
* `dir` - Direction of room order. Either `f` for forwards or `b` for backwards. Setting
41-
this value to `b` will reverse the above sort order. Defaults to `f`.
42-
* `search_term` - Filter rooms by their room name. Search term can be contained in any
43-
part of the room name. Defaults to no filtering.
41+
this value to `b` will reverse the above sort order. Defaults to `f`.
42+
* `search_term` - Filter rooms by their room name, canonical alias and room id.
43+
Specifically, rooms are selected if the search term is contained in
44+
- the room's name,
45+
- the local part of the room's canonical alias, or
46+
- the complete (local and server part) room's id (case sensitive).
47+
48+
Defaults to no filtering.
4449

4550
**Response**
4651

synapse/storage/databases/main/room.py

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -412,22 +412,33 @@ async def get_rooms_paginate(
412412
limit: maximum amount of rooms to retrieve
413413
order_by: the sort order of the returned list
414414
reverse_order: whether to reverse the room list
415-
search_term: a string to filter room names by
415+
search_term: a string to filter room names,
416+
canonical alias and room ids by.
417+
Room ID must match exactly. Canonical alias must match a substring of the local part.
416418
Returns:
417419
A list of room dicts and an integer representing the total number of
418420
rooms that exist given this query
419421
"""
420422
# Filter room names by a string
421423
where_statement = ""
424+
search_pattern = []
422425
if search_term:
423-
where_statement = "WHERE LOWER(state.name) LIKE ?"
426+
where_statement = """
427+
WHERE LOWER(state.name) LIKE ?
428+
OR LOWER(state.canonical_alias) LIKE ?
429+
OR state.room_id = ?
430+
"""
424431

425432
# Our postgres db driver converts ? -> %s in SQL strings as that's the
426433
# placeholder for postgres.
427434
# HOWEVER, if you put a % into your SQL then everything goes wibbly.
428435
# To get around this, we're going to surround search_term with %'s
429436
# before giving it to the database in python instead
430-
search_term = "%" + search_term.lower() + "%"
437+
search_pattern = [
438+
"%" + search_term.lower() + "%",
439+
"#%" + search_term.lower() + "%:%",
440+
search_term,
441+
]
431442

432443
# Set ordering
433444
if RoomSortOrder(order_by) == RoomSortOrder.SIZE:
@@ -519,12 +530,9 @@ async def get_rooms_paginate(
519530
)
520531

521532
def _get_rooms_paginate_txn(txn):
522-
# Execute the data query
523-
sql_values = (limit, start)
524-
if search_term:
525-
# Add the search term into the WHERE clause
526-
sql_values = (search_term,) + sql_values
527-
txn.execute(info_sql, sql_values)
533+
# Add the search term into the WHERE clause
534+
# and execute the data query
535+
txn.execute(info_sql, search_pattern + [limit, start])
528536

529537
# Refactor room query data into a structured dictionary
530538
rooms = []
@@ -551,8 +559,7 @@ def _get_rooms_paginate_txn(txn):
551559
# Execute the count query
552560

553561
# Add the search term into the WHERE clause if present
554-
sql_values = (search_term,) if search_term else ()
555-
txn.execute(count_sql, sql_values)
562+
txn.execute(count_sql, search_pattern)
556563

557564
room_count = txn.fetchone()
558565
return rooms, room_count[0]

tests/rest/admin/test_room.py

Lines changed: 49 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -680,36 +680,6 @@ def test_room_list_sort_order(self):
680680
reversing the order, etc.
681681
"""
682682

683-
def _set_canonical_alias(room_id: str, test_alias: str, admin_user_tok: str):
684-
# Create a new alias to this room
685-
url = "/_matrix/client/r0/directory/room/%s" % (
686-
urllib.parse.quote(test_alias),
687-
)
688-
channel = self.make_request(
689-
"PUT",
690-
url.encode("ascii"),
691-
{"room_id": room_id},
692-
access_token=admin_user_tok,
693-
)
694-
self.assertEqual(
695-
200, int(channel.result["code"]), msg=channel.result["body"]
696-
)
697-
698-
# Set this new alias as the canonical alias for this room
699-
self.helper.send_state(
700-
room_id,
701-
"m.room.aliases",
702-
{"aliases": [test_alias]},
703-
tok=admin_user_tok,
704-
state_key="test",
705-
)
706-
self.helper.send_state(
707-
room_id,
708-
"m.room.canonical_alias",
709-
{"alias": test_alias},
710-
tok=admin_user_tok,
711-
)
712-
713683
def _order_test(
714684
order_type: str,
715685
expected_room_list: List[str],
@@ -781,9 +751,9 @@ def _order_test(
781751
)
782752

783753
# Set room canonical room aliases
784-
_set_canonical_alias(room_id_1, "#A_alias:test", self.admin_user_tok)
785-
_set_canonical_alias(room_id_2, "#B_alias:test", self.admin_user_tok)
786-
_set_canonical_alias(room_id_3, "#C_alias:test", self.admin_user_tok)
754+
self._set_canonical_alias(room_id_1, "#A_alias:test", self.admin_user_tok)
755+
self._set_canonical_alias(room_id_2, "#B_alias:test", self.admin_user_tok)
756+
self._set_canonical_alias(room_id_3, "#C_alias:test", self.admin_user_tok)
787757

788758
# Set room member size in the reverse order. room 1 -> 1 member, 2 -> 2, 3 -> 3
789759
user_1 = self.register_user("bob1", "pass")
@@ -850,7 +820,7 @@ def test_search_term(self):
850820
room_id_2 = self.helper.create_room_as(self.admin_user, tok=self.admin_user_tok)
851821

852822
room_name_1 = "something"
853-
room_name_2 = "else"
823+
room_name_2 = "LoremIpsum"
854824

855825
# Set the name for each room
856826
self.helper.send_state(
@@ -866,6 +836,8 @@ def test_search_term(self):
866836
tok=self.admin_user_tok,
867837
)
868838

839+
self._set_canonical_alias(room_id_1, "#Room_Alias1:test", self.admin_user_tok)
840+
869841
def _search_test(
870842
expected_room_id: Optional[str],
871843
search_term: str,
@@ -914,24 +886,36 @@ def _search_test(
914886
r = rooms[0]
915887
self.assertEqual(expected_room_id, r["room_id"])
916888

917-
# Perform search tests
889+
# Test searching by room name
918890
_search_test(room_id_1, "something")
919891
_search_test(room_id_1, "thing")
920892

921-
_search_test(room_id_2, "else")
922-
_search_test(room_id_2, "se")
893+
_search_test(room_id_2, "LoremIpsum")
894+
_search_test(room_id_2, "lorem")
923895

924896
# Test case insensitive
925897
_search_test(room_id_1, "SOMETHING")
926898
_search_test(room_id_1, "THING")
927899

928-
_search_test(room_id_2, "ELSE")
929-
_search_test(room_id_2, "SE")
900+
_search_test(room_id_2, "LOREMIPSUM")
901+
_search_test(room_id_2, "LOREM")
930902

931903
_search_test(None, "foo")
932904
_search_test(None, "bar")
933905
_search_test(None, "", expected_http_code=400)
934906

907+
# Test that the whole room id returns the room
908+
_search_test(room_id_1, room_id_1)
909+
# Test that the search by room_id is case sensitive
910+
_search_test(None, room_id_1.lower())
911+
# Test search part of local part of room id do not match
912+
_search_test(None, room_id_1[1:10])
913+
914+
# Test that whole room alias return no result, because of domain
915+
_search_test(None, "#Room_Alias1:test")
916+
# Test search local part of alias
917+
_search_test(room_id_1, "alias1")
918+
935919
def test_search_term_non_ascii(self):
936920
"""Test that searching for a room with non-ASCII characters works correctly"""
937921

@@ -1114,6 +1098,32 @@ def test_room_state(self):
11141098
# the create_room already does the right thing, so no need to verify that we got
11151099
# the state events it created.
11161100

1101+
def _set_canonical_alias(self, room_id: str, test_alias: str, admin_user_tok: str):
1102+
# Create a new alias to this room
1103+
url = "/_matrix/client/r0/directory/room/%s" % (urllib.parse.quote(test_alias),)
1104+
channel = self.make_request(
1105+
"PUT",
1106+
url.encode("ascii"),
1107+
{"room_id": room_id},
1108+
access_token=admin_user_tok,
1109+
)
1110+
self.assertEqual(200, int(channel.result["code"]), msg=channel.result["body"])
1111+
1112+
# Set this new alias as the canonical alias for this room
1113+
self.helper.send_state(
1114+
room_id,
1115+
"m.room.aliases",
1116+
{"aliases": [test_alias]},
1117+
tok=admin_user_tok,
1118+
state_key="test",
1119+
)
1120+
self.helper.send_state(
1121+
room_id,
1122+
"m.room.canonical_alias",
1123+
{"alias": test_alias},
1124+
tok=admin_user_tok,
1125+
)
1126+
11171127

11181128
class JoinAliasRoomTestCase(unittest.HomeserverTestCase):
11191129

0 commit comments

Comments
 (0)