Add a new room version for MSC3787's knock+restricted join rule (#12623)

This commit is contained in:
Travis Ralston 2022-05-17 04:41:39 -06:00 committed by GitHub
parent 24b590de32
commit 942c30b16b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 68 additions and 7 deletions

View File

@ -0,0 +1 @@
Add support for [MSC3787: Allowing knocks to restricted rooms](https://github.com/matrix-org/matrix-spec-proposals/pull/3787).

View File

@ -65,6 +65,8 @@ class JoinRules:
PRIVATE: Final = "private" PRIVATE: Final = "private"
# As defined for MSC3083. # As defined for MSC3083.
RESTRICTED: Final = "restricted" RESTRICTED: Final = "restricted"
# As defined for MSC3787.
KNOCK_RESTRICTED: Final = "knock_restricted"
class RestrictedJoinRuleTypes: class RestrictedJoinRuleTypes:

View File

@ -81,6 +81,9 @@ class RoomVersion:
msc2716_historical: bool msc2716_historical: bool
# MSC2716: Adds support for redacting "insertion", "chunk", and "marker" events # MSC2716: Adds support for redacting "insertion", "chunk", and "marker" events
msc2716_redactions: bool msc2716_redactions: bool
# MSC3787: Adds support for a `knock_restricted` join rule, mixing concepts of
# knocks and restricted join rules into the same join condition.
msc3787_knock_restricted_join_rule: bool
class RoomVersions: class RoomVersions:
@ -99,6 +102,7 @@ class RoomVersions:
msc2403_knocking=False, msc2403_knocking=False,
msc2716_historical=False, msc2716_historical=False,
msc2716_redactions=False, msc2716_redactions=False,
msc3787_knock_restricted_join_rule=False,
) )
V2 = RoomVersion( V2 = RoomVersion(
"2", "2",
@ -115,6 +119,7 @@ class RoomVersions:
msc2403_knocking=False, msc2403_knocking=False,
msc2716_historical=False, msc2716_historical=False,
msc2716_redactions=False, msc2716_redactions=False,
msc3787_knock_restricted_join_rule=False,
) )
V3 = RoomVersion( V3 = RoomVersion(
"3", "3",
@ -131,6 +136,7 @@ class RoomVersions:
msc2403_knocking=False, msc2403_knocking=False,
msc2716_historical=False, msc2716_historical=False,
msc2716_redactions=False, msc2716_redactions=False,
msc3787_knock_restricted_join_rule=False,
) )
V4 = RoomVersion( V4 = RoomVersion(
"4", "4",
@ -147,6 +153,7 @@ class RoomVersions:
msc2403_knocking=False, msc2403_knocking=False,
msc2716_historical=False, msc2716_historical=False,
msc2716_redactions=False, msc2716_redactions=False,
msc3787_knock_restricted_join_rule=False,
) )
V5 = RoomVersion( V5 = RoomVersion(
"5", "5",
@ -163,6 +170,7 @@ class RoomVersions:
msc2403_knocking=False, msc2403_knocking=False,
msc2716_historical=False, msc2716_historical=False,
msc2716_redactions=False, msc2716_redactions=False,
msc3787_knock_restricted_join_rule=False,
) )
V6 = RoomVersion( V6 = RoomVersion(
"6", "6",
@ -179,6 +187,7 @@ class RoomVersions:
msc2403_knocking=False, msc2403_knocking=False,
msc2716_historical=False, msc2716_historical=False,
msc2716_redactions=False, msc2716_redactions=False,
msc3787_knock_restricted_join_rule=False,
) )
MSC2176 = RoomVersion( MSC2176 = RoomVersion(
"org.matrix.msc2176", "org.matrix.msc2176",
@ -195,6 +204,7 @@ class RoomVersions:
msc2403_knocking=False, msc2403_knocking=False,
msc2716_historical=False, msc2716_historical=False,
msc2716_redactions=False, msc2716_redactions=False,
msc3787_knock_restricted_join_rule=False,
) )
V7 = RoomVersion( V7 = RoomVersion(
"7", "7",
@ -211,6 +221,7 @@ class RoomVersions:
msc2403_knocking=True, msc2403_knocking=True,
msc2716_historical=False, msc2716_historical=False,
msc2716_redactions=False, msc2716_redactions=False,
msc3787_knock_restricted_join_rule=False,
) )
V8 = RoomVersion( V8 = RoomVersion(
"8", "8",
@ -227,6 +238,7 @@ class RoomVersions:
msc2403_knocking=True, msc2403_knocking=True,
msc2716_historical=False, msc2716_historical=False,
msc2716_redactions=False, msc2716_redactions=False,
msc3787_knock_restricted_join_rule=False,
) )
V9 = RoomVersion( V9 = RoomVersion(
"9", "9",
@ -243,6 +255,7 @@ class RoomVersions:
msc2403_knocking=True, msc2403_knocking=True,
msc2716_historical=False, msc2716_historical=False,
msc2716_redactions=False, msc2716_redactions=False,
msc3787_knock_restricted_join_rule=False,
) )
MSC2716v3 = RoomVersion( MSC2716v3 = RoomVersion(
"org.matrix.msc2716v3", "org.matrix.msc2716v3",
@ -259,6 +272,24 @@ class RoomVersions:
msc2403_knocking=True, msc2403_knocking=True,
msc2716_historical=True, msc2716_historical=True,
msc2716_redactions=True, msc2716_redactions=True,
msc3787_knock_restricted_join_rule=False,
)
MSC3787 = RoomVersion(
"org.matrix.msc3787",
RoomDisposition.UNSTABLE,
EventFormatVersions.V3,
StateResolutionVersions.V2,
enforce_key_validity=True,
special_case_aliases_auth=False,
strict_canonicaljson=True,
limit_notifications_power_levels=True,
msc2176_redaction_rules=False,
msc3083_join_rules=True,
msc3375_redaction_rules=True,
msc2403_knocking=True,
msc2716_historical=False,
msc2716_redactions=False,
msc3787_knock_restricted_join_rule=True,
) )
@ -276,6 +307,7 @@ KNOWN_ROOM_VERSIONS: Dict[str, RoomVersion] = {
RoomVersions.V8, RoomVersions.V8,
RoomVersions.V9, RoomVersions.V9,
RoomVersions.MSC2716v3, RoomVersions.MSC2716v3,
RoomVersions.MSC3787,
) )
} }

