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

Allow public spaces to be returned via the summary APIs. #10580

Merged
merged 4 commits into from
Aug 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/10580.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Allow public rooms to be previewed in the spaces summary APIs from [MSC2946](https://github.com/matrix-org/matrix-doc/pull/2946).
31 changes: 18 additions & 13 deletions synapse/handlers/space_summary.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
Membership,
RoomTypes,
)
from synapse.api.errors import Codes, SynapseError
from synapse.api.errors import AuthError, Codes, SynapseError
from synapse.events import EventBase
from synapse.events.utils import format_event_for_client_v2
from synapse.types import JsonDict
Expand Down Expand Up @@ -86,7 +86,6 @@ class _PaginationSession:
class SpaceSummaryHandler:
def __init__(self, hs: "HomeServer"):
self._clock = hs.get_clock()
self._auth = hs.get_auth()
self._event_auth_handler = hs.get_event_auth_handler()
self._store = hs.get_datastore()
self._event_serializer = hs.get_event_client_serializer()
Expand Down Expand Up @@ -133,9 +132,13 @@ async def get_space_summary(
Returns:
summary dict to return
"""
# first of all, check that the user is in the room in question (or it's
# world-readable)
await self._auth.check_user_in_room_or_world_readable(room_id, requester)
# First of all, check that the room is accessible.
if not await self._is_local_room_accessible(room_id, requester):
raise AuthError(
403,
"User %s not in room %s, and room previews are disabled"
% (requester, room_id),
)

# the queue of rooms to process
room_queue = deque((_RoomQueueEntry(room_id, ()),))
Expand Down Expand Up @@ -304,11 +307,13 @@ async def _get_room_hierarchy(
) -> JsonDict:
"""See docstring for SpaceSummaryHandler.get_room_hierarchy."""

# first of all, check that the user is in the room in question (or it's
# world-readable)
await self._auth.check_user_in_room_or_world_readable(
requested_room_id, requester
)
# First of all, check that the room is accessible.
if not await self._is_local_room_accessible(requested_room_id, requester):
raise AuthError(
403,
"User %s not in room %s, and room previews are disabled"
% (requester, requested_room_id),
)

# If this is continuing a previous session, pull the persisted data.
if from_token:
Expand Down Expand Up @@ -590,7 +595,7 @@ async def _summarize_remote_room(
return results

async def _is_local_room_accessible(
self, room_id: str, requester: Optional[str], origin: Optional[str]
self, room_id: str, requester: Optional[str], origin: Optional[str] = None
) -> bool:
"""
Calculate whether the room should be shown in the spaces summary.
Expand Down Expand Up @@ -744,7 +749,7 @@ async def _is_remote_room_accessible(
# 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.
return await self._is_local_room_accessible(room_id, requester, None)
return await self._is_local_room_accessible(room_id, requester)

async def _build_room_entry(self, room_id: str, for_federation: bool) -> JsonDict:
"""
Expand All @@ -761,7 +766,7 @@ async def _build_room_entry(self, room_id: str, for_federation: bool) -> JsonDic
stats = await self._store.get_room_with_stats(room_id)

# currently this should be impossible because we call
# check_user_in_room_or_world_readable on the room before we get here, so
# _is_local_room_accessible on the room before we get here, so
# there should always be an entry
assert stats is not None, "unable to retrieve stats for %s" % (room_id,)

Expand Down
28 changes: 26 additions & 2 deletions tests/handlers/test_space_summary.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,21 @@ def test_visibility(self):
user2 = self.register_user("user2", "pass")
token2 = self.login("user2", "pass")

# The user cannot see the space.
# The user can see the space since it is publicly joinable.
result = self.get_success(self.handler.get_space_summary(user2, self.space))
expected = [(self.space, [self.room]), (self.room, ())]
self._assert_rooms(result, expected)

result = self.get_success(self.handler.get_room_hierarchy(user2, self.space))
self._assert_hierarchy(result, expected)

# If the space is made invite-only, it should no longer be viewable.
self.helper.send_state(
self.space,
event_type=EventTypes.JoinRules,
body={"join_rule": JoinRules.INVITE},
tok=self.token,
)
self.get_failure(self.handler.get_space_summary(user2, self.space), AuthError)
self.get_failure(self.handler.get_room_hierarchy(user2, self.space), AuthError)

Expand All @@ -260,7 +274,6 @@ def test_visibility(self):
tok=self.token,
)
result = self.get_success(self.handler.get_space_summary(user2, self.space))
expected = [(self.space, [self.room]), (self.room, ())]
self._assert_rooms(result, expected)

result = self.get_success(self.handler.get_room_hierarchy(user2, self.space))
Expand All @@ -277,13 +290,24 @@ def test_visibility(self):
self.get_failure(self.handler.get_room_hierarchy(user2, self.space), AuthError)

# Join the space and results should be returned.
self.helper.invite(self.space, targ=user2, tok=self.token)
self.helper.join(self.space, user2, tok=token2)
result = self.get_success(self.handler.get_space_summary(user2, self.space))
self._assert_rooms(result, expected)

result = self.get_success(self.handler.get_room_hierarchy(user2, self.space))
self._assert_hierarchy(result, expected)

# Attempting to view an unknown room returns the same error.
self.get_failure(
self.handler.get_space_summary(user2, "#not-a-space:" + self.hs.hostname),
AuthError,
)
self.get_failure(
self.handler.get_room_hierarchy(user2, "#not-a-space:" + self.hs.hostname),
AuthError,
)

def _create_room_with_join_rule(
self, join_rule: str, room_version: Optional[str] = None, **extra_content
) -> str:
Expand Down