Skip to content

Commit 078dea0

Browse files
authored
Add more thorough E2E replace key checks (#179)
* Add more thorough E2E replace key checks There was a bug in the Dendrite impl which Sytest did not pick up. These are regression tests for that bug. * goimports -local github.com/matrix-org/complement * Use the same lint version as buildkite and the lint script in this repo
1 parent fd752eb commit 078dea0

File tree

8 files changed

+180
-10
lines changed

8 files changed

+180
-10
lines changed

.github/workflows/ci.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ jobs:
1313
- run: sudo apt-get -qq install libolm-dev
1414
- uses: golangci/golangci-lint-action@v2
1515
with:
16-
version: v1.39
16+
version: v1.33
1717
args: ./internal/... ./tests/...
1818

1919
complement:

go.mod

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ require (
1717
github.com/sirupsen/logrus v1.6.0
1818
github.com/tidwall/gjson v1.6.8
1919
github.com/tidwall/sjson v1.1.5
20-
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 // indirect
20+
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 // indirect
21+
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
22+
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect
2123
maunium.net/go/mautrix v0.8.3
2224
)

go.sum

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,6 @@ github.com/lib/pq v1.9.0 h1:L8nSXQQzAYByakOFMTwpjRoHsMJklur4Gi59b6VivR8=
5353
github.com/lib/pq v1.9.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
5454
github.com/matrix-org/gomatrix v0.0.0-20190528120928-7df988a63f26 h1:Hr3zjRsq2bhrnp3Ky1qgx/fzCtCALOoGYylh2tpS9K4=
5555
github.com/matrix-org/gomatrix v0.0.0-20190528120928-7df988a63f26/go.mod h1:3fxX6gUjWyI/2Bt7J1OLhpCzOfO/bB3AiX0cJtEKud0=
56-
github.com/matrix-org/gomatrixserverlib v0.0.0-20210621174423-185789a71f3a h1:ttpygr7uLtACsxDoTol1BTVqmMOyib0ZBovMOD6OzkU=
57-
github.com/matrix-org/gomatrixserverlib v0.0.0-20210621174423-185789a71f3a/go.mod h1:JsAzE1Ll3+gDWS9JSUHPJiiyAksvOOnGWF2nXdg4ZzU=
5856
github.com/matrix-org/gomatrixserverlib v0.0.0-20210624115417-42ac4e797a58 h1:PVn5mCHmdONm0k5d0/H+fdtI+/C156+J7vylnnvQWPY=
5957
github.com/matrix-org/gomatrixserverlib v0.0.0-20210624115417-42ac4e797a58/go.mod h1:JsAzE1Ll3+gDWS9JSUHPJiiyAksvOOnGWF2nXdg4ZzU=
6058
github.com/matrix-org/util v0.0.0-20190711121626-527ce5ddefc7 h1:ntrLa/8xVzeSs8vHFHK25k0C+NV74sYMJnNSg5NoSRo=
@@ -111,10 +109,12 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
111109
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
112110
golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d h1:1aflnvSoWWLI2k/dMUAl5lvU1YO4Mb4hz0gh+1rjcxU=
113111
golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
112+
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0=
113+
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
114114
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
115115
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
116-
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck=
117-
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
116+
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
117+
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
118118
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
119119
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
120120
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -125,10 +125,14 @@ golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7w
125125
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
126126
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw=
127127
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
128+
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
129+
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I=
130+
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
128131
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
129132
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
130133
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
131134
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
135+
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e h1:FDhOuMEY4JVRztM/gsbk+IKUQ8kj74bxZrgw87eMMVc=
132136
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
133137
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
134138
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

internal/client/client.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,9 @@ func (c *CSAPI) MustDoFunc(t *testing.T, method string, paths []string, opts ...
266266
t.Helper()
267267
res := c.DoFunc(t, method, paths, opts...)
268268
if res.StatusCode < 200 || res.StatusCode >= 300 {
269-
t.Fatalf("CSAPI.MustDoFunc response return non-2xx code: %s", res.Status)
269+
defer res.Body.Close()
270+
body, _ := ioutil.ReadAll(res.Body)
271+
t.Fatalf("CSAPI.MustDoFunc response return non-2xx code: %s - body: %s", res.Status, string(body))
270272
}
271273
return res
272274
}

tests/csapi/e2e_key_backup_test.go

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
package csapi_tests
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/tidwall/gjson"
8+
9+
"github.com/matrix-org/complement/internal/b"
10+
"github.com/matrix-org/complement/internal/client"
11+
"github.com/matrix-org/complement/internal/match"
12+
"github.com/matrix-org/complement/internal/must"
13+
)
14+
15+
type backupKey struct {
16+
isVerified bool
17+
firstMessageIndex float64
18+
forwardedCount float64
19+
}
20+
21+
// This test checks that the rules for replacing room keys are implemented correctly.
22+
// Specifically:
23+
//
24+
// if the keys have different values for is_verified, then it will keep the key that has is_verified set to true;
25+
// if they have the same values for is_verified, then it will keep the key with a lower first_message_index;
26+
// and finally, is is_verified and first_message_index are equal, then it will keep the key with a lower forwarded_count.
27+
func TestE2EKeyBackupReplaceRoomKeyRules(t *testing.T) {
28+
deployment := Deploy(t, b.BlueprintAlice)
29+
defer deployment.Destroy(t)
30+
userID := "@alice:hs1"
31+
roomID := "!foo:hs1"
32+
alice := deployment.Client(t, "hs1", userID)
33+
34+
// make a new key backup
35+
res := alice.MustDoFunc(t, "POST", []string{"_matrix", "client", "r0", "room_keys", "version"}, client.WithJSONBody(t, map[string]interface{}{
36+
"algorithm": "m.megolm_backup.v1",
37+
"auth_data": map[string]interface{}{
38+
"foo": "bar",
39+
},
40+
}))
41+
defer res.Body.Close()
42+
body := must.ParseJSON(t, res.Body)
43+
backupVersion := gjson.GetBytes(body, "version").Str
44+
if backupVersion == "" {
45+
t.Fatalf("failed to get 'version' key from response: %s", string(body))
46+
}
47+
48+
testCases := []struct {
49+
sessionID string // change this for each test case to namespace tests correctly
50+
input backupKey // the key to compare against
51+
keysThatDontReplace []backupKey // the keys which won't update the input key
52+
}{
53+
{
54+
sessionID: "a",
55+
input: backupKey{
56+
isVerified: false,
57+
firstMessageIndex: 10,
58+
forwardedCount: 5,
59+
},
60+
keysThatDontReplace: []backupKey{
61+
{
62+
isVerified: false,
63+
firstMessageIndex: 11, // higher first message index
64+
forwardedCount: 5,
65+
},
66+
{
67+
isVerified: false,
68+
firstMessageIndex: 10,
69+
forwardedCount: 6, // higher forwarded count
70+
},
71+
{
72+
isVerified: false,
73+
firstMessageIndex: 11, // higher first message index
74+
forwardedCount: 6, // higher forwarded count
75+
},
76+
},
77+
},
78+
{
79+
sessionID: "b",
80+
input: backupKey{
81+
isVerified: true,
82+
firstMessageIndex: 10,
83+
forwardedCount: 5,
84+
},
85+
keysThatDontReplace: []backupKey{
86+
{
87+
isVerified: false, // is verified is false
88+
firstMessageIndex: 11, // higher first message index
89+
forwardedCount: 5,
90+
},
91+
{
92+
isVerified: false, // is verified is false
93+
firstMessageIndex: 10,
94+
forwardedCount: 6, // higher forwarded count
95+
},
96+
{
97+
isVerified: false, // is verified is false
98+
firstMessageIndex: 11, // higher first message index
99+
forwardedCount: 6, // higher forwarded count
100+
},
101+
{
102+
isVerified: true,
103+
firstMessageIndex: 11, // higher first message index
104+
forwardedCount: 5,
105+
},
106+
{
107+
isVerified: true,
108+
firstMessageIndex: 10,
109+
forwardedCount: 6, // higher forwarded count
110+
},
111+
{
112+
isVerified: true,
113+
firstMessageIndex: 11, // higher first message index
114+
forwardedCount: 6, // higher forwarded count
115+
},
116+
},
117+
},
118+
}
119+
120+
t.Run("parallel", func(t *testing.T) {
121+
for i := range testCases {
122+
tc := testCases[i]
123+
t.Run(fmt.Sprintf("%+v", tc.input), func(t *testing.T) {
124+
t.Parallel()
125+
// insert the key that will be tested against
126+
alice.MustDoFunc(t, "PUT", []string{"_matrix", "client", "r0", "room_keys", "keys", roomID, tc.sessionID},
127+
client.WithQueries(map[string][]string{"version": {backupVersion}}), client.WithJSONBody(t, map[string]interface{}{
128+
"first_message_index": tc.input.firstMessageIndex,
129+
"forwarded_count": tc.input.forwardedCount,
130+
"is_verified": tc.input.isVerified,
131+
"session_data": map[string]interface{}{"a": "b"},
132+
}),
133+
)
134+
// now check that each key in keysThatDontReplace do not replace this key
135+
for _, testKey := range tc.keysThatDontReplace {
136+
alice.MustDoFunc(t, "PUT", []string{"_matrix", "client", "r0", "room_keys", "keys", roomID, tc.sessionID},
137+
client.WithQueries(map[string][]string{"version": {backupVersion}}), client.WithJSONBody(t, map[string]interface{}{
138+
"first_message_index": testKey.firstMessageIndex,
139+
"forwarded_count": testKey.forwardedCount,
140+
"is_verified": testKey.isVerified,
141+
"session_data": map[string]interface{}{"a": "b"},
142+
}),
143+
)
144+
checkResp := alice.MustDoFunc(t, "GET", []string{"_matrix", "client", "r0", "room_keys", "keys", roomID, tc.sessionID},
145+
client.WithQueries(map[string][]string{"version": {backupVersion}}),
146+
)
147+
must.MatchResponse(t, checkResp, match.HTTPResponse{
148+
StatusCode: 200,
149+
JSON: []match.JSON{
150+
match.JSONKeyEqual("first_message_index", tc.input.firstMessageIndex),
151+
match.JSONKeyEqual("forwarded_count", tc.input.forwardedCount),
152+
match.JSONKeyEqual("is_verified", tc.input.isVerified),
153+
},
154+
})
155+
}
156+
})
157+
}
158+
})
159+
}

