From a2688564c8e03b475a304c7418db3badcb787913 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Wed, 28 Jul 2021 11:49:57 +0100 Subject: [PATCH 01/15] Define cross-signing types (matrix-org/dendrite#1312) --- crosssigning.go | 51 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 crosssigning.go diff --git a/crosssigning.go b/crosssigning.go new file mode 100644 index 00000000..cf99c910 --- /dev/null +++ b/crosssigning.go @@ -0,0 +1,51 @@ +// Copyright 2021 The Matrix.org Foundation C.I.C. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package gomatrixserverlib + +// CrossSigningBody represents either of the concrete types CrossSingingKeys or CrossSigningSignatures +type CrossSigningBody interface { + isCrossSigningBody() +} + +// https://spec.matrix.org/unstable/client-server-api/#post_matrixclientr0keysdevice_signingupload + +type CrossSigningKeys struct { + MasterKey CrossSigningKey `json:"master_key"` + SelfSigningKey CrossSigningKey `json:"self_signing_key"` + UserSigningKey CrossSigningKey `json:"user_signing_key"` +} + +type CrossSigningKey struct { + Signatures map[string]map[KeyID]Base64Bytes `json:"signatures"` + Keys map[KeyID]Base64Bytes `json:"keys"` + Usage []string `json:"usage"` + UserID string `json:"user_id"` +} + +func (s *CrossSigningKey) isCrossSigningBody() {} // implements CrossSigningBody + +// https://spec.matrix.org/unstable/client-server-api/#post_matrixclientr0keyssignaturesupload + +type CrossSigningSignatures map[string]map[string]CrossSigningBody // user ID -> device ID -> key or signature + +type CrossSigningSignature struct { + Algorithms []string `json:"algorithms"` + UserID string `json:"user_id"` + DeviceID string `json:"device_id"` + Keys map[KeyID]Base64Bytes `json:"keys"` + Signatures map[string]map[KeyID]Base64Bytes `json:"signatures"` +} + +func (s *CrossSigningSignature) isCrossSigningBody() {} // implements CrossSigningBody From 054b9cf2de8327f1041c7e90c15cc51b393bd9d1 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Wed, 28 Jul 2021 14:53:11 +0100 Subject: [PATCH 02/15] Exclude signatures key if empty --- crosssigning.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crosssigning.go b/crosssigning.go index cf99c910..9e56f56a 100644 --- a/crosssigning.go +++ b/crosssigning.go @@ -28,7 +28,7 @@ type CrossSigningKeys struct { } type CrossSigningKey struct { - Signatures map[string]map[KeyID]Base64Bytes `json:"signatures"` + Signatures map[string]map[KeyID]Base64Bytes `json:"signatures,omitempty"` Keys map[KeyID]Base64Bytes `json:"keys"` Usage []string `json:"usage"` UserID string `json:"user_id"` @@ -45,7 +45,7 @@ type CrossSigningSignature struct { UserID string `json:"user_id"` DeviceID string `json:"device_id"` Keys map[KeyID]Base64Bytes `json:"keys"` - Signatures map[string]map[KeyID]Base64Bytes `json:"signatures"` + Signatures map[string]map[KeyID]Base64Bytes `json:"signatures,omitempty"` } func (s *CrossSigningSignature) isCrossSigningBody() {} // implements CrossSigningBody From 8efb6cec19a0cee691e4c6c0259cc9a6f8d28339 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Wed, 28 Jul 2021 14:59:05 +0100 Subject: [PATCH 03/15] Define purpose consts --- crosssigning.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/crosssigning.go b/crosssigning.go index 9e56f56a..cddb7599 100644 --- a/crosssigning.go +++ b/crosssigning.go @@ -14,6 +14,14 @@ package gomatrixserverlib +type CrossSigningKeyPurpose string + +const ( + CrossSigningKeyPurposeMaster CrossSigningKeyPurpose = "master" + CrossSigningKeyPurposeSelfSigning CrossSigningKeyPurpose = "self_signing" + CrossSigningKeyPurposeUserSigning CrossSigningKeyPurpose = "user_signing" +) + // CrossSigningBody represents either of the concrete types CrossSingingKeys or CrossSigningSignatures type CrossSigningBody interface { isCrossSigningBody() @@ -30,7 +38,7 @@ type CrossSigningKeys struct { type CrossSigningKey struct { Signatures map[string]map[KeyID]Base64Bytes `json:"signatures,omitempty"` Keys map[KeyID]Base64Bytes `json:"keys"` - Usage []string `json:"usage"` + Usage []CrossSigningKeyPurpose `json:"usage"` UserID string `json:"user_id"` } From 43fa78d3763b36ce2c36f168fcadbec56234cdd1 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Wed, 28 Jul 2021 16:22:45 +0100 Subject: [PATCH 04/15] Scan for Base64Bytes --- base64.go | 18 ++++++++++++++++++ base64_test.go | 17 +++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/base64.go b/base64.go index ef9b36a3..f5d42ca9 100644 --- a/base64.go +++ b/base64.go @@ -18,6 +18,7 @@ package gomatrixserverlib import ( "encoding/base64" "encoding/json" + "fmt" "strings" ) @@ -26,6 +27,10 @@ import ( // // The bytes encoded using base64 when marshalled as JSON. // When the bytes are unmarshalled from JSON they are decoded from base64. +// +// When scanning directly from a database, a string column will be +// decoded from base64 automatically whereas a bytes column will be +// copied as-is. type Base64Bytes []byte // Encode encodes the bytes as base64 @@ -46,6 +51,19 @@ func (b64 *Base64Bytes) Decode(str string) error { return err } +// Implements sql.Scanner +func (b64 *Base64Bytes) Scan(src interface{}) error { + switch v := src.(type) { + case string: + return b64.Decode(v) + case []byte: + *b64 = append(Base64Bytes{}, v...) + return nil + default: + return fmt.Errorf("unsupported source type") + } +} + // MarshalJSON encodes the bytes as base64 and then encodes the base64 as a JSON string. // This takes a value receiver so that maps and slices of Base64Bytes encode correctly. func (b64 Base64Bytes) MarshalJSON() ([]byte, error) { diff --git a/base64_test.go b/base64_test.go index 9b82e193..f346c7c6 100644 --- a/base64_test.go +++ b/base64_test.go @@ -150,3 +150,20 @@ func TestUnmarshalYAMLBase64Struct(t *testing.T) { t.Fatalf("yaml.Unmarshal(%v): wanted %q got %q", input, want, result) } } + +func TestScanBase64(t *testing.T) { + str := "PHq54MtxJxVcavizqxvFZ4E4Xd2GpWJYg6wCVs7DamA" + bya := []byte(str) + itg := 3 + + var b Base64Bytes + if err := b.Scan(str); err != nil { + t.Fatal(err) + } + if err := b.Scan(bya); err != nil { + t.Fatal(err) + } + if err := b.Scan(itg); err == nil { + t.Fatal("should have failed") + } +} From cf79119d7492a206df431ba765e519610c76a8e6 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Thu, 29 Jul 2021 09:51:26 +0100 Subject: [PATCH 05/15] Conform to sql.Valuer interface too --- base64.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/base64.go b/base64.go index f5d42ca9..59d165c3 100644 --- a/base64.go +++ b/base64.go @@ -16,6 +16,7 @@ package gomatrixserverlib import ( + "database/sql/driver" "encoding/base64" "encoding/json" "fmt" @@ -56,14 +57,16 @@ func (b64 *Base64Bytes) Scan(src interface{}) error { switch v := src.(type) { case string: return b64.Decode(v) - case []byte: - *b64 = append(Base64Bytes{}, v...) - return nil default: return fmt.Errorf("unsupported source type") } } +// Implements sql.Valuer +func (b64 *Base64Bytes) Value() (driver.Value, error) { + return b64.Encode(), nil +} + // MarshalJSON encodes the bytes as base64 and then encodes the base64 as a JSON string. // This takes a value receiver so that maps and slices of Base64Bytes encode correctly. func (b64 Base64Bytes) MarshalJSON() ([]byte, error) { From a2fa40ca935a8ea073ef62f154212c6a59d21244 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Thu, 29 Jul 2021 09:57:30 +0100 Subject: [PATCH 06/15] Without pointer receiver --- base64.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base64.go b/base64.go index 59d165c3..92fa3034 100644 --- a/base64.go +++ b/base64.go @@ -63,7 +63,7 @@ func (b64 *Base64Bytes) Scan(src interface{}) error { } // Implements sql.Valuer -func (b64 *Base64Bytes) Value() (driver.Value, error) { +func (b64 Base64Bytes) Value() (driver.Value, error) { return b64.Encode(), nil } From 16ebeb5d078830bc0a4f308c260af106ff34ee8f Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Thu, 29 Jul 2021 15:44:22 +0100 Subject: [PATCH 07/15] Remove unuseful types --- crosssigning.go | 25 ++++++------------------- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/crosssigning.go b/crosssigning.go index cddb7599..422ef7e6 100644 --- a/crosssigning.go +++ b/crosssigning.go @@ -22,38 +22,25 @@ const ( CrossSigningKeyPurposeUserSigning CrossSigningKeyPurpose = "user_signing" ) -// CrossSigningBody represents either of the concrete types CrossSingingKeys or CrossSigningSignatures -type CrossSigningBody interface { - isCrossSigningBody() -} - -// https://spec.matrix.org/unstable/client-server-api/#post_matrixclientr0keysdevice_signingupload - type CrossSigningKeys struct { - MasterKey CrossSigningKey `json:"master_key"` - SelfSigningKey CrossSigningKey `json:"self_signing_key"` - UserSigningKey CrossSigningKey `json:"user_signing_key"` + MasterKey CrossSigningForKey `json:"master_key"` + SelfSigningKey CrossSigningForKey `json:"self_signing_key"` + UserSigningKey CrossSigningForKey `json:"user_signing_key"` } -type CrossSigningKey struct { +// https://spec.matrix.org/unstable/client-server-api/#post_matrixclientr0keysdevice_signingupload +type CrossSigningForKey struct { Signatures map[string]map[KeyID]Base64Bytes `json:"signatures,omitempty"` Keys map[KeyID]Base64Bytes `json:"keys"` Usage []CrossSigningKeyPurpose `json:"usage"` UserID string `json:"user_id"` } -func (s *CrossSigningKey) isCrossSigningBody() {} // implements CrossSigningBody - // https://spec.matrix.org/unstable/client-server-api/#post_matrixclientr0keyssignaturesupload - -type CrossSigningSignatures map[string]map[string]CrossSigningBody // user ID -> device ID -> key or signature - -type CrossSigningSignature struct { +type CrossSigningForDevice struct { Algorithms []string `json:"algorithms"` UserID string `json:"user_id"` DeviceID string `json:"device_id"` Keys map[KeyID]Base64Bytes `json:"keys"` Signatures map[string]map[KeyID]Base64Bytes `json:"signatures,omitempty"` } - -func (s *CrossSigningSignature) isCrossSigningBody() {} // implements CrossSigningBody From dadeeff7cf486d43ff8ccd2fbffadea7b9cfa4e4 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Thu, 29 Jul 2021 18:06:48 +0100 Subject: [PATCH 08/15] CrossSigningForKeyOrDevice --- crosssigning.go | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/crosssigning.go b/crosssigning.go index 422ef7e6..6d782d78 100644 --- a/crosssigning.go +++ b/crosssigning.go @@ -14,6 +14,12 @@ package gomatrixserverlib +import ( + "encoding/json" + + "github.com/tidwall/gjson" +) + type CrossSigningKeyPurpose string const ( @@ -36,6 +42,8 @@ type CrossSigningForKey struct { UserID string `json:"user_id"` } +func (s *CrossSigningForKey) isCrossSigningBody() {} // implements CrossSigningBody + // https://spec.matrix.org/unstable/client-server-api/#post_matrixclientr0keyssignaturesupload type CrossSigningForDevice struct { Algorithms []string `json:"algorithms"` @@ -44,3 +52,24 @@ type CrossSigningForDevice struct { Keys map[KeyID]Base64Bytes `json:"keys"` Signatures map[string]map[KeyID]Base64Bytes `json:"signatures,omitempty"` } + +func (s *CrossSigningForDevice) isCrossSigningBody() {} // implements CrossSigningBody + +type CrossSigningBody interface { + isCrossSigningBody() +} + +type CrossSigningForKeyOrDevice struct { + CrossSigningBody +} + +// Implements json.Unmarshaler +func (c *CrossSigningForKeyOrDevice) UnmarshalJSON(b []byte) error { + if gjson.Get(string(b), "device_id").Exists() { + body := &CrossSigningForDevice{} + return json.Unmarshal(b, body) + } else { + body := &CrossSigningForDevice{} + return json.Unmarshal(b, body) + } +} From bf187f61a1f2bf2407e1f65babe2e399f574d171 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Thu, 29 Jul 2021 18:27:23 +0100 Subject: [PATCH 09/15] Base64Bytes from RawJSON --- base64.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/base64.go b/base64.go index 92fa3034..fd05cd05 100644 --- a/base64.go +++ b/base64.go @@ -57,6 +57,11 @@ func (b64 *Base64Bytes) Scan(src interface{}) error { switch v := src.(type) { case string: return b64.Decode(v) + case []byte: + *b64 = append([]byte{}, v...) + return nil + case RawJSON: + return json.Unmarshal(v, b64) default: return fmt.Errorf("unsupported source type") } From 43ab1125ff285551237e5c6625a3fcdf6f7a8800 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Fri, 30 Jul 2021 09:38:32 +0100 Subject: [PATCH 10/15] Extend RespQueryKeys --- crosssigning.go | 5 ++--- federationtypes.go | 4 +++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/crosssigning.go b/crosssigning.go index 6d782d78..ad22324b 100644 --- a/crosssigning.go +++ b/crosssigning.go @@ -68,8 +68,7 @@ func (c *CrossSigningForKeyOrDevice) UnmarshalJSON(b []byte) error { if gjson.Get(string(b), "device_id").Exists() { body := &CrossSigningForDevice{} return json.Unmarshal(b, body) - } else { - body := &CrossSigningForDevice{} - return json.Unmarshal(b, body) } + body := &CrossSigningForKey{} + return json.Unmarshal(b, body) } diff --git a/federationtypes.go b/federationtypes.go index f943d325..d759e27c 100644 --- a/federationtypes.go +++ b/federationtypes.go @@ -874,7 +874,9 @@ type RespClaimKeys struct { // RespQueryKeys is the response for https://matrix.org/docs/spec/server_server/latest#post-matrix-federation-v1-user-keys-query type RespQueryKeys struct { - DeviceKeys map[string]map[string]DeviceKeys `json:"device_keys"` + DeviceKeys map[string]map[string]DeviceKeys `json:"device_keys"` + MasterKeys map[string]map[KeyID]CrossSigningForKeyOrDevice `json:"master_keys"` + SelfSigningKeys map[string]map[KeyID]CrossSigningForKeyOrDevice `json:"self_signing_keys"` } // DeviceKeys as per https://matrix.org/docs/spec/server_server/latest#post-matrix-federation-v1-user-keys-query From af74e232351ce060922f5e4eebf88529c014d2ea Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Fri, 30 Jul 2021 09:51:52 +0100 Subject: [PATCH 11/15] Fix type --- federationtypes.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/federationtypes.go b/federationtypes.go index d759e27c..a4e4f101 100644 --- a/federationtypes.go +++ b/federationtypes.go @@ -874,9 +874,9 @@ type RespClaimKeys struct { // RespQueryKeys is the response for https://matrix.org/docs/spec/server_server/latest#post-matrix-federation-v1-user-keys-query type RespQueryKeys struct { - DeviceKeys map[string]map[string]DeviceKeys `json:"device_keys"` - MasterKeys map[string]map[KeyID]CrossSigningForKeyOrDevice `json:"master_keys"` - SelfSigningKeys map[string]map[KeyID]CrossSigningForKeyOrDevice `json:"self_signing_keys"` + DeviceKeys map[string]map[string]DeviceKeys `json:"device_keys"` + MasterKeys map[string]CrossSigningForKeyOrDevice `json:"master_keys"` + SelfSigningKeys map[string]CrossSigningForKeyOrDevice `json:"self_signing_keys"` } // DeviceKeys as per https://matrix.org/docs/spec/server_server/latest#post-matrix-federation-v1-user-keys-query From 90d21bddf7e81071fd70763e461e78e5c8d35dcd Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Fri, 30 Jul 2021 11:22:48 +0100 Subject: [PATCH 12/15] Fix CrossSigningFrorKeyOrDevice unmarshaller --- crosssigning.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/crosssigning.go b/crosssigning.go index ad22324b..7f50e4b9 100644 --- a/crosssigning.go +++ b/crosssigning.go @@ -67,8 +67,16 @@ type CrossSigningForKeyOrDevice struct { func (c *CrossSigningForKeyOrDevice) UnmarshalJSON(b []byte) error { if gjson.Get(string(b), "device_id").Exists() { body := &CrossSigningForDevice{} - return json.Unmarshal(b, body) + if err := json.Unmarshal(b, body); err != nil { + return err + } + c.CrossSigningBody = body + return nil } body := &CrossSigningForKey{} - return json.Unmarshal(b, body) + if err := json.Unmarshal(b, body); err != nil { + return err + } + c.CrossSigningBody = body + return nil } From 73fcd4bb6a74fc9adc6c7996fc21cc39c5752997 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Fri, 30 Jul 2021 13:51:29 +0100 Subject: [PATCH 13/15] Update types --- crosssigning.go | 25 +++++++------------------ federationtypes.go | 17 +++++++++++++++++ 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/crosssigning.go b/crosssigning.go index 7f50e4b9..e999c84d 100644 --- a/crosssigning.go +++ b/crosssigning.go @@ -29,31 +29,20 @@ const ( ) type CrossSigningKeys struct { - MasterKey CrossSigningForKey `json:"master_key"` - SelfSigningKey CrossSigningForKey `json:"self_signing_key"` - UserSigningKey CrossSigningForKey `json:"user_signing_key"` + MasterKey CrossSigningKey `json:"master_key"` + SelfSigningKey CrossSigningKey `json:"self_signing_key"` + UserSigningKey CrossSigningKey `json:"user_signing_key"` } // https://spec.matrix.org/unstable/client-server-api/#post_matrixclientr0keysdevice_signingupload -type CrossSigningForKey struct { +type CrossSigningKey struct { Signatures map[string]map[KeyID]Base64Bytes `json:"signatures,omitempty"` Keys map[KeyID]Base64Bytes `json:"keys"` Usage []CrossSigningKeyPurpose `json:"usage"` UserID string `json:"user_id"` } -func (s *CrossSigningForKey) isCrossSigningBody() {} // implements CrossSigningBody - -// https://spec.matrix.org/unstable/client-server-api/#post_matrixclientr0keyssignaturesupload -type CrossSigningForDevice struct { - Algorithms []string `json:"algorithms"` - UserID string `json:"user_id"` - DeviceID string `json:"device_id"` - Keys map[KeyID]Base64Bytes `json:"keys"` - Signatures map[string]map[KeyID]Base64Bytes `json:"signatures,omitempty"` -} - -func (s *CrossSigningForDevice) isCrossSigningBody() {} // implements CrossSigningBody +func (s *CrossSigningKey) isCrossSigningBody() {} // implements CrossSigningBody type CrossSigningBody interface { isCrossSigningBody() @@ -66,14 +55,14 @@ type CrossSigningForKeyOrDevice struct { // Implements json.Unmarshaler func (c *CrossSigningForKeyOrDevice) UnmarshalJSON(b []byte) error { if gjson.Get(string(b), "device_id").Exists() { - body := &CrossSigningForDevice{} + body := &DeviceKeys{} if err := json.Unmarshal(b, body); err != nil { return err } c.CrossSigningBody = body return nil } - body := &CrossSigningForKey{} + body := &CrossSigningKey{} if err := json.Unmarshal(b, body); err != nil { return err } diff --git a/federationtypes.go b/federationtypes.go index a4e4f101..1d8daa66 100644 --- a/federationtypes.go +++ b/federationtypes.go @@ -2,6 +2,7 @@ package gomatrixserverlib import ( "context" + "database/sql/driver" "encoding/json" "fmt" "io" @@ -887,6 +888,22 @@ type DeviceKeys struct { Unsigned map[string]interface{} `json:"unsigned"` } +func (s *DeviceKeys) isCrossSigningBody() {} // implements CrossSigningBody + +func (s *DeviceKeys) Scan(src interface{}) error { + switch v := src.(type) { + case string: + return json.Unmarshal([]byte(v), s) + case []byte: + return json.Unmarshal(v, s) + } + return fmt.Errorf("unsupported source type") +} + +func (s DeviceKeys) Value() (driver.Value, error) { + return json.Marshal(s) +} + // MSC2836EventRelationshipsRequest is a request to /event_relationships from // https://github.com/matrix-org/matrix-doc/blob/kegan/msc/threading/proposals/2836-threading.md // nolint:maligned From 167a408ac8c968b788750658b4a40d1632676b55 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Mon, 2 Aug 2021 11:34:49 +0100 Subject: [PATCH 14/15] Update types in RespUserDeviceKeys --- federationtypes.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/federationtypes.go b/federationtypes.go index 1d8daa66..40d754f0 100644 --- a/federationtypes.go +++ b/federationtypes.go @@ -244,11 +244,11 @@ type RespUserDeviceKeys struct { DeviceID string `json:"device_id"` Algorithms []string `json:"algorithms"` // E.g "curve25519:JLAFKJWSCS": "3C5BFWi2Y8MaVvjM8M22DBmh24PmgR0nPvJOIArzgyI" - Keys map[string]string `json:"keys"` + Keys map[KeyID]Base64Bytes `json:"keys"` // E.g "@alice:example.com": { // "ed25519:JLAFKJWSCS": "dSO80A01XiigH3uBiDVx/EjzaoycHcjq9lfQX0uWsqxl2giMIiSPR8a4d291W1ihKJL/a+myXS367WT6NAIcBA" // } - Signatures map[string]map[string]string `json:"signatures"` + Signatures map[string]map[KeyID]Base64Bytes `json:"signatures"` } // UnmarshalJSON implements json.Unmarshaller From 1a15f53cd401f0351a362ce38ebee834f0127883 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Mon, 2 Aug 2021 13:05:25 +0100 Subject: [PATCH 15/15] Review comments --- base64.go | 5 +++-- base64_test.go | 34 +++++++++++++++++++++++++++------- crosssigning.go | 2 +- 3 files changed, 31 insertions(+), 10 deletions(-) diff --git a/base64.go b/base64.go index fd05cd05..5d4f8021 100644 --- a/base64.go +++ b/base64.go @@ -58,10 +58,11 @@ func (b64 *Base64Bytes) Scan(src interface{}) error { case string: return b64.Decode(v) case []byte: - *b64 = append([]byte{}, v...) + new := append(Base64Bytes{}, v...) + b64 = &new return nil case RawJSON: - return json.Unmarshal(v, b64) + return b64.UnmarshalJSON(v) default: return fmt.Errorf("unsupported source type") } diff --git a/base64_test.go b/base64_test.go index f346c7c6..b9652e26 100644 --- a/base64_test.go +++ b/base64_test.go @@ -16,6 +16,7 @@ package gomatrixserverlib import ( + "bytes" "encoding/json" "testing" @@ -152,18 +153,37 @@ func TestUnmarshalYAMLBase64Struct(t *testing.T) { } func TestScanBase64(t *testing.T) { - str := "PHq54MtxJxVcavizqxvFZ4E4Xd2GpWJYg6wCVs7DamA" - bya := []byte(str) - itg := 3 + expecting := Base64Bytes("This is a test string") + + inputStr := "VGhpcyBpcyBhIHRlc3Qgc3RyaW5n" + inputJSON := RawJSON(`"` + inputStr + `"`) + inputBytes := []byte(inputStr) + inputInt := 3 var b Base64Bytes - if err := b.Scan(str); err != nil { + + if err := b.Scan(inputStr); err != nil { + t.Fatal(err) + } + if !bytes.Equal(expecting, b) { + t.Fatalf("scanning from string failed, got %v, wanted %v", b, expecting) + } + + if err := b.Scan(inputJSON); err != nil { t.Fatal(err) } - if err := b.Scan(bya); err != nil { + if !bytes.Equal(expecting, b) { + t.Fatalf("scanning from RawJSON failed, got %v, wanted %v", b, expecting) + } + + if err := b.Scan(inputBytes); err != nil { t.Fatal(err) } - if err := b.Scan(itg); err == nil { - t.Fatal("should have failed") + if !bytes.Equal(expecting, b) { + t.Fatalf("scanning from []byte failed, got %v, wanted %v", b, expecting) + } + + if err := b.Scan(inputInt); err == nil { + t.Fatal("scanning from int should have failed but didn't") } } diff --git a/crosssigning.go b/crosssigning.go index e999c84d..6c7e83d1 100644 --- a/crosssigning.go +++ b/crosssigning.go @@ -54,7 +54,7 @@ type CrossSigningForKeyOrDevice struct { // Implements json.Unmarshaler func (c *CrossSigningForKeyOrDevice) UnmarshalJSON(b []byte) error { - if gjson.Get(string(b), "device_id").Exists() { + if gjson.GetBytes(b, "device_id").Exists() { body := &DeviceKeys{} if err := json.Unmarshal(b, body); err != nil { return err