diff --git a/synapse/handlers/room_summary.py b/synapse/handlers/room_summary.py
index 720459f1e7..1c39cfed1b 100644
--- a/synapse/handlers/room_summary.py
+++ b/synapse/handlers/room_summary.py
@@ -183,8 +183,13 @@ class RoomSummaryHandler:
) -> JsonDict:
"""See docstring for SpaceSummaryHandler.get_room_hierarchy."""
- # First of all, check that the room is accessible.
- if not await self._is_local_room_accessible(requested_room_id, requester):
+ # If the room is available locally, quickly check that the user can access it.
+ local_room = await self._store.is_host_joined(
+ requested_room_id, self._server_name
+ )
+ if local_room and not await self._is_local_room_accessible(
+ requested_room_id, requester
+ ):
raise UnstableSpecAuthError(
403,
"User %s not in room %s, and room previews are disabled"
@@ -192,6 +197,22 @@ class RoomSummaryHandler:
errcode=Codes.NOT_JOINED,
)
+ if not local_room:
+ room_hierarchy = await self._summarize_remote_room_hierarchy(
+ _RoomQueueEntry(requested_room_id, ()),
+ False,
+ )
+ root_room_entry = room_hierarchy[0]
+ if not root_room_entry or not await self._is_remote_room_accessible(
+ requester, requested_room_id, root_room_entry.room
+ ):
+ raise UnstableSpecAuthError(
+ 403,
+ "User %s not in room %s, and room previews are disabled"
+ % (requester, requested_room_id),
+ errcode=Codes.NOT_JOINED,
+ )
+
# If this is continuing a previous session, pull the persisted data.
if from_token:
try:
@@ -679,23 +700,55 @@ class RoomSummaryHandler:
"""
# The API doesn't return the room version so assume that a
# join rule of knock is valid.
+ join_rule = room.get("join_rule")
+ world_readable = room.get("world_readable")
+
+ logger.warning(
+ "[EMMA] Checking if room %s is accessible to %s: join_rule=%s, world_readable=%s",
+ room_id, requester, join_rule, world_readable
+ )
+
if (
- room.get("join_rule")
- in (JoinRules.PUBLIC, JoinRules.KNOCK, JoinRules.KNOCK_RESTRICTED)
- or room.get("world_readable") is True
+ join_rule in (JoinRules.PUBLIC, JoinRules.KNOCK, JoinRules.KNOCK_RESTRICTED)
+ or world_readable is True
):
return True
- elif not requester:
+ else:
+ logger.warning(
+ "[EMMA] Room %s is not accessible to %s: join_rule=%s, world_readable=%s, join_rule result=%s, world_readable result=%s",
+ room_id, requester, join_rule, world_readable,
+ join_rule in (JoinRules.PUBLIC, JoinRules.KNOCK, JoinRules.KNOCK_RESTRICTED),
+ world_readable is True
+ )
+
+ if not requester:
+ logger.warning(
+ "[EMMA] No requester, so room %s is not accessible",
+ room_id
+ )
return False
+
# Check if the user is a member of any of the allowed rooms from the response.
allowed_rooms = room.get("allowed_room_ids")
+ logger.warning(
+ "[EMMA] Checking if room %s is in allowed rooms for %s: join_rule=%s, allowed_rooms=%s",
+ requester,
+ room_id,
+ join_rule,
+ allowed_rooms
+ )
if allowed_rooms and isinstance(allowed_rooms, list):
if await self._event_auth_handler.is_user_in_rooms(
allowed_rooms, requester
):
return True
+ logger.warning(
+ "[EMMA] Checking if room %s is accessble to %s via local state",
+ room_id,
+ requester
+ )
# Finally, check locally if we can access the room. The user might
# already be in the room (if it was a child room), or there might be a
# pending invite, etc.
@@ -863,6 +916,10 @@ class RoomSummaryHandler:
if not room_entry or not await self._is_remote_room_accessible(
requester, room_entry.room_id, room_entry.room
):
+ logger.warning(
+ "[Emma] Room entry contents: %s",
+ room_entry.room if room_entry else None
+ )
raise NotFoundError("Room not found or is not accessible")
room = dict(room_entry.room)
|