feat(cache): implement hashed API key storage and retrieval

Adds a new hashed key storage mechanism for API keys in the cache. 
Replaces direct mapping to API keys with composite keys based on 
organizationId and name. Implements searching of API keys using 
hash comparisons for improved security. Updates related tests to 
ensure correct functionality and validate the hashing. Also, 
adds support for a new dependency `golang.org/x/crypto`.
This commit is contained in:
2025-11-20 22:11:17 +01:00
parent 1e2236dc9e
commit 4468903535
11 changed files with 357 additions and 69 deletions
+24 -11
View File
@@ -2,10 +2,13 @@ package domain
import (
"context"
"strings"
"testing"
"github.com/stretchr/testify/assert"
"gitlab.com/unboundsoftware/eventsourced/eventsourced"
"github.com/stretchr/testify/require"
"gitlab.com/unboundsoftware/schemas/hash"
)
func TestAddAPIKey_Event(t *testing.T) {
@@ -24,7 +27,6 @@ func TestAddAPIKey_Event(t *testing.T) {
name string
fields fields
args args
want eventsourced.Event
}{
{
name: "event",
@@ -37,14 +39,6 @@ func TestAddAPIKey_Event(t *testing.T) {
Initiator: "jim@example.org",
},
args: args{},
want: &APIKeyAdded{
Name: "test",
Key: "dXNfYWtfMTIzNDU2Nzg5MDEyMzQ1NuOwxEKY/BwUmvv0yJlvuSQnrkHkZJuTTKSVmRt4UrhV",
Refs: []string{"Example@dev"},
Read: true,
Publish: true,
Initiator: "jim@example.org",
},
},
}
for _, tt := range tests {
@@ -57,7 +51,26 @@ func TestAddAPIKey_Event(t *testing.T) {
Publish: tt.fields.Publish,
Initiator: tt.fields.Initiator,
}
assert.Equalf(t, tt.want, a.Event(tt.args.in0), "Event(%v)", tt.args.in0)
event := a.Event(tt.args.in0)
require.NotNil(t, event)
// Cast to APIKeyAdded to verify fields
apiKeyEvent, ok := event.(*APIKeyAdded)
require.True(t, ok, "Event should be *APIKeyAdded")
// Verify non-key fields match exactly
assert.Equal(t, tt.fields.Name, apiKeyEvent.Name)
assert.Equal(t, tt.fields.Refs, apiKeyEvent.Refs)
assert.Equal(t, tt.fields.Read, apiKeyEvent.Read)
assert.Equal(t, tt.fields.Publish, apiKeyEvent.Publish)
assert.Equal(t, tt.fields.Initiator, apiKeyEvent.Initiator)
// Verify the key is hashed correctly (bcrypt format)
assert.True(t, strings.HasPrefix(apiKeyEvent.Key, "$2"), "Key should be bcrypt hashed")
assert.NotEqual(t, tt.fields.Key, apiKeyEvent.Key, "Key should be hashed, not plaintext")
// Verify the hash matches the original key
assert.True(t, hash.CompareAPIKey(apiKeyEvent.Key, tt.fields.Key), "Hashed key should match original")
})
}
}