Skip to content

Commit cc63dd2

Browse files
committed
Merge remote-tracking branch 'origin/master' into clokep/restricted-knocking
2 parents 7e5e1e6 + f254629 commit cc63dd2

File tree

1 file changed

+151
-7
lines changed

1 file changed

+151
-7
lines changed

tests/msc3083_test.go

Lines changed: 151 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import (
1818
"github.com/matrix-org/complement/internal/must"
1919
)
2020

21-
func failJoinRoom(t *testing.T, c *client.CSAPI, roomIDOrAlias string, serverName string) {
21+
func failJoinRoom(t *testing.T, c *client.CSAPI, roomIDOrAlias string, serverName string, expectedErrorCode int) {
2222
t.Helper()
2323

2424
// This is copied from Client.JoinRoom to test a join failure.
@@ -31,7 +31,7 @@ func failJoinRoom(t *testing.T, c *client.CSAPI, roomIDOrAlias string, serverNam
3131
client.WithQueries(query),
3232
)
3333
must.MatchResponse(t, res, match.HTTPResponse{
34-
StatusCode: 403,
34+
StatusCode: expectedErrorCode,
3535
})
3636
}
3737

@@ -85,7 +85,7 @@ func setupRestrictedRoom(t *testing.T, deployment *docker.Deployment) (*client.C
8585
func checkRestrictedRoom(t *testing.T, alice *client.CSAPI, bob *client.CSAPI, space string, room string) {
8686
t.Helper()
8787

88-
failJoinRoom(t, bob, room, "hs1")
88+
failJoinRoom(t, bob, room, "hs1", 403)
8989

9090
// Join the space, attempt to join the room again, which now should succeed.
9191
bob.JoinRoom(t, space, []string{"hs1"})
@@ -109,7 +109,7 @@ func checkRestrictedRoom(t *testing.T, alice *client.CSAPI, bob *client.CSAPI, s
109109
return ev.Get("content").Get("membership").Str == "leave"
110110
})
111111

112-
failJoinRoom(t, bob, room, "hs1")
112+
failJoinRoom(t, bob, room, "hs1", 403)
113113

114114
// Invite the user and joining should work.
115115
alice.InviteRoom(t, room, bob.UserID)
@@ -136,7 +136,7 @@ func checkRestrictedRoom(t *testing.T, alice *client.CSAPI, bob *client.CSAPI, s
136136
},
137137
)
138138
// Fails since invalid values get filtered out of allow.
139-
failJoinRoom(t, bob, room, "hs1")
139+
failJoinRoom(t, bob, room, "hs1", 403)
140140

141141
alice.SendEventSynced(
142142
t,
@@ -152,7 +152,7 @@ func checkRestrictedRoom(t *testing.T, alice *client.CSAPI, bob *client.CSAPI, s
152152
},
153153
)
154154
// Fails since a fully invalid allow key requires an invite.
155-
failJoinRoom(t, bob, room, "hs1")
155+
failJoinRoom(t, bob, room, "hs1", 403)
156156
}
157157

158158
// Test joining a room with join rules restricted to membership in a space.
@@ -251,7 +251,7 @@ func TestRestrictedRoomsRemoteJoinLocalUser(t *testing.T) {
251251
})
252252

253253
// Bob cannot join the room.
254-
failJoinRoom(t, bob, room, "hs1")
254+
failJoinRoom(t, bob, room, "hs1", 403)
255255

256256
// Join the space via hs2.
257257
bob.JoinRoom(t, space, []string{"hs2"})
@@ -310,6 +310,150 @@ func TestRestrictedRoomsRemoteJoinLocalUser(t *testing.T) {
310310
bob.JoinRoom(t, room, []string{"hs1"})
311311
}
312312

