From d6d65d7b4101d7b298825b260b16d1aac500bfa0 Mon Sep 17 00:00:00 2001
From: Krishan <33421343+kfiven@users.noreply.github.com>
Date: Thu, 9 Jan 2025 20:39:34 +1100
Subject: [PATCH 01/14] Add via param in hierarchy endpoint

---
 synapse/rest/client/room.py | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/synapse/rest/client/room.py b/synapse/rest/client/room.py
index 03e7bc0a24..9975393389 100644
--- a/synapse/rest/client/room.py
+++ b/synapse/rest/client/room.py
@@ -1526,6 +1526,10 @@ 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]
+        args: Dict[bytes, List[bytes]] = request.args  # type: ignore
+        remote_room_hosts = parse_strings_from_args(args, "via", required=False)
+
         return 200, await self._room_summary_handler.get_room_hierarchy(
             requester,
             room_id,
@@ -1533,6 +1537,7 @@ class RoomHierarchyRestServlet(RestServlet):
             max_depth=max_depth,
             limit=limit,
             from_token=parse_string(request, "from"),
+            remote_room_hosts=remote_room_hosts,
         )
 
 

From 42c81e301ee96e2d7a3e2057d692d5421e568fd2 Mon Sep 17 00:00:00 2001
From: Krishan <33421343+kfiven@users.noreply.github.com>
Date: Thu, 9 Jan 2025 20:45:38 +1100
Subject: [PATCH 02/14] Add via param to hierarchy endpoint

---
 synapse/handlers/room_summary.py | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/synapse/handlers/room_summary.py b/synapse/handlers/room_summary.py
index 64f5bea014..2a50d91080 100644
--- a/synapse/handlers/room_summary.py
+++ b/synapse/handlers/room_summary.py
@@ -126,6 +126,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 +163,7 @@ class RoomSummaryHandler:
                 max_depth,
                 limit,
                 from_token,
+                remote_room_hosts,
             ),
             self._get_room_hierarchy,
             requester.user.to_string(),
@@ -170,6 +172,7 @@ class RoomSummaryHandler:
             max_depth,
             limit,
             from_token,
+            remote_room_hosts,
         )
 
     async def _get_room_hierarchy(
@@ -180,6 +183,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 +203,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 +244,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()

From e08bc2215e6fa9b7e32428c9fe246171d45b88d3 Mon Sep 17 00:00:00 2001
From: Krishan <33421343+kfiven@users.noreply.github.com>
Date: Thu, 9 Jan 2025 20:49:49 +1100
Subject: [PATCH 03/14] add changelog

---
 changelog.d/18070.feature | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 changelog.d/18070.feature

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).

From 7698c998b513e607a0d753077222ee534e69d00d Mon Sep 17 00:00:00 2001
From: Krishan <33421343+kfiven@users.noreply.github.com>
Date: Thu, 9 Jan 2025 20:55:31 +1100
Subject: [PATCH 04/14] Fix typecheck

---
 synapse/handlers/room_summary.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/synapse/handlers/room_summary.py b/synapse/handlers/room_summary.py
index 2a50d91080..c3a5e9abde 100644
--- a/synapse/handlers/room_summary.py
+++ b/synapse/handlers/room_summary.py
@@ -111,7 +111,7 @@ 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",

From fa9d40563ed5f269432d090f4951e1723521b0a6 Mon Sep 17 00:00:00 2001
From: Krishan <33421343+kfiven@users.noreply.github.com>
Date: Thu, 9 Jan 2025 21:06:26 +1100
Subject: [PATCH 05/14] Fix lint

---
 synapse/handlers/room_summary.py | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/synapse/handlers/room_summary.py b/synapse/handlers/room_summary.py
index c3a5e9abde..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], Optional[List[str]]]
+            Tuple[
+                str,
+                str,
+                bool,
+                Optional[int],
+                Optional[int],
+                Optional[str],
+                Optional[List[str]],
+            ]
         ] = ResponseCache(
             hs.get_clock(),
             "get_room_hierarchy",

From 4151878cd829a645fc5ef2295a105aa5eddb89c7 Mon Sep 17 00:00:00 2001
From: Krishan <33421343+kfiven@users.noreply.github.com>
Date: Mon, 13 Jan 2025 21:12:09 +1100
Subject: [PATCH 06/14] Update 18070.feature

---
 changelog.d/18070.feature | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/changelog.d/18070.feature b/changelog.d/18070.feature
index 1bfa0f9246..0c5753f466 100644
--- a/changelog.d/18070.feature
+++ b/changelog.d/18070.feature
@@ -1 +1 @@
-Add `via` param to hierarchy endpoint. Contributed by Krishan (@kfiven).
+Add `via` param to hierarchy endpoint. Contributed by Krishan (@kfiven). 

From 4e3ab79388944f765e9ccff94642814befdba524 Mon Sep 17 00:00:00 2001
From: Krishan <33421343+kfiven@users.noreply.github.com>
Date: Mon, 13 Jan 2025 21:14:46 +1100
Subject: [PATCH 07/14] Update 18070.feature

---
 changelog.d/18070.feature | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/changelog.d/18070.feature b/changelog.d/18070.feature
index 0c5753f466..1bfa0f9246 100644
--- a/changelog.d/18070.feature
+++ b/changelog.d/18070.feature
@@ -1 +1 @@
-Add `via` param to hierarchy endpoint. Contributed by Krishan (@kfiven). 
+Add `via` param to hierarchy endpoint. Contributed by Krishan (@kfiven).

From 7f17913436ab7b3b1e98f7ecc27a492cd16822b0 Mon Sep 17 00:00:00 2001
From: Krishan <33421343+kfiven@users.noreply.github.com>
Date: Fri, 28 Feb 2025 17:45:22 +1100
Subject: [PATCH 08/14] Add MSC4235 experimental flag

---
 synapse/config/experimental.py | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/synapse/config/experimental.py b/synapse/config/experimental.py
index 90d19849ff..052a59223f 100644
--- a/synapse/config/experimental.py
+++ b/synapse/config/experimental.py
@@ -444,3 +444,7 @@ 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)
+

