diff --git a/changelog.d/10189.misc b/changelog.d/10189.misc
new file mode 100644
index 0000000000..df0e636c7d
--- /dev/null
+++ b/changelog.d/10189.misc
@@ -0,0 +1 @@
+Update MSC3083 support for modifications in the MSC.
diff --git a/synapse/api/constants.py b/synapse/api/constants.py
index ca13843680..6c3958f7ab 100644
--- a/synapse/api/constants.py
+++ b/synapse/api/constants.py
@@ -65,6 +65,12 @@ class JoinRules:
MSC3083_RESTRICTED = "restricted"
+class RestrictedJoinRuleTypes:
+ """Understood types for the allow rules in restricted join rules."""
+
+ ROOM_MEMBERSHIP = "m.room_membership"
+
+
class LoginType:
PASSWORD = "m.login.password"
EMAIL_IDENTITY = "m.login.email.identity"
diff --git a/synapse/handlers/event_auth.py b/synapse/handlers/event_auth.py
index a0df16a32f..989996b628 100644
--- a/synapse/handlers/event_auth.py
+++ b/synapse/handlers/event_auth.py
@@ -13,7 +13,12 @@
# limitations under the License.
from typing import TYPE_CHECKING, Collection, Optional
-from synapse.api.constants import EventTypes, JoinRules, Membership
+from synapse.api.constants import (
+ EventTypes,
+ JoinRules,
+ Membership,
+ RestrictedJoinRuleTypes,
+)
from synapse.api.errors import AuthError
from synapse.api.room_versions import RoomVersion
from synapse.events import EventBase
@@ -42,7 +47,7 @@ class EventAuthHandler:
Check whether a user can join a room without an invite due to restricted join rules.
When joining a room with restricted joined rules (as defined in MSC3083),
- the membership of spaces must be checked during a room join.
+ the membership of rooms must be checked during a room join.
Args:
state_ids: The state of the room as it currently is.
@@ -67,20 +72,20 @@ class EventAuthHandler:
if not await self.has_restricted_join_rules(state_ids, room_version):
return
- # Get the spaces which allow access to this room and check if the user is
+ # Get the rooms which allow access to this room and check if the user is
# in any of them.
- allowed_spaces = await self.get_spaces_that_allow_join(state_ids)
- if not await self.is_user_in_rooms(allowed_spaces, user_id):
+ allowed_rooms = await self.get_rooms_that_allow_join(state_ids)
+ if not await self.is_user_in_rooms(allowed_rooms, user_id):
raise AuthError(
403,
- "You do not belong to any of the required spaces to join this room.",
+ "You do not belong to any of the required rooms to join this room.",
)
async def has_restricted_join_rules(
self, state_ids: StateMap[str], room_version: RoomVersion
) -> bool:
"""
- Return if the room has the proper join rules set for access via spaces.
+ Return if the room has the proper join rules set for access via rooms.
Args:
state_ids: The state of the room as it currently is.
@@ -102,17 +107,17 @@ class EventAuthHandler:
join_rules_event = await self._store.get_event(join_rules_event_id)
return join_rules_event.content.get("join_rule") == JoinRules.MSC3083_RESTRICTED
- async def get_spaces_that_allow_join(
+ async def get_rooms_that_allow_join(
self, state_ids: StateMap[str]
) -> Collection[str]:
"""
- Generate a list of spaces which allow access to a room.
+ Generate a list of rooms in which membership allows access to a room.
Args:
- state_ids: The state of the room as it currently is.
+ state_ids: The current state of the room the user wishes to join
Returns:
- A collection of spaces which provide membership to the room.
+ A collection of room IDs. Membership in any of the rooms in the list grants the ability to join the target room.
"""
# If there's no join rule, then it defaults to invite (so this doesn't apply).
join_rules_event_id = state_ids.get((EventTypes.JoinRules, ""), None)
@@ -123,21 +128,25 @@ class EventAuthHandler:
join_rules_event = await self._store.get_event(join_rules_event_id)
# If allowed is of the wrong form, then only allow invited users.
- allowed_spaces = join_rules_event.content.get("allow", [])
- if not isinstance(allowed_spaces, list):
+ allow_list = join_rules_event.content.get("allow", [])
+ if not isinstance(allow_list, list):
return ()
# Pull out the other room IDs, invalid data gets filtered.
result = []
- for space in allowed_spaces:
- if not isinstance(space, dict):
+ for allow in allow_list:
+ if not isinstance(allow, dict):
+ continue
+
+ # If the type is unexpected, skip it.
+ if allow.get("type") != RestrictedJoinRuleTypes.ROOM_MEMBERSHIP:
continue
- space_id = space.get("space")
- if not isinstance(space_id, str):
+ room_id = allow.get("room_id")
+ if not isinstance(room_id, str):
continue
- result.append(space_id)
+ result.append(room_id)
return result
diff --git a/synapse/handlers/space_summary.py b/synapse/handlers/space_summary.py
index 73d2aab15c..e953a8afe6 100644
--- a/synapse/handlers/space_summary.py
+++ b/synapse/handlers/space_summary.py
@@ -160,14 +160,14 @@ class SpaceSummaryHandler:
# Check if the user is a member of any of the allowed spaces
# from the response.
- allowed_spaces = room.get("allowed_spaces")
+ allowed_rooms = room.get("allowed_spaces")
if (
not include_room
- and allowed_spaces
- and isinstance(allowed_spaces, list)
+ and allowed_rooms
+ and isinstance(allowed_rooms, list)
):
include_room = await self._event_auth_handler.is_user_in_rooms(
- allowed_spaces, requester
+ allowed_rooms, requester
)
# Finally, if this isn't the requested room, check ourselves
@@ -455,11 +455,11 @@ class SpaceSummaryHandler:
if self._event_auth_handler.has_restricted_join_rules(
state_ids, room_version
):
- allowed_spaces = (
- await self._event_auth_handler.get_spaces_that_allow_join(state_ids)
+ allowed_rooms = (
+ await self._event_auth_handler.get_rooms_that_allow_join(state_ids)
)
if await self._event_auth_handler.is_user_in_rooms(
- allowed_spaces, requester
+ allowed_rooms, requester
):
return True
@@ -475,10 +475,10 @@ class SpaceSummaryHandler:
if await self._event_auth_handler.has_restricted_join_rules(
state_ids, room_version
):
- allowed_spaces = (
- await self._event_auth_handler.get_spaces_that_allow_join(state_ids)
+ allowed_rooms = (
+ await self._event_auth_handler.get_rooms_that_allow_join(state_ids)
)
- for space_id in allowed_spaces:
+ for space_id in allowed_rooms:
if await self._auth.check_host_in_room(space_id, origin):
return True
@@ -512,11 +512,11 @@ class SpaceSummaryHandler:
)
room_version = await self._store.get_room_version(room_id)
- allowed_spaces = None
+ allowed_rooms = None
if await self._event_auth_handler.has_restricted_join_rules(
current_state_ids, room_version
):
- allowed_spaces = await self._event_auth_handler.get_spaces_that_allow_join(
+ allowed_rooms = await self._event_auth_handler.get_rooms_that_allow_join(
current_state_ids
)
@@ -533,7 +533,7 @@ class SpaceSummaryHandler:
"guest_can_join": stats["guest_access"] == "can_join",
"creation_ts": create_event.origin_server_ts,
"room_type": create_event.content.get(EventContentFields.ROOM_TYPE),
- "allowed_spaces": allowed_spaces,
+ "allowed_spaces": allowed_rooms,
}
# Filter out Nones – rather omit the field altogether
|