View File

@ -414,7 +414,12 @@ def _is_membership_change_allowed(
raise AuthError(403, "You are banned from this room") raise AuthError(403, "You are banned from this room")
elif join_rule == JoinRules.PUBLIC: elif join_rule == JoinRules.PUBLIC:
pass pass
elif room_version.msc3083_join_rules and join_rule == JoinRules.RESTRICTED: elif (
room_version.msc3083_join_rules and join_rule == JoinRules.RESTRICTED
) or (
room_version.msc3787_knock_restricted_join_rule
and join_rule == JoinRules.KNOCK_RESTRICTED
):
# This is the same as public, but the event must contain a reference # This is the same as public, but the event must contain a reference
# to the server who authorised the join. If the event does not contain # to the server who authorised the join. If the event does not contain
# the proper content it is rejected. # the proper content it is rejected.
@ -440,8 +445,13 @@ def _is_membership_change_allowed(
if authorising_user_level < invite_level: if authorising_user_level < invite_level:
raise AuthError(403, "Join event authorised by invalid server.") raise AuthError(403, "Join event authorised by invalid server.")
elif join_rule == JoinRules.INVITE or ( elif (
room_version.msc2403_knocking and join_rule == JoinRules.KNOCK join_rule == JoinRules.INVITE
or (room_version.msc2403_knocking and join_rule == JoinRules.KNOCK)
or (
room_version.msc3787_knock_restricted_join_rule
and join_rule == JoinRules.KNOCK_RESTRICTED
)
): ):
if not caller_in_room and not caller_invited: if not caller_in_room and not caller_invited:
raise AuthError(403, "You are not invited to this room.") raise AuthError(403, "You are not invited to this room.")
@ -462,7 +472,10 @@ def _is_membership_change_allowed(
if user_level < ban_level or user_level <= target_level: if user_level < ban_level or user_level <= target_level:
raise AuthError(403, "You don't have permission to ban") raise AuthError(403, "You don't have permission to ban")
elif room_version.msc2403_knocking and Membership.KNOCK == membership: elif room_version.msc2403_knocking and Membership.KNOCK == membership:
if join_rule != JoinRules.KNOCK: if join_rule != JoinRules.KNOCK and (
not room_version.msc3787_knock_restricted_join_rule
or join_rule != JoinRules.KNOCK_RESTRICTED
):
raise AuthError(403, "You don't have permission to knock") raise AuthError(403, "You don't have permission to knock")
elif target_user_id != event.user_id: elif target_user_id != event.user_id:
raise AuthError(403, "You cannot knock for other users") raise AuthError(403, "You cannot knock for other users")

View File

@ -241,7 +241,15 @@ class EventAuthHandler:
# If the join rule is not restricted, this doesn't apply. # If the join rule is not restricted, this doesn't apply.
join_rules_event = await self._store.get_event(join_rules_event_id) join_rules_event = await self._store.get_event(join_rules_event_id)
return join_rules_event.content.get("join_rule") == JoinRules.RESTRICTED content_join_rule = join_rules_event.content.get("join_rule")
if content_join_rule == JoinRules.RESTRICTED:
return True
# also check for MSC3787 behaviour
if room_version.msc3787_knock_restricted_join_rule:
return content_join_rule == JoinRules.KNOCK_RESTRICTED
return False
async def get_rooms_that_allow_join( async def get_rooms_that_allow_join(
self, state_ids: StateMap[str] self, state_ids: StateMap[str]

View File

@ -562,8 +562,13 @@ class RoomSummaryHandler:
if join_rules_event_id: if join_rules_event_id:
join_rules_event = await self._store.get_event(join_rules_event_id) join_rules_event = await self._store.get_event(join_rules_event_id)
join_rule = join_rules_event.content.get("join_rule") join_rule = join_rules_event.content.get("join_rule")
if join_rule == JoinRules.PUBLIC or ( if (
room_version.msc2403_knocking and join_rule == JoinRules.KNOCK join_rule == JoinRules.PUBLIC
or (room_version.msc2403_knocking and join_rule == JoinRules.KNOCK)
or (
room_version.msc3787_knock_restricted_join_rule
and join_rule == JoinRules.KNOCK_RESTRICTED
)
): ):
return True return True