Skip to content

Commit 3e4a636

Browse files
feat: Include allowed_room_ids in the /summary client-server API
response for rooms with restricted join rules, as required by Matrix 1.15.
1 parent 76b4fdc commit 3e4a636

3 files changed

Lines changed: 72 additions & 20 deletions

File tree

changelog.d/19762.feature

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Include `allowed_room_ids` in the `/summary` client-server API response for rooms with restricted join rules, as required by Matrix 1.15.
2+
Contributed by @FrenchGithubUser @Famedly.

synapse/handlers/room_summary.py

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -775,8 +775,8 @@ async def _build_room_entry(self, room_id: str, for_federation: bool) -> JsonDic
775775
776776
Args:
777777
room_id: The room ID to summarize.
778-
for_federation: True if this is a summary requested over federation
779-
(which includes additional fields).
778+
for_federation: True if this is a summary requested over federation.
779+
Unused; kept for API stability.
780780
781781
Returns:
782782
The JSON dictionary for the room.
@@ -805,24 +805,21 @@ async def _build_room_entry(self, room_id: str, for_federation: bool) -> JsonDic
805805
"encryption": stats.encryption,
806806
}
807807

808-
# Federation requests need to provide additional information so the
809-
# requested server is able to filter the response appropriately.
810-
if for_federation:
811-
current_state_ids = (
812-
await self._storage_controllers.state.get_current_state_ids(room_id)
813-
)
814-
room_version = await self._store.get_room_version(room_id)
808+
# Include allowed_room_ids for rooms with restricted join rules so that
809+
# clients can determine which memberships grant access.
810+
current_state_ids = await self._storage_controllers.state.get_current_state_ids(
811+
room_id
812+
)
813+
room_version = await self._store.get_room_version(room_id)
815814

816-
if await self._event_auth_handler.has_restricted_join_rules(
817-
current_state_ids, room_version
818-
):
819-
allowed_rooms = (
820-
await self._event_auth_handler.get_rooms_that_allow_join(
821-
current_state_ids
822-
)
823-
)
824-
if allowed_rooms:
825-
entry["allowed_room_ids"] = allowed_rooms
815+
if await self._event_auth_handler.has_restricted_join_rules(
816+
current_state_ids, room_version
817+
):
818+
allowed_rooms = await self._event_auth_handler.get_rooms_that_allow_join(
819+
current_state_ids
820+
)
821+
if allowed_rooms:
822+
entry["allowed_room_ids"] = allowed_rooms
826823

827824
# Filter out Nones – rather omit the field altogether
828825
room_entry = {k: v for k, v in entry.items() if v is not None}
@@ -932,7 +929,6 @@ async def get_room_summary(
932929
raise NotFoundError("Room not found or is not accessible")
933930

934931
room = dict(room_entry.room)
935-
room.pop("allowed_room_ids", None)
936932

937933
# If there was a requester, add their membership.
938934
# We keep the membership in the local membership table unless the

tests/handlers/test_room_summary.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1219,6 +1219,60 @@ def test_visibility(self) -> None:
12191219
result = self.get_success(self.handler.get_room_summary(user2, self.room))
12201220
self.assertEqual(result.get("room_id"), self.room)
12211221

1222+
def test_allowed_room_ids_local(self) -> None:
1223+
"""allowed_room_ids is returned for a local room with restricted join rules."""
1224+
# Create a space that the restricted room will allow membership from.
1225+
space = self.helper.create_room_as(
1226+
self.user,
1227+
tok=self.token,
1228+
extra_content={
1229+
"creation_content": {"type": RoomTypes.SPACE},
1230+
"initial_state": [
1231+
{
1232+
"type": EventTypes.JoinRules,
1233+
"state_key": "",
1234+
"content": {"join_rule": JoinRules.PUBLIC},
1235+
}
1236+
],
1237+
},
1238+
)
1239+
1240+
# Create a room version 8 room with join_rule=restricted allowing members
1241+
# of the space above.
1242+
restricted_room = self.helper.create_room_as(
1243+
self.user,
1244+
room_version=RoomVersions.V8.identifier,
1245+
tok=self.token,
1246+
extra_content={
1247+
"initial_state": [
1248+
{
1249+
"type": EventTypes.JoinRules,
1250+
"state_key": "",
1251+
"content": {
1252+
"join_rule": JoinRules.RESTRICTED,
1253+
"allow": [
1254+
{
1255+
"type": RestrictedJoinRuleTypes.ROOM_MEMBERSHIP,
1256+
"room_id": space,
1257+
}
1258+
],
1259+
},
1260+
}
1261+
]
1262+
},
1263+
)
1264+
1265+
result = self.get_success(
1266+
self.handler.get_room_summary(self.user, restricted_room)
1267+
)
1268+
self.assertEqual(result.get("room_id"), restricted_room)
1269+
self.assertEqual(result.get("allowed_room_ids"), [space])
1270+
1271+
def test_allowed_room_ids_absent_without_restricted_join_rules(self) -> None:
1272+
"""allowed_room_ids is absent for rooms that do not use restricted join rules."""
1273+
result = self.get_success(self.handler.get_room_summary(self.user, self.room))
1274+
self.assertNotIn("allowed_room_ids", result)
1275+
12221276
def test_fed(self) -> None:
12231277
"""
12241278
Return data over federation and ensure that it is handled properly.

0 commit comments

Comments
 (0)