@@ -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