@@ -446,3 +446,105 @@ func doTestRestrictedRoomsRemoteJoinFailOver(t *testing.T, roomVersion string, j
446446 return true
447447 }))
448448}
449+
450+ // A homeserver should be able to do a local join (when someone else from the same
451+ // homeserver is already joined to the room) to a room using any local user who has
452+ // invite power levels.
453+ //
454+ // In the test case, there are no local room creators on hs2, so hs2 will need to use
455+ // one of the local people listed in the power levels who can invite. While hs2, could
456+ // do another remote join to get charlie in the room, we assert it was a local join by
457+ // checking the `join_authorised_via_users_server` (homeservers should prefer a local
458+ // join).
459+ //
460+ // This is a regression test for Synapse as it previously only looked for local room
461+ // creators in v12 rooms, https://github.com/element-hq/synapse/issues/19120
462+ func TestRestrictedRoomsLocalJoinNoCreatorsUsesPowerLevelsV12 (t * testing.T ) {
463+ doTestRestrictedRoomsLocalJoinNoCreatorsUsesPowerLevels (t , "12" , "restricted" )
464+ }
465+
466+ // See docstring on `TestRestrictedRoomsLocalJoinNoCreatorsUsesPowerLevelsV12`
467+ func TestRestrictedRoomsLocalJoinNoCreatorsUsesPowerLevelsV11 (t * testing.T ) {
468+ doTestRestrictedRoomsLocalJoinNoCreatorsUsesPowerLevels (t , "11" , "restricted" )
469+ }
470+
471+ func doTestRestrictedRoomsLocalJoinNoCreatorsUsesPowerLevels (t * testing.T , roomVersion string , joinRule string ) {
472+ deployment := complement .Deploy (t , 2 )
473+ defer deployment .Destroy (t )
474+ // Create the room
475+ alice , allowed_room , room := setupRestrictedRoom (t , deployment , roomVersion , joinRule )
476+ // Create two users on the other homeserver.
477+ bob := deployment .Register (t , "hs2" , helpers.RegistrationOpts {})
478+ charlie := deployment .Register (t , "hs2" , helpers.RegistrationOpts {})
479+
480+ // Bob joins the allowed room.
481+ bob .JoinRoom (t , allowed_room , []spec.ServerName {
482+ deployment .GetFullyQualifiedHomeserverName (t , "hs1" ),
483+ })
484+ // Bob joins the restricted room. This join should go remotely
485+ // and consequently be authorised by Alice (on hs1) as she is the only
486+ // member.
487+ bob .JoinRoom (t , room , []spec.ServerName {
488+ deployment .GetFullyQualifiedHomeserverName (t , "hs1" ),
489+ })
490+ // Ensure the join was authorised by alice
491+ bob .MustSyncUntil (t , client.SyncReq {}, client .SyncJoinedTo (bob .UserID , room , func (ev gjson.Result ) bool {
492+ must .MatchGJSON (t , ev ,
493+ match .JSONKeyEqual ("content.join_authorised_via_users_server" , alice .UserID ),
494+ )
495+ return true
496+ }))
497+
498+ // Alice restricts the invite power level to moderators and promotes Bob to
499+ // moderator.
500+ state_key := ""
501+ if roomVersion == "12" {
502+ // Alice is a creator and cannot appear in the power levels
503+ alice .SendEventSynced (t , room , b.Event {
504+ Type : "m.room.power_levels" ,
505+ StateKey : & state_key ,
506+ Content : map [string ]interface {}{
507+ "invite" : 50 ,
508+ "users" : map [string ]interface {}{
509+ bob .UserID : 50 ,
510+ },
511+ },
512+ })
513+ } else {
514+ // rooms <v12 need alice to be in the power levels to retain power
515+ alice .SendEventSynced (t , room , b.Event {
516+ Type : "m.room.power_levels" ,
517+ StateKey : & state_key ,
518+ Content : map [string ]interface {}{
519+ "invite" : 50 ,
520+ "users" : map [string ]interface {}{
521+ alice .UserID : 100 ,
522+ bob .UserID : 50 ,
523+ },
524+ },
525+ })
526+ }
527+
528+ // Charlie joins the allowed room.
529+ charlie .JoinRoom (t , allowed_room , []spec.ServerName {
530+ deployment .GetFullyQualifiedHomeserverName (t , "hs1" ),
531+ })
532+ // Charlie attempts to join the restricted room.
533+ // hs2 should use bob to authorise the join as he is a local user with
534+ // invite power levels.
535+ // If the server did not correctly detect that bob could issue an invite,
536+ // this join would instead be a remote join authorised via @alice:hs1.
537+ charlie .JoinRoom (t , room , []spec.ServerName {
538+ deployment .GetFullyQualifiedHomeserverName (t , "hs2" ),
539+ })
540+
541+ // Ensure the join was authorised by bob. The join should not be
542+ // authorised by alice as hs2 should not have attempted a remote
543+ // join given bob is a local user that can authorise the join.
544+ bob .MustSyncUntil (t , client.SyncReq {}, client .SyncJoinedTo (charlie .UserID , room , func (ev gjson.Result ) bool {
545+ must .MatchGJSON (t , ev ,
546+ match .JSONKeyEqual ("content.join_authorised_via_users_server" , bob .UserID ),
547+ )
548+ return true
549+ }))
550+ }
0 commit comments