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

Commit f558369

Browse files
authored
Do not recurse into non-spaces in the spaces summary. (#10256)
Previously m.child.room events in non-space rooms would be treated as part of the room graph, but this is no longer supported.
1 parent 7647b03 commit f558369

File tree

5 files changed

+43
-26
lines changed

5 files changed

+43
-26
lines changed

changelog.d/10256.misc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Improve the performance of the spaces summary endpoint by only recursing into spaces (and not rooms in general).

synapse/api/constants.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,12 @@ class EventContentFields:
201201
)
202202

203203

204+
class RoomTypes:
205+
"""Understood values of the room_type field of m.room.create events."""
206+
207+
SPACE = "m.space"
208+
209+
204210
class RoomEncryptionAlgorithms:
205211
MEGOLM_V1_AES_SHA2 = "m.megolm.v1.aes-sha2"
206212
DEFAULT = MEGOLM_V1_AES_SHA2

synapse/handlers/space_summary.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
EventTypes,
2626
HistoryVisibility,
2727
Membership,
28+
RoomTypes,
2829
)
2930
from synapse.events import EventBase
3031
from synapse.events.utils import format_event_for_client_v2
@@ -318,7 +319,8 @@ async def _summarize_local_room(
318319
319320
Returns:
320321
A tuple of:
321-
An iterable of a single value of the room.
322+
The room information, if the room should be returned to the
323+
user. None, otherwise.
322324
323325
An iterable of the sorted children events. This may be limited
324326
to a maximum size or may include all children.
@@ -328,7 +330,11 @@ async def _summarize_local_room(
328330

329331
room_entry = await self._build_room_entry(room_id)
330332

331-
# look for child rooms/spaces.
333+
# If the room is not a space, return just the room information.
334+
if room_entry.get("room_type") != RoomTypes.SPACE:
335+
return room_entry, ()
336+
337+
# Otherwise, look for child rooms/spaces.
332338
child_events = await self._get_child_events(room_id)
333339

334340
if suggested_only:
@@ -348,6 +354,7 @@ async def _summarize_local_room(
348354
event_format=format_event_for_client_v2,
349355
)
350356
)
357+
351358
return room_entry, events_result
352359

353360
async def _summarize_remote_room(

tests/handlers/test_space_summary.py

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from typing import Any, Iterable, Optional, Tuple
1515
from unittest import mock
1616

17+
from synapse.api.constants import EventContentFields, RoomTypes
1718
from synapse.api.errors import AuthError
1819
from synapse.handlers.space_summary import _child_events_comparison_key
1920
from synapse.rest import admin
@@ -97,9 +98,21 @@ def prepare(self, reactor, clock, hs: HomeServer):
9798
self.hs = hs
9899
self.handler = self.hs.get_space_summary_handler()
99100

101+
# Create a user.
100102
self.user = self.register_user("user", "pass")
101103
self.token = self.login("user", "pass")
102104

105+
# Create a space and a child room.
106+
self.space = self.helper.create_room_as(
107+
self.user,
108+
tok=self.token,
109+
extra_content={
110+
"creation_content": {EventContentFields.ROOM_TYPE: RoomTypes.SPACE}
111+
},
112+
)
113+
self.room = self.helper.create_room_as(self.user, tok=self.token)
114+
self._add_child(self.space, self.room, self.token)
115+
103116
def _add_child(self, space_id: str, room_id: str, token: str) -> None:
104117
"""Add a child room to a space."""
105118
self.helper.send_state(
@@ -128,43 +141,32 @@ def _assert_events(
128141

129142
def test_simple_space(self):
130143
"""Test a simple space with a single room."""
131-
space = self.helper.create_room_as(self.user, tok=self.token)
132-
room = self.helper.create_room_as(self.user, tok=self.token)
133-
self._add_child(space, room, self.token)
134-
135-
result = self.get_success(self.handler.get_space_summary(self.user, space))
144+
result = self.get_success(self.handler.get_space_summary(self.user, self.space))
136145
# The result should have the space and the room in it, along with a link
137146
# from space -> room.
138-
self._assert_rooms(result, [space, room])
139-
self._assert_events(result, [(space, room)])
147+
self._assert_rooms(result, [self.space, self.room])
148+
self._assert_events(result, [(self.space, self.room)])
140149

141150
def test_visibility(self):
142151
"""A user not in a space cannot inspect it."""
143-
space = self.helper.create_room_as(self.user, tok=self.token)
144-
room = self.helper.create_room_as(self.user, tok=self.token)
145-
self._add_child(space, room, self.token)
146-
147152
user2 = self.register_user("user2", "pass")
148153
token2 = self.login("user2", "pass")
149154

150155
# The user cannot see the space.
151-
self.get_failure(self.handler.get_space_summary(user2, space), AuthError)
156+
self.get_failure(self.handler.get_space_summary(user2, self.space), AuthError)
152157

153158
# Joining the room causes it to be visible.
154-
self.helper.join(space, user2, tok=token2)
155-
result = self.get_success(self.handler.get_space_summary(user2, space))
159+
self.helper.join(self.space, user2, tok=token2)
160+
result = self.get_success(self.handler.get_space_summary(user2, self.space))
156161

157162
# The result should only have the space, but includes the link to the room.
158-
self._assert_rooms(result, [space])
159-
self._assert_events(result, [(space, room)])
163+
self._assert_rooms(result, [self.space])
164+
self._assert_events(result, [(self.space, self.room)])
160165

161166
def test_world_readable(self):
162167
"""A world-readable room is visible to everyone."""
163-
space = self.helper.create_room_as(self.user, tok=self.token)
164-
room = self.helper.create_room_as(self.user, tok=self.token)
165-
self._add_child(space, room, self.token)
166168
self.helper.send_state(
167-
space,
169+
self.space,
168170
event_type="m.room.history_visibility",
169171
body={"history_visibility": "world_readable"},
170172
tok=self.token,
@@ -173,6 +175,6 @@ def test_world_readable(self):
173175
user2 = self.register_user("user2", "pass")
174176

175177
# The space should be visible, as well as the link to the room.
176-
result = self.get_success(self.handler.get_space_summary(user2, space))
177-
self._assert_rooms(result, [space])
178-
self._assert_events(result, [(space, room)])
178+
result = self.get_success(self.handler.get_space_summary(user2, self.space))
179+
self._assert_rooms(result, [self.space])
180+
self._assert_events(result, [(self.space, self.room)])

tests/rest/client/v1/utils.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ def create_room_as(
5252
room_version: str = None,
5353
tok: str = None,
5454
expect_code: int = 200,
55+
extra_content: Optional[Dict] = None,
5556
) -> str:
5657
"""
5758
Create a room.
@@ -72,7 +73,7 @@ def create_room_as(
7273
temp_id = self.auth_user_id
7374
self.auth_user_id = room_creator
7475
path = "/_matrix/client/r0/createRoom"
75-
content = {}
76+
content = extra_content or {}
7677
if not is_public:
7778
content["visibility"] = "private"
7879
if room_version:

0 commit comments

Comments
 (0)