313+
// A server will request a failover if asked to /make_join and it does not have
314+
// the appropriate authorisation to complete the request.
315+
//
316+
// Setup 3 homeservers:
317+
// * hs1 creates the space/room.
318+
// * hs2 joins the room
319+
// * hs3 attempts to join via hs2 (should fail) and hs1 (should work)
320+
func TestRestrictedRoomsRemoteJoinFailOver(t *testing.T) {
321+
deployment := Deploy(t, b.Blueprint{
322+
Name: "federation_three_homeservers",
323+
Homeservers: []b.Homeserver{
324+
{
325+
Name: "hs1",
326+
Users: []b.User{
327+
{
328+
Localpart: "alice",
329+
DisplayName: "Alice",
330+
},
331+
},
332+
},
333+
{
334+
Name: "hs2",
335+
Users: []b.User{
336+
{
337+
Localpart: "bob",
338+
DisplayName: "Bob",
339+
},
340+
},
341+
},
342+
{
343+
Name: "hs3",
344+
Users: []b.User{
345+
{
346+
Localpart: "charlie",
347+
DisplayName: "Charlie",
348+
},
349+
},
350+
},
351+
},
352+
})
353+
defer deployment.Destroy(t)
354+
355+
// Setup the user, space, and restricted room.
356+
alice, space, room := setupRestrictedRoom(t, deployment)
357+
358+
// Raise the power level so that only alice can invite.
359+
state_key := ""
360+
alice.SendEventSynced(t, room, b.Event{
361+
Type: "m.room.power_levels",
362+
StateKey: &state_key,
363+
Content: map[string]interface{}{
364+
"invite": 100,
365+
"users": map[string]interface{}{
366+
alice.UserID: 100,
367+
},
368+
},
369+
})
370+
371+
// Create a second user on a different homeserver.
372+
bob := deployment.Client(t, "hs2", "@bob:hs2")
373+
374+
// Bob joins the room and space.
375+
bob.JoinRoom(t, space, []string{"hs1"})
376+
bob.JoinRoom(t, room, []string{"hs1"})
377+
378+
// Charlie should join the space (which gives access to the room).
379+
charlie := deployment.Client(t, "hs3", "@charlie:hs3")
380+
charlie.JoinRoom(t, space, []string{"hs1"})
381+
382+
// hs2 doesn't have anyone to invite from, so the join fails.
383+
failJoinRoom(t, charlie, room, "hs2", 502)
384+
385+
// Including hs1 (and failing over to it) allows the join to succeed.
386+
charlie.JoinRoom(t, room, []string{"hs2", "hs1"})
387+
388+
// Double check that the join was authorised via hs1.
389+
bob.SyncUntilTimelineHas(
390+
t,
391+
room,
392+
func(ev gjson.Result) bool {
393+
if ev.Get("type").Str != "m.room.member" || ev.Get("state_key").Str != charlie.UserID {
394+
return false
395+
}
396+
must.EqualStr(t, ev.Get("content").Get("membership").Str, "join", "Charlie failed to join the room")
397+
must.EqualStr(t, ev.Get("content").Get("join_authorised_via_users_server").Str, alice.UserID, "Join authorised via incorrect server")
398+
399+
return true
400+
},
401+
)
402+
403+
// Bump the power-level of bob.
404+
alice.SendEventSynced(t, room, b.Event{
405+
Type: "m.room.power_levels",
406+
StateKey: &state_key,
407+
Content: map[string]interface{}{
408+
"invite": 100,
409+
"users": map[string]interface{}{
410+
alice.UserID: 100,
411+
bob.UserID: 100,
412+
},
413+
},
414+
})
415+
416+
// Charlie leaves the room (so they can rejoin).
417+
charlie.LeaveRoom(t, room)
418+
419+
// Ensure the events have synced to hs2.
420+
bob.SyncUntilTimelineHas(
421+
t,
422+
room,
423+
func(ev gjson.Result) bool {
424+
if ev.Get("type").Str != "m.room.member" || ev.Get("state_key").Str != charlie.UserID {
425+
return false
426+
}
427+
return ev.Get("content").Get("membership").Str == "leave"
428+
},
429+
)
430+
431+
// Bob leaves the space so that hs2 doesn't know if Charlie is in the space or not.
432+
bob.LeaveRoom(t, space)
433+
434+
// hs2 cannot complete the join since they do not know if Charlie meets the
435+
// requirements (since it is no longer in the space).
436+
failJoinRoom(t, charlie, room, "hs2", 502)
437+
438+
// Including hs1 (and failing over to it) allows the join to succeed.
439+
charlie.JoinRoom(t, room, []string{"hs2", "hs1"})
440+
441+
// Double check that the join was authorised via hs1.
442+
bob.SyncUntilTimelineHas(
443+
t,
444+
room,
445+
func(ev gjson.Result) bool {
446+
if ev.Get("type").Str != "m.room.member" || ev.Get("state_key").Str != charlie.UserID {
447+
return false
448+
}
449+
must.EqualStr(t, ev.Get("content").Get("membership").Str, "join", "Charlie failed to join the room")
450+
must.EqualStr(t, ev.Get("content").Get("join_authorised_via_users_server").Str, alice.UserID, "Join authorised via incorrect server")
451+
452+
return true
453+
},
454+
)
455+
}
456+
313457
// Request the room summary and ensure the expected rooms are in the response.
314458
func requestAndAssertSummary(t *testing.T, user *client.CSAPI, space string, expected_rooms []interface{}) {
315459
t.Helper()

0 commit comments

Comments
 (0)