Skip to content

Commit 11adc36

Browse files
Merge pull request #220 from matrix-org/neilalexander/restrictedjoin
Run restricted join tests for Dendrite
2 parents 0dd587d + ea7c8b5 commit 11adc36

File tree

2 files changed

+191
-176
lines changed

2 files changed

+191
-176
lines changed

tests/restricted_rooms_test.go

Lines changed: 0 additions & 176 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
// +build msc2946,!dendrite_blacklist
2-
31
// Tests MSC3083, joining restricted rooms based on membership in another room.
42

53
package tests
@@ -451,177 +449,3 @@ func TestRestrictedRoomsRemoteJoinFailOver(t *testing.T) {
451449
},
452450
)
453451
}
454-
455-
// Request the room summary and ensure the expected rooms are in the response.
456-
func requestAndAssertSummary(t *testing.T, user *client.CSAPI, space string, expected_rooms []interface{}) {
457-
t.Helper()
458-
459-
res := user.MustDo(t, "POST", []string{"_matrix", "client", "unstable", "org.matrix.msc2946", "rooms", space, "spaces"}, map[string]interface{}{})
460-
must.MatchResponse(t, res, match.HTTPResponse{
461-
JSON: []match.JSON{
462-
match.JSONCheckOff("rooms", expected_rooms, func(r gjson.Result) interface{} {
463-
return r.Get("room_id").Str
464-
}, nil),
465-
},
466-
})
467-
}
468-
469-
// Tests that MSC2946 works for a restricted room.
470-
//
471-
// Create a space with a room in it that has join rules restricted to membership
472-
// in that space.
473-
//
474-
// The user should be unable to see the room in the spaces summary unless they
475-
// are a member of the space.
476-
func TestRestrictedRoomsSpacesSummary(t *testing.T) {
477-
deployment := Deploy(t, b.BlueprintOneToOneRoom)
478-
defer deployment.Destroy(t)
479-
480-
// Create the rooms
481-
alice := deployment.Client(t, "hs1", "@alice:hs1")
482-
space := alice.CreateRoom(t, map[string]interface{}{
483-
"preset": "public_chat",
484-
"name": "Space",
485-
"creation_content": map[string]interface{}{
486-
"type": "m.space",
487-
},
488-
// World readable to allow peeking without joining.
489-
"initial_state": []map[string]interface{}{
490-
{
491-
"type": "m.room.history_visibility",
492-
"state_key": "",
493-
"content": map[string]interface{}{
494-
"history_visibility": "world_readable",
495-
},
496-
},
497-
},
498-
})
499-
// The room is room version 8 which supports the restricted join_rule.
500-
room := alice.CreateRoom(t, map[string]interface{}{
501-
"preset": "public_chat",
502-
"name": "Room",
503-
"room_version": "8",
504-
"initial_state": []map[string]interface{}{
505-
{
506-
"type": "m.room.join_rules",
507-
"state_key": "",
508-
"content": map[string]interface{}{
509-
"join_rule": "restricted",
510-
"allow": []map[string]interface{}{
511-
{
512-
"type": "m.room_membership",
513-
"room_id": &space,
514-
"via": []string{"hs1"},
515-
},
516-
},
517-
},
518-
},
519-
},
520-
})
521-
alice.SendEventSynced(t, space, b.Event{
522-
Type: "m.space.child",
523-
StateKey: &room,
524-
Content: map[string]interface{}{
525-
"via": []string{"hs1"},
526-
},
527-
})
528-
529-
t.Logf("Space: %s", space)
530-
t.Logf("Room: %s", room)
531-
532-
// Create a second user on the same homeserver.
533-
bob := deployment.Client(t, "hs1", "@bob:hs1")
534-
535-
// Querying the space returns only the space, as the room is restricted.
536-
requestAndAssertSummary(t, bob, space, []interface{}{space})
537-
538-
// Join the space, and now the restricted room should appear.
539-
bob.JoinRoom(t, space, []string{"hs1"})
540-
requestAndAssertSummary(t, bob, space, []interface{}{space, room})
541-
}
542-
543-
// Tests that MSC2946 works over federation for a restricted room.
544-
//
545-
// Create a space with a room in it that has join rules restricted to membership
546-
// in that space. The space and room are on different homeservers. While generating
547-
// the summary of space hs1 needs to ask hs2 to generate the summary for room since
548-
// it is not participating in the room.
549-
//
550-
// The user should be unable to see the room in the spaces summary unless they
551-
// are a member of the space.
552-
//
553-
// This tests the interactions over federation where the space and room are on
554-
// different homeservers, and one might not have the proper information needed to
555-
// decide if a user is in a room.
556-
func TestRestrictedRoomsSpacesSummaryFederation(t *testing.T) {
557-
deployment := Deploy(t, b.BlueprintFederationTwoLocalOneRemote)
558-
defer deployment.Destroy(t)
559-
560-
// Create the rooms
561-
alice := deployment.Client(t, "hs1", "@alice:hs1")
562-
bob := deployment.Client(t, "hs1", "@bob:hs1")
563-
space := alice.CreateRoom(t, map[string]interface{}{
564-
"preset": "public_chat",
565-
"name": "Space",
566-
"creation_content": map[string]interface{}{
567-
"type": "m.space",
568-
},
569-
"initial_state": []map[string]interface{}{
570-
{
571-
"type": "m.room.history_visibility",
572-
"state_key": "",
573-
"content": map[string]string{
574-
"history_visibility": "world_readable",
575-
},
576-
},
577-
},
578-
})
579-
580-
// The room is room version 8 which supports the restricted join_rule and is
581-
// created on hs2.
582-
charlie := deployment.Client(t, "hs2", "@charlie:hs2")
583-
room := charlie.CreateRoom(t, map[string]interface{}{
584-
"preset": "public_chat",
585-
"name": "Room",
586-
"room_version": "8",
587-
"initial_state": []map[string]interface{}{
588-
{
589-
"type": "m.room.join_rules",
590-
"state_key": "",
591-
"content": map[string]interface{}{
592-
"join_rule": "restricted",
593-
"allow": []map[string]interface{}{
594-
{
595-
"type": "m.room_membership",
596-
"room_id": &space,
597-
"via": []string{"hs1"},
598-
},
599-
},
600-
},
601-
},
602-
},
603-
})
604-
605-
// create the link (this doesn't really make sense since how would alice know
606-
// about the room? but it works for testing)
607-
alice.SendEventSynced(t, space, b.Event{
608-
Type: spaceChildEventType,
609-
StateKey: &room,
610-
Content: map[string]interface{}{
611-
"via": []string{"hs2"},
612-
},
613-
})
614-
615-
// The room appears for neither alice or bob initially. Although alice is in
616-
// the space and should be able to access the room, hs2 doesn't know this!
617-
requestAndAssertSummary(t, alice, space, []interface{}{space})
618-
requestAndAssertSummary(t, bob, space, []interface{}{space})
619-
620-
// charlie joins the space and now hs2 knows that alice is in the space (and
621-
// can join the room).
622-
charlie.JoinRoom(t, space, []string{"hs1"})
623-
624-
// The restricted room should appear for alice (who is in the space).
625-
requestAndAssertSummary(t, alice, space, []interface{}{space, room})
626-
requestAndAssertSummary(t, bob, space, []interface{}{space})
627-
}

