Skip to content

Commit 78c255e

Browse files
authored
Add TestRestrictedRoomsLocalJoinNoCreatorsUsesPowerLevels (#836)
Adds a test to prevent regressions fixed by element-hq/synapse#19321. Reproduce element-hq/synapse#19120
1 parent 46290be commit 78c255e

File tree

2 files changed

+112
-0
lines changed

2 files changed

+112
-0
lines changed

tests/knock_restricted_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,13 @@ func TestRestrictedRoomsRemoteJoinLocalUserInMSC3787Room(t *testing.T) {
7979
func TestRestrictedRoomsRemoteJoinFailOverInMSC3787Room(t *testing.T) {
8080
doTestRestrictedRoomsRemoteJoinFailOver(t, roomVersion, joinRule)
8181
}
82+
83+
// See docstring on `TestRestrictedRoomsLocalJoinNoCreatorsUsesPowerLevelsV12`
84+
func TestKnockRestrictedRoomsLocalJoinNoCreatorsUsesPowerLevelsV12(t *testing.T) {
85+
doTestRestrictedRoomsLocalJoinNoCreatorsUsesPowerLevels(t, "12", "knock_restricted")
86+
}
87+
88+
// See docstring on `TestRestrictedRoomsLocalJoinNoCreatorsUsesPowerLevelsV12`
89+
func TestKnockRestrictedRoomsLocalJoinNoCreatorsUsesPowerLevelsV11(t *testing.T) {
90+
doTestRestrictedRoomsLocalJoinNoCreatorsUsesPowerLevels(t, "11", "knock_restricted")
91+
}

tests/restricted_rooms_test.go

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)