Skip to content

Commit

Permalink
Add Equal method for CrossSigningKey (#444)
Browse files Browse the repository at this point in the history
Playing around with Copilot, code is mostly generated (but reviewed)

Also fixes CI by using the correct repository for Dendrite.
  • Loading branch information
S7evinK authored Jan 6, 2025
1 parent e86ab16 commit bf86bc9
Show file tree
Hide file tree
Showing 3 changed files with 173 additions and 1 deletion.
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ jobs:
steps:
- uses: actions/checkout@v3
with:
repository: "matrix-org/dendrite"
repository: "element-hq/dendrite"
- name: Install libolm
run: sudo apt-get install libolm-dev libolm3
- name: Setup go
Expand Down
53 changes: 53 additions & 0 deletions fclient/crosssigning.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
package fclient

import (
"bytes"
"encoding/json"
"slices"

"github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/gomatrixserverlib/spec"
Expand Down Expand Up @@ -46,6 +48,57 @@ type CrossSigningKey struct {

func (s *CrossSigningKey) isCrossSigningBody() {} // implements CrossSigningBody

func (s *CrossSigningKey) Equal(other *CrossSigningKey) bool {
if s == nil || other == nil {
return false
}
if s.UserID != other.UserID {
return false
}
if len(s.Usage) != len(other.Usage) {
return false
}

// Make sure the slices are sorted before we compare them.
if !slices.IsSorted(s.Usage) {
slices.Sort(s.Usage)
}
if !slices.IsSorted(other.Usage) {
slices.Sort(other.Usage)
}
for i := range s.Usage {
if s.Usage[i] != other.Usage[i] {
return false
}
}
if len(s.Keys) != len(other.Keys) {
return false
}
for k, v := range s.Keys {
if !bytes.Equal(other.Keys[k], v) {
return false
}
}
if len(s.Signatures) != len(other.Signatures) {
return false
}
for k, v := range s.Signatures {
otherV, ok := other.Signatures[k]
if !ok {
return false
}
if len(v) != len(otherV) {
return false
}
for k2, v2 := range v {
if !bytes.Equal(otherV[k2], v2) {
return false
}
}
}
return true
}

type CrossSigningBody interface {
isCrossSigningBody()
}
Expand Down
119 changes: 119 additions & 0 deletions fclient/crosssigning_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
package fclient

import (
"testing"

"github.com/matrix-org/gomatrixserverlib"
"github.com/matrix-org/gomatrixserverlib/spec"
)

var tests = []struct {
name string
s *CrossSigningKey
other *CrossSigningKey
expect bool
}{
{
name: "NilReceiver_ReturnsFalse",
s: nil,
other: &CrossSigningKey{},
expect: false,
},
{
name: "NilOther_ReturnsFalse",
s: &CrossSigningKey{},
other: nil,
expect: false,
},
{
name: "DifferentUserID_ReturnsFalse",
s: &CrossSigningKey{UserID: "user1"},
other: &CrossSigningKey{UserID: "user2"},
expect: false,
},
{
name: "DifferentUsageLength_ReturnsFalse",
s: &CrossSigningKey{Usage: []CrossSigningKeyPurpose{CrossSigningKeyPurposeMaster}},
other: &CrossSigningKey{Usage: []CrossSigningKeyPurpose{CrossSigningKeyPurposeMaster, CrossSigningKeyPurposeSelfSigning}},
expect: false,
},
{
name: "UnsortedUsages_ReturnsTrue",
s: &CrossSigningKey{Usage: []CrossSigningKeyPurpose{CrossSigningKeyPurposeSelfSigning, CrossSigningKeyPurposeMaster}},
other: &CrossSigningKey{Usage: []CrossSigningKeyPurpose{CrossSigningKeyPurposeMaster, CrossSigningKeyPurposeSelfSigning}},
expect: true,
},
{
name: "UnsortedUsages_ReturnsTrue",
s: &CrossSigningKey{Usage: []CrossSigningKeyPurpose{CrossSigningKeyPurposeSelfSigning, CrossSigningKeyPurposeMaster}},
other: &CrossSigningKey{Usage: []CrossSigningKeyPurpose{CrossSigningKeyPurposeSelfSigning, CrossSigningKeyPurposeMaster}},
expect: true,
},
{
name: "DifferentUsageValues_ReturnsFalse",
s: &CrossSigningKey{Usage: []CrossSigningKeyPurpose{CrossSigningKeyPurposeMaster}},
other: &CrossSigningKey{Usage: []CrossSigningKeyPurpose{CrossSigningKeyPurposeSelfSigning}},
expect: false,
},
{
name: "DifferentKeysLength_ReturnsFalse",
s: &CrossSigningKey{Keys: map[gomatrixserverlib.KeyID]spec.Base64Bytes{"key1": {}}},
other: &CrossSigningKey{Keys: map[gomatrixserverlib.KeyID]spec.Base64Bytes{"key1": {}, "key2": {}}},
expect: false,
},
{
name: "DifferentKeysValues_ReturnsFalse",
s: &CrossSigningKey{Keys: map[gomatrixserverlib.KeyID]spec.Base64Bytes{"key1": {}}},
other: &CrossSigningKey{Keys: map[gomatrixserverlib.KeyID]spec.Base64Bytes{"key1": {1}}},
expect: false,
},
{
name: "DifferentSignaturesLength_ReturnsFalse",
s: &CrossSigningKey{Signatures: map[string]map[gomatrixserverlib.KeyID]spec.Base64Bytes{"sig1": {"key1": {}}}},
other: &CrossSigningKey{Signatures: map[string]map[gomatrixserverlib.KeyID]spec.Base64Bytes{"sig1": {"key1": {}}, "sig2": {"key2": {}}}},
expect: false,
},
{
name: "DifferentSignaturesValues_ReturnsFalse",
s: &CrossSigningKey{Signatures: map[string]map[gomatrixserverlib.KeyID]spec.Base64Bytes{"sig1": {"key1": {}}}},
other: &CrossSigningKey{Signatures: map[string]map[gomatrixserverlib.KeyID]spec.Base64Bytes{"sig1": {"key1": {1}}}},
expect: false,
},
{
name: "IdenticalKeys_ReturnsTrue",
s: &CrossSigningKey{
UserID: "user1",
Usage: []CrossSigningKeyPurpose{CrossSigningKeyPurposeMaster},
Keys: map[gomatrixserverlib.KeyID]spec.Base64Bytes{"key1": {}},
Signatures: map[string]map[gomatrixserverlib.KeyID]spec.Base64Bytes{"sig1": {"key1": {}}},
},
other: &CrossSigningKey{
UserID: "user1",
Usage: []CrossSigningKeyPurpose{CrossSigningKeyPurposeMaster},
Keys: map[gomatrixserverlib.KeyID]spec.Base64Bytes{"key1": {}},
Signatures: map[string]map[gomatrixserverlib.KeyID]spec.Base64Bytes{"sig1": {"key1": {}}},
},
expect: true,
},
}

func TestCrossSigningKeyEqual(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := tt.s.Equal(tt.other); got != tt.expect {
t.Errorf("Equal() = %v, want %v", got, tt.expect)
}
})
}
}

func BenchmarkEqual(b *testing.B) {

for i := 0; i < b.N; i++ {
for _, tt := range tests {
if !tt.s.Equal(tt.other) && tt.expect {
b.Fatal(tt.name, tt.s)
}
}
}
}

0 comments on commit bf86bc9

Please sign in to comment.