tests/restricted_spaces_test.go

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
//go:build msc2946
2+
// +build msc2946
3+
4+
// Tests MSC3083, joining restricted spaces based on membership in another room.
5+
6+
package tests
7+
8+
import (
9+
"testing"
10+
11+
"github.com/tidwall/gjson"
12+
13+
"github.com/matrix-org/complement/internal/b"
14+
"github.com/matrix-org/complement/internal/client"
15+
"github.com/matrix-org/complement/internal/match"
16+
"github.com/matrix-org/complement/internal/must"
17+
)
18+
19+
// Request the room summary and ensure the expected rooms are in the response.
20+
func requestAndAssertSummary(t *testing.T, user *client.CSAPI, space string, expected_rooms []interface{}) {
21+
t.Helper()
22+
23+
res := user.MustDo(t, "POST", []string{"_matrix", "client", "unstable", "org.matrix.msc2946", "rooms", space, "spaces"}, map[string]interface{}{})
24+
must.MatchResponse(t, res, match.HTTPResponse{
25+
JSON: []match.JSON{
26+
match.JSONCheckOff("rooms", expected_rooms, func(r gjson.Result) interface{} {
27+
return r.Get("room_id").Str
28+
}, nil),
29+
},
30+
})
31+
}
32+
33+
// Tests that MSC2946 works for a restricted room.
34+
//
35+
// Create a space with a room in it that has join rules restricted to membership
36+
// in that space.
37+
//
38+
// The user should be unable to see the room in the spaces summary unless they
39+
// are a member of the space.
40+
func TestRestrictedRoomsSpacesSummary(t *testing.T) {
41+
deployment := Deploy(t, b.BlueprintOneToOneRoom)
42+
defer deployment.Destroy(t)
43+
44+
// Create the rooms
45+
alice := deployment.Client(t, "hs1", "@alice:hs1")
46+
space := alice.CreateRoom(t, map[string]interface{}{
47+
"preset": "public_chat",
48+
"name": "Space",
49+
"creation_content": map[string]interface{}{
50+
"type": "m.space",
51+
},
52+
// World readable to allow peeking without joining.
53+
"initial_state": []map[string]interface{}{
54+
{
55+
"type": "m.room.history_visibility",
56+
"state_key": "",
57+
"content": map[string]interface{}{
58+
"history_visibility": "world_readable",
59+
},
60+
},
61+
},
62+
})
63+
// The room is room version 8 which supports the restricted join_rule.
64+
room := alice.CreateRoom(t, map[string]interface{}{
65+
"preset": "public_chat",
66+
"name": "Room",
67+
"room_version": "8",
68+
"initial_state": []map[string]interface{}{
69+
{
70+
"type": "m.room.join_rules",
71+
"state_key": "",
72+
"content": map[string]interface{}{
73+
"join_rule": "restricted",
74+
"allow": []map[string]interface{}{
75+
{
76+
"type": "m.room_membership",
77+
"room_id": &space,
78+
"via": []string{"hs1"},
79+
},
80+
},
81+
},
82+
},
83+
},
84+
})
85+
alice.SendEventSynced(t, space, b.Event{
86+
Type: "m.space.child",
87+
StateKey: &room,
88+
Content: map[string]interface{}{
89+
"via": []string{"hs1"},
90+
},
91+
})
92+
93+
t.Logf("Space: %s", space)
94+
t.Logf("Room: %s", room)
95+
96+
// Create a second user on the same homeserver.
97+
bob := deployment.Client(t, "hs1", "@bob:hs1")
98+
99+
// Querying the space returns only the space, as the room is restricted.
100+
requestAndAssertSummary(t, bob, space, []interface{}{space})
101+
102+
// Join the space, and now the restricted room should appear.
103+
bob.JoinRoom(t, space, []string{"hs1"})
104+
requestAndAssertSummary(t, bob, space, []interface{}{space, room})
105+
}
106+
107+
// Tests that MSC2946 works over federation for a restricted room.
108+
//
109+
// Create a space with a room in it that has join rules restricted to membership
110+
// in that space. The space and room are on different homeservers. While generating
111+
// the summary of space hs1 needs to ask hs2 to generate the summary for room since
112+
// it is not participating in the room.
113+
//
114+
// The user should be unable to see the room in the spaces summary unless they
115+
// are a member of the space.
116+
//
117+
// This tests the interactions over federation where the space and room are on
118+
// different homeservers, and one might not have the proper information needed to
119+
// decide if a user is in a room.
120+
func TestRestrictedRoomsSpacesSummaryFederation(t *testing.T) {
121+
deployment := Deploy(t, b.BlueprintFederationTwoLocalOneRemote)
122+
defer deployment.Destroy(t)
123+
124+
// Create the rooms
125+
alice := deployment.Client(t, "hs1", "@alice:hs1")
126+
bob := deployment.Client(t, "hs1", "@bob:hs1")
127+
space := alice.CreateRoom(t, map[string]interface{}{
128+
"preset": "public_chat",
129+
"name": "Space",
130+
"creation_content": map[string]interface{}{
131+
"type": "m.space",
132+
},
133+
"initial_state": []map[string]interface{}{
134+
{
135+
"type": "m.room.history_visibility",
136+
"state_key": "",
137+
"content": map[string]string{
138+
"history_visibility": "world_readable",
139+
},
140+
},
141+
},
142+
})
143+
144+
// The room is room version 8 which supports the restricted join_rule and is
145+
// created on hs2.
146+
charlie := deployment.Client(t, "hs2", "@charlie:hs2")
147+
room := charlie.CreateRoom(t, map[string]interface{}{
148+
"preset": "public_chat",
149+
"name": "Room",
150+
"room_version": "8",
151+
"initial_state": []map[string]interface{}{
152+
{
153+
"type": "m.room.join_rules",
154+
"state_key": "",
155+
"content": map[string]interface{}{
156+
"join_rule": "restricted",
157+
"allow": []map[string]interface{}{
158+
{
159+
"type": "m.room_membership",
160+
"room_id": &space,
161+
"via": []string{"hs1"},
162+
},
163+
},
164+
},
165+
},
166+
},
167+
})
168+
169+
// create the link (this doesn't really make sense since how would alice know
170+
// about the room? but it works for testing)
171+
alice.SendEventSynced(t, space, b.Event{
172+
Type: spaceChildEventType,
173+
StateKey: &room,
174+
Content: map[string]interface{}{
175+
"via": []string{"hs2"},
176+
},
177+
})
178+
179+
// The room appears for neither alice or bob initially. Although alice is in
180+
// the space and should be able to access the room, hs2 doesn't know this!
181+
requestAndAssertSummary(t, alice, space, []interface{}{space})
182+
requestAndAssertSummary(t, bob, space, []interface{}{space})
183+
184+
// charlie joins the space and now hs2 knows that alice is in the space (and
185+
// can join the room).
186+
charlie.JoinRoom(t, space, []string{"hs1"})
187+
188+
// The restricted room should appear for alice (who is in the space).
189+
requestAndAssertSummary(t, alice, space, []interface{}{space, room})
190+
requestAndAssertSummary(t, bob, space, []interface{}{space})
191+
}

0 commit comments

Comments
 (0)