@@ -106,6 +106,18 @@ def check(
106
106
if not event .signatures .get (event_id_domain ):
107
107
raise AuthError (403 , "Event not signed by sending server" )
108
108
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
+
109
121
# Implementation of https://matrix.org/docs/spec/rooms/v1#authorization-rules
110
122
#
111
123
# 1. If type is m.room.create:
@@ -177,7 +189,7 @@ def check(
177
189
# https://github.com/vector-im/vector-web/issues/1208 hopefully
178
190
if event .type == EventTypes .ThirdPartyInvite :
179
191
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 )
181
193
182
194
if user_level < invite_level :
183
195
raise AuthError (403 , "You don't have permission to invite users" )
@@ -285,8 +297,8 @@ def _is_membership_change_allowed(
285
297
user_level = get_user_power_level (event .user_id , auth_events )
286
298
target_level = get_user_power_level (target_user_id , auth_events )
287
299
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 )
290
302
291
303
logger .debug (
292
304
"_is_membership_change_allowed: %s" ,
@@ -336,25 +348,48 @@ def _is_membership_change_allowed(
336
348
elif target_in_room : # the target is already in the room.
337
349
raise AuthError (403 , "%s is already in the room." % target_user_id )
338
350
else :
339
- invite_level = _get_named_level (auth_events , "invite" , 0 )
340
-
341
351
if user_level < invite_level :
342
352
raise AuthError (403 , "You don't have permission to invite users" )
343
353
elif Membership .JOIN == membership :
344
354
# Joins are valid iff caller == target and:
345
355
# * They are not banned.
346
356
# * They are accepting a previously sent invitation.
347
357
# * 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.
349
360
if event .user_id != target_user_id :
350
361
raise AuthError (403 , "Cannot force another user to join." )
351
362
elif target_banned :
352
363
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 (
354
367
room_version .msc3083_join_rules
355
368
and join_rule == JoinRules .MSC3083_RESTRICTED
356
369
):
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
+
358
393
elif join_rule == JoinRules .INVITE or (
359
394
room_version .msc2403_knocking and join_rule == JoinRules .KNOCK
360
395
):
@@ -369,7 +404,7 @@ def _is_membership_change_allowed(
369
404
if target_banned and user_level < ban_level :
370
405
raise AuthError (403 , "You cannot unban user %s." % (target_user_id ,))
371
406
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 )
373
408
374
409
if user_level < kick_level or user_level <= target_level :
375
410
raise AuthError (403 , "You cannot kick user %s." % target_user_id )
@@ -445,7 +480,7 @@ def get_send_level(
445
480
446
481
447
482
def _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 )
449
484
450
485
send_level = get_send_level (event .type , event .get ("state_key" ), power_levels_event )
451
486
user_level = get_user_power_level (event .user_id , auth_events )
@@ -485,7 +520,7 @@ def check_redaction(
485
520
"""
486
521
user_level = get_user_power_level (event .user_id , auth_events )
487
522
488
- redact_level = _get_named_level (auth_events , "redact" , 50 )
523
+ redact_level = get_named_level (auth_events , "redact" , 50 )
489
524
490
525
if user_level >= redact_level :
491
526
return False
@@ -600,7 +635,7 @@ def _check_power_levels(
600
635
)
601
636
602
637
603
- def _get_power_level_event (auth_events : StateMap [EventBase ]) -> Optional [EventBase ]:
638
+ def get_power_level_event (auth_events : StateMap [EventBase ]) -> Optional [EventBase ]:
604
639
return auth_events .get ((EventTypes .PowerLevels , "" ))
605
640
606
641
@@ -616,7 +651,7 @@ def get_user_power_level(user_id: str, auth_events: StateMap[EventBase]) -> int:
616
651
Returns:
617
652
the user's power level in this room.
618
653
"""
619
- power_level_event = _get_power_level_event (auth_events )
654
+ power_level_event = get_power_level_event (auth_events )
620
655
if power_level_event :
621
656
level = power_level_event .content .get ("users" , {}).get (user_id )
622
657
if not level :
@@ -640,8 +675,8 @@ def get_user_power_level(user_id: str, auth_events: StateMap[EventBase]) -> int:
640
675
return 0
641
676
642
677
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 )
645
680
646
681
if not power_level_event :
647
682
return default
@@ -728,7 +763,9 @@ def get_public_keys(invite_event: EventBase) -> List[Dict[str, Any]]:
728
763
return public_keys
729
764
730
765
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 ]]:
732
769
"""Given an event, return a list of (EventType, StateKey) that may be
733
770
needed to auth the event. The returned list may be a superset of what
734
771
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
760
797
)
761
798
auth_types .add (key )
762
799
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
+
763
808
return auth_types
0 commit comments