tests/msc2716_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,12 @@ import (
1515
"testing"
1616
"time"
1717

18+
"github.com/tidwall/gjson"
19+
1820
"github.com/matrix-org/complement/internal/b"
1921
"github.com/matrix-org/complement/internal/client"
2022
"github.com/matrix-org/complement/internal/match"
2123
"github.com/matrix-org/complement/internal/must"
22-
"github.com/tidwall/gjson"
2324
)
2425

2526
type event struct {

tests/msc2946_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@ import (
77
"net/url"
88
"testing"
99

10+
"github.com/tidwall/gjson"
11+
1012
"github.com/matrix-org/complement/internal/b"
1113
"github.com/matrix-org/complement/internal/client"
1214
"github.com/matrix-org/complement/internal/match"
1315
"github.com/matrix-org/complement/internal/must"
14-
"github.com/tidwall/gjson"
1516
)
1617

1718
var (

tests/msc3083_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@ import (
99
"net/url"
1010
"testing"
1111

12+
"github.com/tidwall/gjson"
13+
1214
"github.com/matrix-org/complement/internal/b"
1315
"github.com/matrix-org/complement/internal/client"
1416
"github.com/matrix-org/complement/internal/docker"
1517
"github.com/matrix-org/complement/internal/match"
1618
"github.com/matrix-org/complement/internal/must"
17-
"github.com/tidwall/gjson"
1819
)
1920

2021
func failJoinRoom(t *testing.T, c *client.CSAPI, roomIDOrAlias string, serverName string) {

0 commit comments

Comments
 (0)