Skip to content
117 changes: 107 additions & 10 deletions tests/msc3083_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,10 @@ import (
)

var (
spaceChildEventType = "org.matrix.msc1772.space.child"
spaceParentEventType = "org.matrix.msc1772.space.parent"
msc1772SpaceChildEventType = "org.matrix.msc1772.space.child"
)

func FailJoinRoom(c *client.CSAPI, t *testing.T, roomIDOrAlias string, serverName string) {
func FailJoinRoom(c *client.CSAPI, t *testing.T, roomIDOrAlias string, serverName string, expectedHttpCode int) {
// This is copied from Client.JoinRoom to test a join failure.
query := make(url.Values, 1)
query.Set("server_name", serverName)
Expand All @@ -29,13 +28,13 @@ func FailJoinRoom(c *client.CSAPI, t *testing.T, roomIDOrAlias string, serverNam
nil,
"application/json",
query,
403,
expectedHttpCode,
)
}

// Test joining a room with join rules restricted to membership in a space.
func TestRestrictedRoomsLocalJoin(t *testing.T) {
deployment := Deploy(t, "msc3083", b.BlueprintOneToOneRoom)
deployment := Deploy(t, "msc3083_local", b.BlueprintOneToOneRoom)
defer deployment.Destroy(t)

// Create the space and put a room in it.
Expand Down Expand Up @@ -66,7 +65,7 @@ func TestRestrictedRoomsLocalJoin(t *testing.T) {
},
})
alice.SendEventSynced(t, space, b.Event{
Type: spaceChildEventType,
Type: msc1772SpaceChildEventType,
StateKey: &room,
Content: map[string]interface{}{
"via": []string{"hs1"},
Expand All @@ -75,7 +74,7 @@ func TestRestrictedRoomsLocalJoin(t *testing.T) {

// Create a second user and attempt to join the room, it should fail.
bob := deployment.Client(t, "hs1", "@bob:hs1")
FailJoinRoom(bob, t, room, "hs1")
FailJoinRoom(bob, t, room, "hs1", 403)

// Join the space, attempt to join the room again, which now should succeed.
bob.JoinRoom(t, space, []string{"hs1"})
Expand All @@ -84,7 +83,7 @@ func TestRestrictedRoomsLocalJoin(t *testing.T) {
// Leaving the room works and the user is unable to re-join.
bob.LeaveRoom(t, room)
bob.LeaveRoom(t, space)
FailJoinRoom(bob, t, room, "hs1")
FailJoinRoom(bob, t, room, "hs1", 403)

// Invite the user and joining should work.
alice.InviteRoom(t, room, "@bob:hs1")
Expand All @@ -111,7 +110,7 @@ func TestRestrictedRoomsLocalJoin(t *testing.T) {
},
)
// Fails since invalid values get filtered out of allow.
FailJoinRoom(bob, t, room, "hs1")
FailJoinRoom(bob, t, room, "hs1", 403)

alice.SendEventSynced(
t,
Expand All @@ -127,5 +126,103 @@ func TestRestrictedRoomsLocalJoin(t *testing.T) {
},
)
// Fails since a fully invalid allow key rquires an invite.
FailJoinRoom(bob, t, room, "hs1")
FailJoinRoom(bob, t, room, "hs1", 403)
}

// Test joining a room with join rules restricted to membership in a space.
func TestRestrictedRoomsRemoteJoin(t *testing.T) {
deployment := Deploy(t, "msc3083_remote", b.BlueprintFederationOneToOneRoom)
defer deployment.Destroy(t)

// Create the space and put a room in it.
alice := deployment.Client(t, "hs1", "@alice:hs1")
space := alice.CreateRoom(t, map[string]interface{}{
"preset": "public_chat",
"name": "Space",
})
// The room is an unstable room version which supports the restricted join_rule.
room := alice.CreateRoom(t, map[string]interface{}{
"preset": "public_chat",
"name": "Room",
"room_version": "org.matrix.msc3083",
"initial_state": []map[string]interface{}{
{
"type": "m.room.join_rules",
"state_key": "",
"content": map[string]interface{}{
"join_rule": "restricted",
"allow": []map[string]interface{}{
{
"space": &space,
"via": []string{"hs1"},
},
},
},
},
},
})
alice.SendEventSynced(t, space, b.Event{
Type: msc1772SpaceChildEventType,
StateKey: &room,
Content: map[string]interface{}{
"via": []string{"hs1"},
},
})

// Create a second user and attempt to join the room, it should fail.
bob := deployment.Client(t, "hs2", "@bob:hs2")
// Note that this is a 400 error because it comes back over federation.
FailJoinRoom(bob, t, room, "hs1", 400)

// Join the space, attempt to join the room again, which now should succeed.
bob.JoinRoom(t, space, []string{"hs1"})
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)
FailJoinRoom(bob, t, room, "hs1", 400)

// Invite the user and joining shuold work.
alice.InviteRoom(t, room, "@bob:hs2")
bob.JoinRoom(t, room, []string{"hs1"})

// Leave the room again, and join the space.
bob.LeaveRoom(t, room)
bob.JoinRoom(t, space, []string{"hs1"})

// Update the room to have bad values in the "allow" field, which should stop
// joining from working properly.
emptyStateKey := ""
alice.SendEventSynced(
t,
room,
b.Event{
Type: "m.room.join_rules",
Sender: alice.UserID,
StateKey: &emptyStateKey,
Content: map[string]interface{}{
"join_rule": "restricted",
"allow": []string{"invalid"},
},
},
)
// Fails since invalid values get filtered out of allow.
FailJoinRoom(bob, t, room, "hs1", 400)

alice.SendEventSynced(
t,
room,
b.Event{
Type: "m.room.join_rules",
Sender: alice.UserID,
StateKey: &emptyStateKey,
Content: map[string]interface{}{
"join_rule": "restricted",
"allow": "invalid",
},
},
)
// Fails since a fully invalid allow key rquires an invite.
FailJoinRoom(bob, t, room, "hs1", 400)
}