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

Commit 48c358f

Browse files
committed
Abstract out a method for checking if a remote room should be included.
1 parent f8e86b7 commit 48c358f

File tree

2 files changed

+55
-43
lines changed

2 files changed

+55
-43
lines changed

changelog.d/10560.feature

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add pagination to the spaces summary based on updates to [MSC2946](https://github.com/matrix-org/matrix-doc/pull/2946).

synapse/handlers/space_summary.py

Lines changed: 54 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -158,48 +158,10 @@ async def get_space_summary(
158158
room = room_entry.room
159159
fed_room_id = room_entry.room_id
160160

161-
# The room should only be included in the summary if:
162-
# a. the user is in the room;
163-
# b. the room is world readable; or
164-
# c. the user could join the room, e.g. the join rules
165-
# are set to public or the user is in a space that
166-
# has been granted access to the room.
167-
#
168-
# Note that we know the user is not in the root room (which is
169-
# why the remote call was made in the first place), but the user
170-
# could be in one of the children rooms and we just didn't know
171-
# about the link.
172-
173-
# The API doesn't return the room version so assume that a
174-
# join rule of knock is valid.
175-
include_room = (
176-
room.get("join_rules") in (JoinRules.PUBLIC, JoinRules.KNOCK)
177-
or room.get("world_readable") is True
178-
)
179-
180-
# Check if the user is a member of any of the allowed spaces
181-
# from the response.
182-
allowed_rooms = room.get("allowed_room_ids") or room.get(
183-
"allowed_spaces"
184-
)
185-
if (
186-
not include_room
187-
and allowed_rooms
188-
and isinstance(allowed_rooms, list)
189-
):
190-
include_room = await self._event_auth_handler.is_user_in_rooms(
191-
allowed_rooms, requester
192-
)
193-
194-
# Finally, if this isn't the requested room, check ourselves
195-
# if we can access the room.
196-
if not include_room and fed_room_id != queue_entry.room_id:
197-
include_room = await self._is_room_accessible(
198-
fed_room_id, requester, None
199-
)
200-
201161
# The user can see the room, include it!
202-
if include_room:
162+
if await self._is_remote_room_accessible(
163+
queue_entry.room_id, requester, fed_room_id, room
164+
):
203165
# Before returning to the client, remove the allowed_room_ids
204166
# and allowed_spaces keys.
205167
room.pop("allowed_room_ids", None)
@@ -336,7 +298,7 @@ async def _summarize_local_room(
336298
Returns:
337299
A room entry if the room should be returned. None, otherwise.
338300
"""
339-
if not await self._is_room_accessible(room_id, requester, origin):
301+
if not await self._is_local_room_accessible(room_id, requester, origin):
340302
return None
341303

342304
room_entry = await self._build_room_entry(room_id, for_federation=bool(origin))
@@ -438,7 +400,7 @@ async def _summarize_remote_room(
438400

439401
return results
440402

441-
async def _is_room_accessible(
403+
async def _is_local_room_accessible(
442404
self, room_id: str, requester: Optional[str], origin: Optional[str]
443405
) -> bool:
444406
"""
@@ -550,6 +512,55 @@ async def _is_room_accessible(
550512
)
551513
return False
552514

515+
async def _is_remote_room_accessible(
516+
self, requested_room_id: str, requester: str, room_id: str, room: JsonDict
517+
) -> bool:
518+
"""
519+
Calculate whether the room received over federation should be shown in the spaces summary.
520+
521+
It should be included if:
522+
523+
* The requester is joined or can join the room (per MSC3173).
524+
* The history visibility is set to world readable.
525+
526+
Note that we know the user is not in the requested room (which is why the
527+
remote call was made in the first place), but the user could be in one
528+
of the children rooms and we just didn't know about the link.
529+
530+
Args:
531+
requested_room_id: The room ID which was requested.
532+
requester: The user requesting the summary.
533+
room_id: The child room ID returned over federation.
534+
room: The summary of the child room returned over federation.
535+
536+
Returns:
537+
True if the room should be included in the spaces summary.
538+
"""
539+
# The API doesn't return the room version so assume that a
540+
# join rule of knock is valid.
541+
if (
542+
room.get("join_rules") in (JoinRules.PUBLIC, JoinRules.KNOCK)
543+
or room.get("world_readable") is True
544+
):
545+
return True
546+
547+
# Check if the user is a member of any of the allowed spaces
548+
# from the response.
549+
allowed_rooms = room.get("allowed_room_ids") or room.get("allowed_spaces")
550+
if allowed_rooms and isinstance(allowed_rooms, list):
551+
if await self._event_auth_handler.is_user_in_rooms(
552+
allowed_rooms, requester
553+
):
554+
return True
555+
556+
# Finally, if this isn't the requested room, check ourselves
557+
# if we can access the room.
558+
if room_id != requested_room_id:
559+
if await self._is_local_room_accessible(room_id, requester, None):
560+
return True
561+
562+
return False
563+
553564
async def _build_room_entry(self, room_id: str, for_federation: bool) -> JsonDict:
554565
"""
555566
Generate en entry suitable for the 'rooms' list in the summary response.

0 commit comments

Comments
 (0)