diff --git a/tests/csapi/upload_keys_test.go b/tests/csapi/upload_keys_test.go index 6a0a94ed..9cf64d8f 100644 --- a/tests/csapi/upload_keys_test.go +++ b/tests/csapi/upload_keys_test.go @@ -5,6 +5,7 @@ import ( "net/http" "strings" "testing" + "time" "github.com/tidwall/gjson" @@ -174,6 +175,46 @@ func TestUploadKey(t *testing.T) { }) } +// Per MSC4225, keys must be issued in the same order they are uploaded +func TestKeyClaimOrdering(t *testing.T) { + deployment := complement.Deploy(t, 1) + defer deployment.Destroy(t) + alice := deployment.Register(t, "hs1", helpers.RegistrationOpts{}) + _, oneTimeKeys := alice.MustGenerateOneTimeKeys(t, 2) + + // first upload key 1, sleep a bit, then upload key 0. + otk1 := map[string]interface{}{"signed_curve25519:1": oneTimeKeys["signed_curve25519:1"]} + alice.MustDo(t, "POST", []string{"_matrix", "client", "v3", "keys", "upload"}, + client.WithJSONBody(t, map[string]interface{}{"one_time_keys": otk1})) + + // Ensure that there is a difference in timestamp between the two upload requests. + time.Sleep(1 * time.Second) + + otk0 := map[string]interface{}{"signed_curve25519:0": oneTimeKeys["signed_curve25519:0"]} + alice.MustDo(t, "POST", []string{"_matrix", "client", "v3", "keys", "upload"}, + client.WithJSONBody(t, map[string]interface{}{"one_time_keys": otk0})) + + // Now claim the keys, and check they come back in the right order + reqBody := client.WithJSONBody(t, map[string]interface{}{ + "one_time_keys": map[string]interface{}{ + alice.UserID: map[string]string{ + alice.DeviceID: "signed_curve25519", + }, + }, + }) + otksField := "one_time_keys." + client.GjsonEscape(alice.UserID) + "." + client.GjsonEscape(alice.DeviceID) + resp := alice.MustDo(t, "POST", []string{"_matrix", "client", "v3", "keys", "claim"}, reqBody) + must.MatchResponse(t, resp, match.HTTPResponse{ + StatusCode: http.StatusOK, + JSON: []match.JSON{match.JSONKeyEqual(otksField, otk1)}, + }) + resp = alice.MustDo(t, "POST", []string{"_matrix", "client", "v3", "keys", "claim"}, reqBody) + must.MatchResponse(t, resp, match.HTTPResponse{ + StatusCode: http.StatusOK, + JSON: []match.JSON{match.JSONKeyEqual(otksField, otk0)}, + }) +} + // Tests idempotency of the /keys/upload endpoint. // Tests that if you upload 4 OTKs then upload the same 4, no error is returned. func TestUploadKeyIdempotency(t *testing.T) {