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

Test MSC3083 - joining a restricted room. #98

Merged
merged 6 commits into from
Apr 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions dockerfiles/synapse/homeserver.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -105,3 +105,5 @@ AS_REGISTRATION_FILES
experimental_features:
# Enable knocking support
msc2403_enabled: true
# Enable spaces support
spaces_enabled: true
17 changes: 17 additions & 0 deletions internal/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,23 @@ func (c *CSAPI) JoinRoom(t *testing.T, roomIDOrAlias string, serverNames []strin
return GetJSONFieldStr(t, body, "room_id")
}

// LeaveRoom joins the room ID, else fails the test.
func (c *CSAPI) LeaveRoom(t *testing.T, roomID string) {
t.Helper()
// leave the room
c.MustDoRaw(t, "POST", []string{"_matrix", "client", "r0", "rooms", roomID, "leave"}, nil, "application/json", nil)
}

// InviteRoom invites userID to the room ID, else fails the test.
func (c *CSAPI) InviteRoom(t *testing.T, roomID string, userID string) {
t.Helper()
// Invite the user to the room
body := map[string]interface{}{
"user_id": userID,
}
c.MustDo(t, "POST", []string{"_matrix", "client", "r0", "rooms", roomID, "invite"}, body)
}

// SendEventSynced sends `e` into the room and waits for its event ID to come down /sync.
// Returns the event ID of the sent event.
func (c *CSAPI) SendEventSynced(t *testing.T, roomID string, e b.Event) string {
Expand Down
131 changes: 131 additions & 0 deletions tests/msc3083_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
// +build msc3083

// Tests MSC3083, an experimental feature for joining restricted rooms based on
// membership in a space.

package tests

import (
"net/url"
"testing"

"github.com/matrix-org/complement/internal/b"
"github.com/matrix-org/complement/internal/client"
)

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

func FailJoinRoom(c *client.CSAPI, t *testing.T, roomIDOrAlias string, serverName string) {
// This is copied from Client.JoinRoom to test a join failure.
query := make(url.Values, 1)
query.Set("server_name", serverName)
c.MustDoWithStatusRaw(
t,
"POST",
[]string{"_matrix", "client", "r0", "join", roomIDOrAlias},
nil,
"application/json",
query,
403,
)
}

// Test joining a room with join rules restricted to membership in a space.
func TestRestrictedRoomsLocalJoin(t *testing.T) {
deployment := Deploy(t, "msc3083", b.BlueprintOneToOneRoom)
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: spaceChildEventType,
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, "hs1", "@bob:hs1")
FailJoinRoom(bob, t, room, "hs1")

// 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)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if you leave the space first?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leaving the space first should be fine. The ordering of these two steps doesn't matter.

FailJoinRoom(bob, t, room, "hs1")

// Invite the user and joining should work.
alice.InviteRoom(t, room, "@bob:hs1")
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")

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")
}