diff --git a/changelog.d/18070.feature b/changelog.d/18070.feature new file mode 100644 index 0000000000..1bfa0f9246 --- /dev/null +++ b/changelog.d/18070.feature @@ -0,0 +1 @@ +Add `via` param to hierarchy endpoint. Contributed by Krishan (@kfiven). diff --git a/synapse/config/experimental.py b/synapse/config/experimental.py index 0a963b121a..3dc3abeebe 100644 --- a/synapse/config/experimental.py +++ b/synapse/config/experimental.py @@ -560,3 +560,6 @@ class ExperimentalConfig(Config): # MSC4076: Add `disable_badge_count`` to pusher configuration self.msc4076_enabled: bool = experimental.get("msc4076_enabled", False) + + # MSC4235: Add `via` param to hierarchy endpoint + self.msc4235_enabled: bool = experimental.get("msc4235_enabled", False) diff --git a/synapse/handlers/room_summary.py b/synapse/handlers/room_summary.py index 64f5bea014..57161fb02c 100644 --- a/synapse/handlers/room_summary.py +++ b/synapse/handlers/room_summary.py @@ -111,7 +111,15 @@ class RoomSummaryHandler: # If a user tries to fetch the same page multiple times in quick succession, # only process the first attempt and return its result to subsequent requests. self._pagination_response_cache: ResponseCache[ - Tuple[str, str, bool, Optional[int], Optional[int], Optional[str]] + Tuple[ + str, + str, + bool, + Optional[int], + Optional[int], + Optional[str], + Optional[List[str]], + ] ] = ResponseCache( hs.get_clock(), "get_room_hierarchy", @@ -126,6 +134,7 @@ class RoomSummaryHandler: max_depth: Optional[int] = None, limit: Optional[int] = None, from_token: Optional[str] = None, + remote_room_hosts: Optional[List[str]] = None, ) -> JsonDict: """ Implementation of the room hierarchy C-S API. @@ -162,6 +171,7 @@ class RoomSummaryHandler: max_depth, limit, from_token, + remote_room_hosts, ), self._get_room_hierarchy, requester.user.to_string(), @@ -170,6 +180,7 @@ class RoomSummaryHandler: max_depth, limit, from_token, + remote_room_hosts, ) async def _get_room_hierarchy( @@ -180,6 +191,7 @@ class RoomSummaryHandler: max_depth: Optional[int] = None, limit: Optional[int] = None, from_token: Optional[str] = None, + remote_room_hosts: Optional[List[str]] = None, ) -> JsonDict: """See docstring for SpaceSummaryHandler.get_room_hierarchy.""" @@ -199,7 +211,7 @@ class RoomSummaryHandler: if not local_room: room_hierarchy = await self._summarize_remote_room_hierarchy( - _RoomQueueEntry(requested_room_id, ()), + _RoomQueueEntry(requested_room_id, remote_room_hosts or ()), False, ) root_room_entry = room_hierarchy[0] @@ -240,7 +252,7 @@ class RoomSummaryHandler: processed_rooms = set(pagination_session["processed_rooms"]) else: # The queue of rooms to process, the next room is last on the stack. - room_queue = [_RoomQueueEntry(requested_room_id, ())] + room_queue = [_RoomQueueEntry(requested_room_id, remote_room_hosts or ())] # Rooms we have already processed. processed_rooms = set() diff --git a/synapse/rest/client/room.py b/synapse/rest/client/room.py index 03e7bc0a24..5b6ec9b17d 100644 --- a/synapse/rest/client/room.py +++ b/synapse/rest/client/room.py @@ -1517,6 +1517,7 @@ class RoomHierarchyRestServlet(RestServlet): super().__init__() self._auth = hs.get_auth() self._room_summary_handler = hs.get_room_summary_handler() + self.msc4235_enabled = hs.config.experimental.msc4235_enabled async def on_GET( self, request: SynapseRequest, room_id: str @@ -1526,6 +1527,14 @@ class RoomHierarchyRestServlet(RestServlet): max_depth = parse_integer(request, "max_depth") limit = parse_integer(request, "limit") + # twisted.web.server.Request.args is incorrectly defined as Optional[Any] + remote_room_hosts = None + if self.msc4235_enabled: + args: Dict[bytes, List[bytes]] = request.args # type: ignore + remote_room_hosts = parse_strings_from_args( + args, "org.matrix.msc4235.via", required=False + ) + return 200, await self._room_summary_handler.get_room_hierarchy( requester, room_id, @@ -1533,6 +1542,7 @@ class RoomHierarchyRestServlet(RestServlet): max_depth=max_depth, limit=limit, from_token=parse_string(request, "from"), + remote_room_hosts=remote_room_hosts, )