@@ -106,6 +106,18 @@ def check(
106106 if not event .signatures .get (event_id_domain ):
107107 raise AuthError (403 , "Event not signed by sending server" )
108108
109+ is_invite_via_allow_rule = (
110+ event .type == EventTypes .Member
111+ and event .membership == Membership .JOIN
112+ and "join_authorised_via_users_server" in event .content
113+ )
114+ if is_invite_via_allow_rule :
115+ authoriser_domain = get_domain_from_id (
116+ event .content ["join_authorised_via_users_server" ]
117+ )
118+ if not event .signatures .get (authoriser_domain ):
119+ raise AuthError (403 , "Event not signed by authorising server" )
120+
109121 # Implementation of https://matrix.org/docs/spec/rooms/v1#authorization-rules
110122 #
111123 # 1. If type is m.room.create:
@@ -177,7 +189,7 @@ def check(
177189 # https://github.com/vector-im/vector-web/issues/1208 hopefully
178190 if event .type == EventTypes .ThirdPartyInvite :
179191 user_level = get_user_power_level (event .user_id , auth_events )
180- invite_level = _get_named_level (auth_events , "invite" , 0 )
192+ invite_level = get_named_level (auth_events , "invite" , 0 )
181193
182194 if user_level < invite_level :
183195 raise AuthError (403 , "You don't have permission to invite users" )
@@ -285,8 +297,8 @@ def _is_membership_change_allowed(
285297 user_level = get_user_power_level (event .user_id , auth_events )
286298 target_level = get_user_power_level (target_user_id , auth_events )
287299
288- # FIXME (erikj): What should we do here as the default?
289- ban_level = _get_named_level (auth_events , "ban" , 50 )
300+ invite_level = get_named_level ( auth_events , "invite" , 0 )
301+ ban_level = get_named_level (auth_events , "ban" , 50 )
290302
291303 logger .debug (
292304 "_is_membership_change_allowed: %s" ,
@@ -336,25 +348,48 @@ def _is_membership_change_allowed(
336348 elif target_in_room : # the target is already in the room.
337349 raise AuthError (403 , "%s is already in the room." % target_user_id )
338350 else :
339- invite_level = _get_named_level (auth_events , "invite" , 0 )
340-
341351 if user_level < invite_level :
342352 raise AuthError (403 , "You don't have permission to invite users" )
343353 elif Membership .JOIN == membership :
344354 # Joins are valid iff caller == target and:
345355 # * They are not banned.
346356 # * They are accepting a previously sent invitation.
347357 # * They are already joined (it's a NOOP).
348- # * The room is public or restricted.
358+ # * The room is public.
359+ # * The room is restricted and the user meets the allows rules.
349360 if event .user_id != target_user_id :
350361 raise AuthError (403 , "Cannot force another user to join." )
351362 elif target_banned :
352363 raise AuthError (403 , "You are banned from this room" )
353- elif join_rule == JoinRules .PUBLIC or (
364+ elif join_rule == JoinRules .PUBLIC :
365+ pass
366+ elif (
354367 room_version .msc3083_join_rules
355368 and join_rule == JoinRules .MSC3083_RESTRICTED
356369 ):
357- pass
370+ # This is the same as public, but the event must contain a reference
371+ # to the server who authorised the join. If the event does not contain
372+ # the proper content it is rejected.
373+ #
374+ # Note that if the caller is in the room or invited, then they do
375+ # not need to meet the allow rules.
376+ if not caller_in_room and not caller_invited :
377+ authorising_user = event .content .get ("join_authorised_via_users_server" )
378+
379+ if authorising_user is None :
380+ raise AuthError (403 , "Join event is missing authorising user." )
381+
382+ # The authorising user must be in the room.
383+ key = (EventTypes .Member , authorising_user )
384+ member_event = auth_events .get (key )
385+ _check_joined_room (member_event , authorising_user , event .room_id )
386+
387+ authorising_user_level = get_user_power_level (
388+ authorising_user , auth_events
389+ )
390+ if authorising_user_level < invite_level :
391+ raise AuthError (403 , "Join event authorised by invalid server." )
392+
358393 elif join_rule == JoinRules .INVITE or (
359394 room_version .msc2403_knocking and join_rule == JoinRules .KNOCK
360395 ):
@@ -369,7 +404,7 @@ def _is_membership_change_allowed(
369404 if target_banned and user_level < ban_level :
370405 raise AuthError (403 , "You cannot unban user %s." % (target_user_id ,))
371406 elif target_user_id != event .user_id :
372- kick_level = _get_named_level (auth_events , "kick" , 50 )
407+ kick_level = get_named_level (auth_events , "kick" , 50 )
373408
374409 if user_level < kick_level or user_level <= target_level :
375410 raise AuthError (403 , "You cannot kick user %s." % target_user_id )
@@ -445,7 +480,7 @@ def get_send_level(
445480
446481
447482def _can_send_event (event : EventBase , auth_events : StateMap [EventBase ]) -> bool :
448- power_levels_event = _get_power_level_event (auth_events )
483+ power_levels_event = get_power_level_event (auth_events )
449484
450485 send_level = get_send_level (event .type , event .get ("state_key" ), power_levels_event )
451486 user_level = get_user_power_level (event .user_id , auth_events )
@@ -485,7 +520,7 @@ def check_redaction(
485520 """
486521 user_level = get_user_power_level (event .user_id , auth_events )
487522
488- redact_level = _get_named_level (auth_events , "redact" , 50 )
523+ redact_level = get_named_level (auth_events , "redact" , 50 )
489524
490525 if user_level >= redact_level :
491526 return False
@@ -600,7 +635,7 @@ def _check_power_levels(
600635 )
601636
602637
603- def _get_power_level_event (auth_events : StateMap [EventBase ]) -> Optional [EventBase ]:
638+ def get_power_level_event (auth_events : StateMap [EventBase ]) -> Optional [EventBase ]:
604639 return auth_events .get ((EventTypes .PowerLevels , "" ))
605640
606641
@@ -616,7 +651,7 @@ def get_user_power_level(user_id: str, auth_events: StateMap[EventBase]) -> int:
616651 Returns:
617652 the user's power level in this room.
618653 """
619- power_level_event = _get_power_level_event (auth_events )
654+ power_level_event = get_power_level_event (auth_events )
620655 if power_level_event :
621656 level = power_level_event .content .get ("users" , {}).get (user_id )
622657 if not level :
@@ -640,8 +675,8 @@ def get_user_power_level(user_id: str, auth_events: StateMap[EventBase]) -> int:
640675 return 0
641676
642677
643- def _get_named_level (auth_events : StateMap [EventBase ], name : str , default : int ) -> int :
644- power_level_event = _get_power_level_event (auth_events )
678+ def get_named_level (auth_events : StateMap [EventBase ], name : str , default : int ) -> int :
679+ power_level_event = get_power_level_event (auth_events )
645680
646681 if not power_level_event :
647682 return default
@@ -728,7 +763,9 @@ def get_public_keys(invite_event: EventBase) -> List[Dict[str, Any]]:
728763 return public_keys
729764
730765
731- def auth_types_for_event (event : Union [EventBase , EventBuilder ]) -> Set [Tuple [str , str ]]:
766+ def auth_types_for_event (
767+ room_version : RoomVersion , event : Union [EventBase , EventBuilder ]
768+ ) -> Set [Tuple [str , str ]]:
732769 """Given an event, return a list of (EventType, StateKey) that may be
733770 needed to auth the event. The returned list may be a superset of what
734771 would actually be required depending on the full state of the room.
@@ -760,4 +797,12 @@ def auth_types_for_event(event: Union[EventBase, EventBuilder]) -> Set[Tuple[str
760797 )
761798 auth_types .add (key )
762799
800+ if room_version .msc3083_join_rules and membership == Membership .JOIN :
801+ if "join_authorised_via_users_server" in event .content :
802+ key = (
803+ EventTypes .Member ,
804+ event .content ["join_authorised_via_users_server" ],
805+ )
806+ auth_types .add (key )
807+
763808 return auth_types
0 commit comments