Skip to content

Commit

Permalink
Add tests for MSC3787 (#367)
Browse files Browse the repository at this point in the history
Co-authored-by: Erik Johnston <erik@matrix.org>
Co-authored-by: David Robertson <davidr@element.io>
Co-authored-by: Kegan Dougal <kegan@matrix.org>
  • Loading branch information
4 people authored May 27, 2022
1 parent 6c31e8d commit 25adcae
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 27 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ jobs:
matrix:
include:
- homeserver: Synapse
tags: synapse_blacklist msc3083 faster_joins
tags: synapse_blacklist msc3083 msc3787 faster_joins

- homeserver: Dendrite
tags: msc2836 dendrite_blacklist

Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ require (
github.com/gogo/protobuf v1.3.2 // indirect
github.com/gorilla/mux v1.8.0
github.com/matrix-org/gomatrix v0.0.0-20210324163249-be2af5ef2e16
github.com/matrix-org/gomatrixserverlib v0.0.0-20220524100759-f98e737f8f9c
github.com/matrix-org/gomatrixserverlib v0.0.0-20220526140030-dcfbb70ff32d
github.com/matrix-org/util v0.0.0-20200807132607-55161520e1d4
github.com/moby/term v0.0.0-20210610120745-9d4ed1856297 // indirect
github.com/morikuni/aec v1.0.0 // indirect
Expand All @@ -21,7 +21,7 @@ require (
github.com/sirupsen/logrus v1.8.1
github.com/tidwall/gjson v1.14.1
github.com/tidwall/sjson v1.2.4
golang.org/x/crypto v0.0.0-20220518034528-6f7dac969898 // indirect
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6 // indirect
golang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9 // indirect
golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2 // indirect
Expand Down
8 changes: 8 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,14 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/matrix-org/gomatrix v0.0.0-20190528120928-7df988a63f26/go.mod h1:3fxX6gUjWyI/2Bt7J1OLhpCzOfO/bB3AiX0cJtEKud0=
github.com/matrix-org/gomatrix v0.0.0-20210324163249-be2af5ef2e16 h1:ZtO5uywdd5dLDCud4r0r55eP4j9FuUNpl60Gmntcop4=
github.com/matrix-org/gomatrix v0.0.0-20210324163249-be2af5ef2e16/go.mod h1:/gBX06Kw0exX1HrwmoBibFA98yBk/jxKpGVeyQbff+s=
github.com/matrix-org/gomatrixserverlib v0.0.0-20220519174812-8904a93b5a99 h1:JsIMDWZl2B9bReq/yNlLSsBk2Zvx+JO8Ci8B+eZDHzM=
github.com/matrix-org/gomatrixserverlib v0.0.0-20220519174812-8904a93b5a99/go.mod h1:V5eO8rn/C3rcxig37A/BCeKerLFS+9Avg/77FIeTZ48=
github.com/matrix-org/gomatrixserverlib v0.0.0-20220524100759-f98e737f8f9c h1:J9krMtVgo4mV/G+mRA1u3GL6nNxdNnuPcs891uIQGic=
github.com/matrix-org/gomatrixserverlib v0.0.0-20220524100759-f98e737f8f9c/go.mod h1:V5eO8rn/C3rcxig37A/BCeKerLFS+9Avg/77FIeTZ48=
github.com/matrix-org/gomatrixserverlib v0.0.0-20220526125151-b6f33bc40ed8 h1:5cdzTYzcwWxp7TvYtHi5WpMHarPddpFDxHnkLtgGgdE=
github.com/matrix-org/gomatrixserverlib v0.0.0-20220526125151-b6f33bc40ed8/go.mod h1:V5eO8rn/C3rcxig37A/BCeKerLFS+9Avg/77FIeTZ48=
github.com/matrix-org/gomatrixserverlib v0.0.0-20220526140030-dcfbb70ff32d h1:IwyG/58rFn0/ugD0A/IdSIo7D/oLJ4+k3NznlYhzyHs=
github.com/matrix-org/gomatrixserverlib v0.0.0-20220526140030-dcfbb70ff32d/go.mod h1:jX38yp3SSLJNftBg3PXU1ayd0PCLIiDHQ4xAc9DIixk=
github.com/matrix-org/util v0.0.0-20190711121626-527ce5ddefc7/go.mod h1:vVQlW/emklohkZnOPwD3LrZUBqdfsbiyO3p1lNV8F6U=
github.com/matrix-org/util v0.0.0-20200807132607-55161520e1d4 h1:eCEHXWDv9Rm335MSuB49mFUK44bwZPFSDde3ORE3syk=
github.com/matrix-org/util v0.0.0-20200807132607-55161520e1d4/go.mod h1:vVQlW/emklohkZnOPwD3LrZUBqdfsbiyO3p1lNV8F6U=
Expand Down Expand Up @@ -138,6 +144,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20220513210258-46612604a0f9/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220518034528-6f7dac969898 h1:SLP7Q4Di66FONjDJbCYrCRrh97focO6sLogHO7/g8F0=
golang.org/x/crypto v0.0.0-20220518034528-6f7dac969898/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM=
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
Expand Down
29 changes: 19 additions & 10 deletions tests/knocking_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import (
"time"

"github.com/matrix-org/gomatrixserverlib"

"github.com/tidwall/gjson"

"github.com/matrix-org/complement/internal/b"
Expand All @@ -32,6 +31,11 @@ const testKnockReason string = "Let me in... LET ME IN!!!"
// Knocking is currently an experimental feature and not in the matrix spec.
// This function tests knocking on local and remote room.
func TestKnocking(t *testing.T) {
// v7 is required for knocking support
doTestKnocking(t, "7", "knock")
}

func doTestKnocking(t *testing.T, roomVersion string, joinRule string) {
deployment := Deploy(t, b.BlueprintFederationTwoLocalOneRemote)
defer deployment.Destroy(t)

Expand Down Expand Up @@ -67,33 +71,33 @@ func TestKnocking(t *testing.T) {
RoomVersion string `json:"room_version"`
}{
"private_chat", // Set to private in order to get an invite-only room
"7", // Room version required for knocking.
roomVersion,
})
alice.InviteRoom(t, roomIDOne, david)
inviteWaiter.Wait(t, 5*time.Second)
serverRoomOne := srv.MustJoinRoom(t, deployment, "hs1", roomIDOne, david)

// Test knocking between two users on the same homeserver
knockingBetweenTwoUsersTest(t, roomIDOne, alice, bob, serverRoomOne, false)
knockingBetweenTwoUsersTest(t, roomIDOne, alice, bob, serverRoomOne, false, joinRule)

// Create a room for alice and charlie to test knocking with
roomIDTwo := alice.CreateRoom(t, struct {
Preset string `json:"preset"`
RoomVersion string `json:"room_version"`
}{
"private_chat", // Set to private in order to get an invite-only room
"7", // Room version required for knocking.
roomVersion,
})
inviteWaiter = NewWaiter()
alice.InviteRoom(t, roomIDTwo, david)
inviteWaiter.Wait(t, 5*time.Second)
serverRoomTwo := srv.MustJoinRoom(t, deployment, "hs1", roomIDTwo, david)

// Test knocking between two users, each on a separate homeserver
knockingBetweenTwoUsersTest(t, roomIDTwo, alice, charlie, serverRoomTwo, true)
knockingBetweenTwoUsersTest(t, roomIDTwo, alice, charlie, serverRoomTwo, true, joinRule)
}

func knockingBetweenTwoUsersTest(t *testing.T, roomID string, inRoomUser, knockingUser *client.CSAPI, serverRoom *federation.ServerRoom, testFederation bool) {
func knockingBetweenTwoUsersTest(t *testing.T, roomID string, inRoomUser, knockingUser *client.CSAPI, serverRoom *federation.ServerRoom, testFederation bool, joinRule string) {
t.Run("Knocking on a room with a join rule other than 'knock' should fail", func(t *testing.T) {
knockOnRoomWithStatus(t, knockingUser, roomID, "Can I knock anyways?", []string{"hs1"}, 403)
})
Expand All @@ -105,7 +109,7 @@ func knockingBetweenTwoUsersTest(t *testing.T, roomID string, inRoomUser, knocki
Sender: inRoomUser.UserID,
StateKey: &emptyStateKey,
Content: map[string]interface{}{
"join_rule": "knock",
"join_rule": joinRule,
},
})
})
Expand Down Expand Up @@ -367,6 +371,11 @@ func knockOnRoomWithStatus(t *testing.T, c *client.CSAPI, roomID, reason string,
// representing a knock room. For sanity-checking, this test will also create a public room and ensure it has a
// 'join_rule' representing a publicly-joinable room.
func TestKnockRoomsInPublicRoomsDirectory(t *testing.T) {
// v7 is required for knocking
doTestKnockRoomsInPublicRoomsDirectory(t, "7", "knock")
}

func doTestKnockRoomsInPublicRoomsDirectory(t *testing.T, roomVersion string, joinRule string) {
deployment := Deploy(t, b.BlueprintAlice)
defer deployment.Destroy(t)

Expand All @@ -380,7 +389,7 @@ func TestKnockRoomsInPublicRoomsDirectory(t *testing.T) {
RoomVersion string `json:"room_version"`
}{
"private_chat", // Set to private in order to get an invite-only room
"7", // Room version required for knocking.
roomVersion,
})

// Change the join_rule to allow knocking
Expand All @@ -390,12 +399,12 @@ func TestKnockRoomsInPublicRoomsDirectory(t *testing.T) {
Sender: alice.UserID,
StateKey: &emptyStateKey,
Content: map[string]interface{}{
"join_rule": "knock",
"join_rule": joinRule,
},
})

// Publish the room to the public room directory and check that the 'join_rule' key is knock
publishAndCheckRoomJoinRule(t, alice, roomID, "knock")
publishAndCheckRoomJoinRule(t, alice, roomID, joinRule)

// Create a public room
roomID = alice.CreateRoom(t, struct {
Expand Down
81 changes: 81 additions & 0 deletions tests/msc3787_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
//go:build msc3787
// +build msc3787

// This file contains tests for a join rule which mixes concepts of restricted joins
// and knocking. This is currently experimental and defined by MSC3787, found here:
// /~https://github.com/matrix-org/matrix-spec-proposals/pull/3787
//
// Generally, this is a combination of knocking_test and restricted_rooms_test.

package tests

import (
"testing"

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

var (
msc3787RoomVersion = "org.matrix.msc3787"
msc3787JoinRule = "knock_restricted"
)

// See TestKnocking
func TestKnockingInMSC3787Room(t *testing.T) {
doTestKnocking(t, msc3787RoomVersion, msc3787JoinRule)
}

// See TestKnockRoomsInPublicRoomsDirectory
func TestKnockRoomsInPublicRoomsDirectoryInMSC3787Room(t *testing.T) {
doTestKnockRoomsInPublicRoomsDirectory(t, msc3787RoomVersion, msc3787JoinRule)
}

// See TestCannotSendKnockViaSendKnock
func TestCannotSendKnockViaSendKnockInMSC3787Room(t *testing.T) {
testValidationForSendMembershipEndpoint(t, "/_matrix/federation/v1/send_knock", "knock",
map[string]interface{}{
"preset": "public_chat",
"room_version": msc3787RoomVersion,
},
)
}

// See TestRestrictedRoomsLocalJoin
func TestRestrictedRoomsLocalJoinInMSC3787Room(t *testing.T) {
deployment := Deploy(t, b.BlueprintOneToOneRoom)
defer deployment.Destroy(t)

// Setup the user, allowed room, and restricted room.
alice, allowed_room, room := setupRestrictedRoom(t, deployment, msc3787RoomVersion, msc3787JoinRule)

// Create a second user on the same homeserver.
bob := deployment.Client(t, "hs1", "@bob:hs1")

// Execute the checks.
checkRestrictedRoom(t, alice, bob, allowed_room, room, msc3787JoinRule)
}

// See TestRestrictedRoomsRemoteJoin
func TestRestrictedRoomsRemoteJoinInMSC3787Room(t *testing.T) {
deployment := Deploy(t, b.BlueprintFederationOneToOneRoom)
defer deployment.Destroy(t)

// Setup the user, allowed room, and restricted room.
alice, allowed_room, room := setupRestrictedRoom(t, deployment, msc3787RoomVersion, msc3787JoinRule)

// Create a second user on a different homeserver.
bob := deployment.Client(t, "hs2", "@bob:hs2")

// Execute the checks.
checkRestrictedRoom(t, alice, bob, allowed_room, room, msc3787JoinRule)
}

// See TestRestrictedRoomsRemoteJoinLocalUser
func TestRestrictedRoomsRemoteJoinLocalUserInMSC3787Room(t *testing.T) {
doTestRestrictedRoomsRemoteJoinLocalUser(t, msc3787RoomVersion, msc3787JoinRule)
}

// See TestRestrictedRoomsRemoteJoinFailOver
func TestRestrictedRoomsRemoteJoinFailOverInMSC3787Room(t *testing.T) {
doTestRestrictedRoomsRemoteJoinFailOver(t, msc3787RoomVersion, msc3787JoinRule)
}
34 changes: 21 additions & 13 deletions tests/restricted_rooms_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func failJoinRoom(t *testing.T, c *client.CSAPI, roomIDOrAlias string, serverNam

// Creates two rooms on room version 8 and sets the second room to have
// restricted join rules with allow set to the first room.
func setupRestrictedRoom(t *testing.T, deployment *docker.Deployment) (*client.CSAPI, string, string) {
func setupRestrictedRoom(t *testing.T, deployment *docker.Deployment, roomVersion string, joinRule string) (*client.CSAPI, string, string) {
t.Helper()

alice := deployment.Client(t, "hs1", "@alice:hs1")
Expand All @@ -47,13 +47,13 @@ func setupRestrictedRoom(t *testing.T, deployment *docker.Deployment) (*client.C
room := alice.CreateRoom(t, map[string]interface{}{
"preset": "public_chat",
"name": "Room",
"room_version": "8",
"room_version": roomVersion,
"initial_state": []map[string]interface{}{
{
"type": "m.room.join_rules",
"state_key": "",
"content": map[string]interface{}{
"join_rule": "restricted",
"join_rule": joinRule,
"allow": []map[string]interface{}{
{
"type": "m.room_membership",
Expand All @@ -69,7 +69,7 @@ func setupRestrictedRoom(t *testing.T, deployment *docker.Deployment) (*client.C
return alice, allowed_room, room
}

func checkRestrictedRoom(t *testing.T, alice *client.CSAPI, bob *client.CSAPI, allowed_room string, room string) {
func checkRestrictedRoom(t *testing.T, alice *client.CSAPI, bob *client.CSAPI, allowed_room string, room string, joinRule string) {
t.Helper()

t.Run("Join should fail initially", func(t *testing.T) {
Expand Down Expand Up @@ -141,7 +141,7 @@ func checkRestrictedRoom(t *testing.T, alice *client.CSAPI, bob *client.CSAPI, a
Sender: alice.UserID,
StateKey: &emptyStateKey,
Content: map[string]interface{}{
"join_rule": "restricted",
"join_rule": joinRule,
"allow": []string{"invalid"},
},
},
Expand All @@ -157,7 +157,7 @@ func checkRestrictedRoom(t *testing.T, alice *client.CSAPI, bob *client.CSAPI, a
Sender: alice.UserID,
StateKey: &emptyStateKey,
Content: map[string]interface{}{
"join_rule": "restricted",
"join_rule": joinRule,
"allow": "invalid",
},
},
Expand All @@ -173,13 +173,13 @@ func TestRestrictedRoomsLocalJoin(t *testing.T) {
defer deployment.Destroy(t)

// Setup the user, allowed room, and restricted room.
alice, allowed_room, room := setupRestrictedRoom(t, deployment)
alice, allowed_room, room := setupRestrictedRoom(t, deployment, "8", "restricted")

// Create a second user on the same homeserver.
bob := deployment.Client(t, "hs1", "@bob:hs1")

// Execute the checks.
checkRestrictedRoom(t, alice, bob, allowed_room, room)
checkRestrictedRoom(t, alice, bob, allowed_room, room, "restricted")
}

// Test joining a room with join rules restricted to membership in another room.
Expand All @@ -188,18 +188,22 @@ func TestRestrictedRoomsRemoteJoin(t *testing.T) {
defer deployment.Destroy(t)

// Setup the user, allowed room, and restricted room.
alice, allowed_room, room := setupRestrictedRoom(t, deployment)
alice, allowed_room, room := setupRestrictedRoom(t, deployment, "8", "restricted")

// Create a second user on a different homeserver.
bob := deployment.Client(t, "hs2", "@bob:hs2")

// Execute the checks.
checkRestrictedRoom(t, alice, bob, allowed_room, room)
checkRestrictedRoom(t, alice, bob, allowed_room, room, "restricted")
}

// 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) {
doTestRestrictedRoomsRemoteJoinLocalUser(t, "8", "restricted")
}

func doTestRestrictedRoomsRemoteJoinLocalUser(t *testing.T, roomVersion string, joinRule string) {
runtime.SkipIf(t, runtime.Dendrite) // requires more debugging

deployment := Deploy(t, b.BlueprintFederationTwoLocalOneRemote)
Expand All @@ -218,13 +222,13 @@ func TestRestrictedRoomsRemoteJoinLocalUser(t *testing.T) {
room := charlie.CreateRoom(t, map[string]interface{}{
"preset": "public_chat",
"name": "Room",
"room_version": "8",
"room_version": roomVersion,
"initial_state": []map[string]interface{}{
{
"type": "m.room.join_rules",
"state_key": "",
"content": map[string]interface{}{
"join_rule": "restricted",
"join_rule": joinRule,
"allow": []map[string]interface{}{
{
"type": "m.room_membership",
Expand Down Expand Up @@ -323,6 +327,10 @@ func TestRestrictedRoomsRemoteJoinLocalUser(t *testing.T) {
// * hs2 joins the room
// * hs3 attempts to join via hs2 (should fail) and hs1 (should work)
func TestRestrictedRoomsRemoteJoinFailOver(t *testing.T) {
doTestRestrictedRoomsRemoteJoinFailOver(t, "8", "restricted")
}

func doTestRestrictedRoomsRemoteJoinFailOver(t *testing.T, roomVersion string, joinRule string) {
runtime.SkipIf(t, runtime.Dendrite) // requires more debugging

deployment := Deploy(t, b.Blueprint{
Expand Down Expand Up @@ -360,7 +368,7 @@ func TestRestrictedRoomsRemoteJoinFailOver(t *testing.T) {
defer deployment.Destroy(t)

// Setup the user, allowed room, and restricted room.
alice, allowed_room, room := setupRestrictedRoom(t, deployment)
alice, allowed_room, room := setupRestrictedRoom(t, deployment, roomVersion, joinRule)

// Raise the power level so that only alice can invite.
state_key := ""
Expand Down

0 comments on commit 25adcae

Please sign in to comment.