Skip to content

Commit e75a23a

Browse files
authored
Fix hierarchy returning 403 when room is accessible through federation (#17194)
1 parent e563e4b commit e75a23a

File tree

3 files changed

+72
-2
lines changed

3 files changed

+72
-2
lines changed

changelog.d/17194.bugfix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix hierarchy returning 403 when room is accessible through federation. Contributed by Krishan (@kfiven).

synapse/handlers/room_summary.py

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,15 +183,36 @@ async def _get_room_hierarchy(
183183
) -> JsonDict:
184184
"""See docstring for SpaceSummaryHandler.get_room_hierarchy."""
185185

186-
# First of all, check that the room is accessible.
187-
if not await self._is_local_room_accessible(requested_room_id, requester):
186+
# If the room is available locally, quickly check that the user can access it.
187+
local_room = await self._store.is_host_joined(
188+
requested_room_id, self._server_name
189+
)
190+
if local_room and not await self._is_local_room_accessible(
191+
requested_room_id, requester
192+
):
188193
raise UnstableSpecAuthError(
189194
403,
190195
"User %s not in room %s, and room previews are disabled"
191196
% (requester, requested_room_id),
192197
errcode=Codes.NOT_JOINED,
193198
)
194199

200+
if not local_room:
201+
room_hierarchy = await self._summarize_remote_room_hierarchy(
202+
_RoomQueueEntry(requested_room_id, ()),
203+
False,
204+
)
205+
root_room_entry = room_hierarchy[0]
206+
if not root_room_entry or not await self._is_remote_room_accessible(
207+
requester, requested_room_id, root_room_entry.room
208+
):
209+
raise UnstableSpecAuthError(
210+
403,
211+
"User %s not in room %s, and room previews are disabled"
212+
% (requester, requested_room_id),
213+
errcode=Codes.NOT_JOINED,
214+
)
215+
195216
# If this is continuing a previous session, pull the persisted data.
196217
if from_token:
197218
try:

tests/handlers/test_room_summary.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -757,6 +757,54 @@ async def summarize_remote_room_hierarchy(
757757
)
758758
self._assert_hierarchy(result, expected)
759759

760+
def test_fed_root(self) -> None:
761+
"""
762+
Test if requested room is available over federation.
763+
"""
764+
fed_hostname = self.hs.hostname + "2"
765+
fed_space = "#fed_space:" + fed_hostname
766+
fed_subroom = "#fed_sub_room:" + fed_hostname
767+
768+
requested_room_entry = _RoomEntry(
769+
fed_space,
770+
{
771+
"room_id": fed_space,
772+
"world_readable": True,
773+
"room_type": RoomTypes.SPACE,
774+
},
775+
[
776+
{
777+
"type": EventTypes.SpaceChild,
778+
"room_id": fed_space,
779+
"state_key": fed_subroom,
780+
"content": {"via": [fed_hostname]},
781+
}
782+
],
783+
)
784+
child_room = {
785+
"room_id": fed_subroom,
786+
"world_readable": True,
787+
}
788+
789+
async def summarize_remote_room_hierarchy(
790+
_self: Any, room: Any, suggested_only: bool
791+
) -> Tuple[Optional[_RoomEntry], Dict[str, JsonDict], Set[str]]:
792+
return requested_room_entry, {fed_subroom: child_room}, set()
793+
794+
expected = [
795+
(fed_space, [fed_subroom]),
796+
(fed_subroom, ()),
797+
]
798+
799+
with mock.patch(
800+
"synapse.handlers.room_summary.RoomSummaryHandler._summarize_remote_room_hierarchy",
801+
new=summarize_remote_room_hierarchy,
802+
):
803+
result = self.get_success(
804+
self.handler.get_room_hierarchy(create_requester(self.user), fed_space)
805+
)
806+
self._assert_hierarchy(result, expected)
807+
760808
def test_fed_filtering(self) -> None:
761809
"""
762810
Rooms returned over federation should be properly filtered to only include

0 commit comments

Comments
 (0)