Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updates to tests for restricted rooms based on changes to MSC3083. #145

Merged
merged 8 commits into from
Jul 26, 2021
134 changes: 131 additions & 3 deletions tests/msc3083_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ func setupRestrictedRoom(t *testing.T, deployment *docker.Deployment) (*client.C
room := alice.CreateRoom(t, map[string]interface{}{
"preset": "public_chat",
"name": "Room",
"room_version": "org.matrix.msc3083",
"room_version": "org.matrix.msc3083.v2",
"initial_state": []map[string]interface{}{
{
"type": "m.room.join_rules",
Expand Down Expand Up @@ -90,6 +90,9 @@ func checkRestrictedRoom(t *testing.T, alice *client.CSAPI, bob *client.CSAPI, s
bob.JoinRoom(t, space, []string{"hs1"})
bob.JoinRoom(t, room, []string{"hs1"})

// Joining the same room again should work fine (e.g. to change your display name).
bob.JoinRoom(t, room, []string{"hs1"})

// Leaving the room works and the user is unable to re-join.
bob.LeaveRoom(t, room)
bob.LeaveRoom(t, space)
Expand Down Expand Up @@ -181,6 +184,131 @@ func TestRestrictedRoomsRemoteJoin(t *testing.T) {
checkRestrictedRoom(t, alice, bob, space, room)
}

// A server will do a remote join for a local user if it is unable to to issue
// joins in a restricted room it is already participating in.
func TestRestrictedRoomsRemoteJoinLocalUser(t *testing.T) {
deployment := Deploy(t, b.BlueprintFederationTwoLocalOneRemote)
defer deployment.Destroy(t)

// Charlie sets up the space so it is on the other server.
charlie := deployment.Client(t, "hs2", "@charlie:hs2")
space := charlie.CreateRoom(t, map[string]interface{}{
"preset": "public_chat",
"name": "Space",
"creation_content": map[string]interface{}{
"type": "m.space",
},
})
// The room is an unstable room version which supports the restricted join_rule.
room := charlie.CreateRoom(t, map[string]interface{}{
"preset": "public_chat",
"name": "Room",
"room_version": "org.matrix.msc3083.v2",
"initial_state": []map[string]interface{}{
{
"type": "m.room.join_rules",
"state_key": "",
"content": map[string]interface{}{
"join_rule": "restricted",
"allow": []map[string]interface{}{
{
"type": "m.room_membership",
"room_id": &space,
"via": []string{"hs2"},
},
},
},
},
},
})
charlie.SendEventSynced(t, space, b.Event{
Type: "m.space.child",
StateKey: &room,
Content: map[string]interface{}{
"via": []string{"hs2"},
},
})

// Invite alice manually and accept it.
alice := deployment.Client(t, "hs1", "@alice:hs1")
charlie.InviteRoom(t, room, alice.UserID)
alice.JoinRoom(t, room, []string{"hs2"})

// Confirm that Alice cannot issue invites (due to the default power levels).
bob := deployment.Client(t, "hs1", "@bob:hs1")
body := map[string]interface{}{
"user_id": bob.UserID,
}
res := alice.DoFunc(
t,
"POST",
[]string{"_matrix", "client", "r0", "rooms", room, "invite"},
client.WithJSONBody(t, body),
)
must.MatchResponse(t, res, match.HTTPResponse{
StatusCode: 403,
})

// Bob cannot join the room.
failJoinRoom(t, bob, room, "hs1")

// Join the space via hs2.
bob.JoinRoom(t, space, []string{"hs2"})
// Joining the room should work, although we're joining via hs1, it will end up
// as a remote join through hs2.
bob.JoinRoom(t, room, []string{"hs1"})

// Ensure that the join comes down sync on hs2. Note that we want to ensure hs2
// accepted the event.
charlie.SyncUntilTimelineHas(
t,
room,
func(ev gjson.Result) bool {
if ev.Get("type").Str != "m.room.member" || ev.Get("state_key").Str != bob.UserID {
return false
}
must.EqualStr(t, ev.Get("sender").Str, bob.UserID, "Bob should have joined by himself")
must.EqualStr(t, ev.Get("content").Get("membership").Str, "join", "Bob failed to join the room")

return true
},
)

// Raise the power level so that users on hs1 can invite people and then leave
// the room.
state_key := ""
charlie.SendEventSynced(t, room, b.Event{
Type: "m.room.power_levels",
StateKey: &state_key,
Content: map[string]interface{}{
"invite": 0,
"users": map[string]interface{}{
charlie.UserID: 100,
},
},
})
charlie.LeaveRoom(t, room)

// Ensure the events have synced to hs1.
alice.SyncUntilTimelineHas(
t,
room,
func(ev gjson.Result) bool {
if ev.Get("type").Str != "m.room.member" || ev.Get("state_key").Str != charlie.UserID {
return false
}
must.EqualStr(t, ev.Get("content").Get("membership").Str, "leave", "Charlie failed to leave the room")

return true
},
)

// Have bob leave and rejoin. This should still work even though hs2 isn't in
// the room anymore!
bob.LeaveRoom(t, room)
bob.JoinRoom(t, room, []string{"hs1"})
}

// Request the room summary and ensure the expected rooms are in the response.
func requestAndAssertSummary(t *testing.T, user *client.CSAPI, space string, expected_rooms []interface{}) {
t.Helper()
Expand Down Expand Up @@ -229,7 +357,7 @@ func TestRestrictedRoomsSpacesSummary(t *testing.T) {
room := alice.CreateRoom(t, map[string]interface{}{
"preset": "public_chat",
"name": "Room",
"room_version": "org.matrix.msc3083",
"room_version": "org.matrix.msc3083.v2",
"initial_state": []map[string]interface{}{
{
"type": "m.room.join_rules",
Expand Down Expand Up @@ -312,7 +440,7 @@ func TestRestrictedRoomsSpacesSummaryFederation(t *testing.T) {
room := charlie.CreateRoom(t, map[string]interface{}{
"preset": "public_chat",
"name": "Room",
"room_version": "org.matrix.msc3083",
"room_version": "org.matrix.msc3083.v2",
"initial_state": []map[string]interface{}{
{
"type": "m.room.join_rules",
Expand Down