From 013845fa517df5fd7f7d8e2bd16e892d8635617c Mon Sep 17 00:00:00 2001
From: Krishan <33421343+kfiven@users.noreply.github.com>
Date: Fri, 28 Feb 2025 17:48:20 +1100
Subject: [PATCH 09/14] Add unstable prefix in via parameter

---
 synapse/rest/client/room.py | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/synapse/rest/client/room.py b/synapse/rest/client/room.py
index 9975393389..d63885accb 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
@@ -1527,8 +1528,10 @@ class RoomHierarchyRestServlet(RestServlet):
         limit = parse_integer(request, "limit")
 
         # twisted.web.server.Request.args is incorrectly defined as Optional[Any]
-        args: Dict[bytes, List[bytes]] = request.args  # type: ignore
-        remote_room_hosts = parse_strings_from_args(args, "via", required=False)
+        remote_room_hosts: List[str] | 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,

From 76b13b183d29c8155c9dc0bd84c26c4408d66fbd Mon Sep 17 00:00:00 2001
From: Krishan <33421343+kfiven@users.noreply.github.com>
Date: Fri, 28 Feb 2025 17:53:44 +1100
Subject: [PATCH 10/14] Fix typecheck

---
 synapse/rest/client/room.py | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/synapse/rest/client/room.py b/synapse/rest/client/room.py
index d63885accb..fab1558140 100644
--- a/synapse/rest/client/room.py
+++ b/synapse/rest/client/room.py
@@ -1,3 +1,4 @@
+L
 #
 # This file is licensed under the Affero General Public License (AGPL) version 3.
 #
@@ -1529,7 +1530,7 @@ class RoomHierarchyRestServlet(RestServlet):
 
         # twisted.web.server.Request.args is incorrectly defined as Optional[Any]
         remote_room_hosts: List[str] | None
-        if self.msc4235_enabled
+        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)
 

From 482716f18ee9e0ccd8449d75655cd8c5df88873d Mon Sep 17 00:00:00 2001
From: Krishan <33421343+kfiven@users.noreply.github.com>
Date: Fri, 28 Feb 2025 17:54:40 +1100
Subject: [PATCH 11/14] Fix lint

---
 synapse/rest/client/room.py | 1 -
 1 file changed, 1 deletion(-)

diff --git a/synapse/rest/client/room.py b/synapse/rest/client/room.py
index fab1558140..346cc29746 100644
--- a/synapse/rest/client/room.py
+++ b/synapse/rest/client/room.py
@@ -1,4 +1,3 @@
-L
 #
 # This file is licensed under the Affero General Public License (AGPL) version 3.
 #

From 00a4c937be9beb943aa9a4169d870a7ca611ed97 Mon Sep 17 00:00:00 2001
From: Krishan <33421343+kfiven@users.noreply.github.com>
Date: Fri, 28 Feb 2025 18:12:23 +1100
Subject: [PATCH 12/14] Fix lint

---
 synapse/rest/client/room.py | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/synapse/rest/client/room.py b/synapse/rest/client/room.py
index 346cc29746..715fd8376b 100644
--- a/synapse/rest/client/room.py
+++ b/synapse/rest/client/room.py
@@ -1531,7 +1531,9 @@ class RoomHierarchyRestServlet(RestServlet):
         remote_room_hosts: List[str] | 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)
+            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,

From 76f087c1d9969ea31ec3553c27ca7115e66912a8 Mon Sep 17 00:00:00 2001
From: Krishan <33421343+kfiven@users.noreply.github.com>
Date: Fri, 28 Feb 2025 18:13:29 +1100
Subject: [PATCH 13/14] Fix lint

---
 synapse/config/experimental.py | 1 -
 1 file changed, 1 deletion(-)

diff --git a/synapse/config/experimental.py b/synapse/config/experimental.py
index 052a59223f..88b076d119 100644
--- a/synapse/config/experimental.py
+++ b/synapse/config/experimental.py
@@ -447,4 +447,3 @@ class ExperimentalConfig(Config):
 
         # MSC4235: Add `via` param to hierarchy endpoint
         self.msc4235_enabled: bool = experimental.get("msc4235_enabled", False)
-

From a3039b3a019b9283e481f6f2ffa14940448ee9ff Mon Sep 17 00:00:00 2001
From: Krishan <33421343+kfiven@users.noreply.github.com>
Date: Fri, 28 Feb 2025 18:21:36 +1100
Subject: [PATCH 14/14] Fix error: X | Y syntax for unions requires Python 3.10

---
 synapse/rest/client/room.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/synapse/rest/client/room.py b/synapse/rest/client/room.py
index 715fd8376b..5b6ec9b17d 100644
--- a/synapse/rest/client/room.py
+++ b/synapse/rest/client/room.py
@@ -1528,7 +1528,7 @@ class RoomHierarchyRestServlet(RestServlet):
         limit = parse_integer(request, "limit")
 
         # twisted.web.server.Request.args is incorrectly defined as Optional[Any]
-        remote_room_hosts: List[str] | None
+        remote_room_hosts = None
         if self.msc4235_enabled:
             args: Dict[bytes, List[bytes]] = request.args  # type: ignore
             remote_room_hosts = parse_strings_from_args(