From 23c042aead65385a500be6e671ddd0e942a7e864 Mon Sep 17 00:00:00 2001 From: Rory& Date: Tue, 27 May 2025 06:37:52 +0200 Subject: [PATCH 06/10] Expose tombstone in room admin api --- synapse/rest/admin/rooms.py | 5 ++++ synapse/rest/client/room.py | 1 - synapse/storage/databases/main/room.py | 36 +++++++++++++++++++++++++- 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/synapse/rest/admin/rooms.py b/synapse/rest/admin/rooms.py index f8c5bf18d4..adac1f0362 100644 --- a/synapse/rest/admin/rooms.py +++ b/synapse/rest/admin/rooms.py @@ -251,6 +251,10 @@ class ListRoomRestServlet(RestServlet): direction = parse_enum(request, "dir", Direction, default=Direction.FORWARDS) reverse_order = True if direction == Direction.BACKWARDS else False + emma_include_tombstone = parse_boolean( + request, "emma_include_tombstone", default=False + ) + # Return list of rooms according to parameters rooms, total_rooms = await self.store.get_rooms_paginate( start, @@ -260,6 +264,7 @@ class ListRoomRestServlet(RestServlet): search_term, public_rooms, empty_rooms, + emma_include_tombstone = emma_include_tombstone ) response = { diff --git a/synapse/rest/client/room.py b/synapse/rest/client/room.py index 63ea52baf8..38230de0de 100644 --- a/synapse/rest/client/room.py +++ b/synapse/rest/client/room.py @@ -918,7 +918,6 @@ class RoomEventServlet(RestServlet): request, "fi.mau.msc2815.include_unredacted_content" ) - == "true" ) if include_unredacted_content and not await self.auth.is_server_admin( requester diff --git a/synapse/storage/databases/main/room.py b/synapse/storage/databases/main/room.py index 1df06a5171..347dbbba6b 100644 --- a/synapse/storage/databases/main/room.py +++ b/synapse/storage/databases/main/room.py @@ -610,6 +610,7 @@ class RoomWorkerStore(CacheInvalidationWorkerStore): search_term: Optional[str], public_rooms: Optional[bool], empty_rooms: Optional[bool], + emma_include_tombstone: bool = False, ) -> Tuple[List[Dict[str, Any]], int]: """Function to retrieve a paginated list of rooms as json. @@ -629,6 +630,7 @@ class RoomWorkerStore(CacheInvalidationWorkerStore): If true, empty rooms are queried. if false, empty rooms are excluded from the query. When it is none (the default), both empty rooms and none-empty rooms are queried. + emma_include_tombstone: If true, include tombstone events in the results. Returns: A list of room dicts and an integer representing the total number of rooms that exist given this query @@ -797,11 +799,43 @@ class RoomWorkerStore(CacheInvalidationWorkerStore): room_count = cast(Tuple[int], txn.fetchone()) return rooms, room_count[0] - return await self.db_pool.runInteraction( + result = await self.db_pool.runInteraction( "get_rooms_paginate", _get_rooms_paginate_txn, ) + if emma_include_tombstone: + room_id_sql, room_id_args = make_in_list_sql_clause( + self.database_engine, "cse.room_id", [r["room_id"] for r in result[0]] + ) + + tombstone_sql = """ + SELECT cse.room_id, cse.event_id, ej.json + FROM current_state_events cse + JOIN event_json ej USING (event_id) + WHERE cse.type = 'm.room.tombstone' + AND {room_id_sql} + """.format( + room_id_sql=room_id_sql + ) + + def _get_tombstones_txn( + txn: LoggingTransaction, + ) -> Dict[str, JsonDict]: + txn.execute(tombstone_sql, room_id_args) + for room_id, event_id, json in txn: + for result_room in result[0]: + if result_room["room_id"] == room_id: + result_room["gay.rory.synapse_admin_extensions.tombstone"] = db_to_json(json) + break + return result[0], result[1] + + result = await self.db_pool.runInteraction( + "get_rooms_tombstones", _get_tombstones_txn, + ) + + return result + @cached(max_entries=10000) async def get_ratelimit_for_user(self, user_id: str) -> Optional[RatelimitOverride]: """Check if there are any overrides for ratelimiting for the given user -- 2.49.0