Files
schemas/hash/hash_test.go
T

170 lines
4.1 KiB
Go
Raw Normal View History

package hash
import (
"strings"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestAPIKey(t *testing.T) {
key := "test_api_key_12345" // gitleaks:allow
hash1, err := APIKey(key)
require.NoError(t, err)
assert.NotEmpty(t, hash1)
assert.NotEqual(t, key, hash1, "Hash should not equal plaintext")
// Bcrypt hashes should start with $2
assert.True(t, strings.HasPrefix(hash1, "$2"), "Should be a bcrypt hash")
// Same key should produce different hashes (due to salt)
hash2, err := APIKey(key)
require.NoError(t, err)
assert.NotEqual(t, hash1, hash2, "Bcrypt should produce different hashes with different salts")
}
func TestCompareAPIKey_Bcrypt(t *testing.T) {
key := "test_api_key_12345" // gitleaks:allow
hash, err := APIKey(key)
require.NoError(t, err)
// Correct key should match
assert.True(t, CompareAPIKey(hash, key))
// Wrong key should not match
assert.False(t, CompareAPIKey(hash, "wrong_key"))
}
func TestCompareAPIKey_Legacy(t *testing.T) {
key := "test_api_key_12345" // gitleaks:allow
// Create a legacy SHA256 hash
legacyHash := String(key)
// Should still work with legacy hashes
assert.True(t, CompareAPIKey(legacyHash, key))
// Wrong key should not match
assert.False(t, CompareAPIKey(legacyHash, "wrong_key"))
}
func TestCompareAPIKey_BackwardCompatibility(t *testing.T) {
tests := []struct {
name string
hashFunc func(string) string
expectOK bool
}{
{
name: "bcrypt hash",
hashFunc: func(k string) string {
h, _ := APIKey(k)
return h
},
expectOK: true,
},
{
name: "legacy SHA256 hash",
hashFunc: func(k string) string {
return String(k)
},
expectOK: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
key := "test_key_123"
hash := tt.hashFunc(key)
result := CompareAPIKey(hash, key)
assert.Equal(t, tt.expectOK, result)
})
}
}
func TestString(t *testing.T) {
// Test that String function still works (for non-sensitive data)
input := "test_string"
hash1 := String(input)
hash2 := String(input)
// SHA256 should be deterministic
assert.Equal(t, hash1, hash2)
assert.NotEmpty(t, hash1)
assert.NotEqual(t, input, hash1)
}
func TestIsLegacyHash(t *testing.T) {
tests := []struct {
name string
hash string
isLegacy bool
}{
{
name: "bcrypt hash",
hash: "$2a$12$abcdefghijklmnopqrstuv",
isLegacy: false,
},
{
name: "SHA256 hash",
hash: "dXNfYWtfMTIzNDU2Nzg5MDEyMzQ1NuOwxEKY",
isLegacy: true,
},
{
name: "empty string",
hash: "",
isLegacy: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equal(t, tt.isLegacy, IsLegacyHash(tt.hash))
})
}
}
func TestMigrateAPIKeyHash(t *testing.T) {
plainKey := "test_api_key_123"
t.Run("migrate legacy hash", func(t *testing.T) {
// Create a legacy SHA256 hash
legacyHash := String(plainKey)
// Migrate it
newHash, migrated, err := MigrateAPIKeyHash(legacyHash, plainKey)
require.NoError(t, err)
assert.True(t, migrated, "Should indicate migration occurred")
assert.NotEqual(t, legacyHash, newHash, "New hash should differ from legacy")
assert.True(t, strings.HasPrefix(newHash, "$2"), "New hash should be bcrypt")
// Verify new hash works
assert.True(t, CompareAPIKey(newHash, plainKey))
})
t.Run("no migration needed for bcrypt", func(t *testing.T) {
// Create a bcrypt hash
bcryptHash, err := APIKey(plainKey)
require.NoError(t, err)
// Try to migrate it
newHash, migrated, err := MigrateAPIKeyHash(bcryptHash, plainKey)
require.NoError(t, err)
assert.False(t, migrated, "Should not migrate bcrypt hash")
assert.Equal(t, bcryptHash, newHash, "Hash should remain unchanged")
})
t.Run("invalid key does not migrate", func(t *testing.T) {
legacyHash := String("correct_key")
// Try to migrate with wrong plaintext
newHash, migrated, err := MigrateAPIKeyHash(legacyHash, "wrong_key")
require.NoError(t, err)
assert.False(t, migrated, "Should not migrate invalid key")
assert.Empty(t, newHash, "Should return empty for invalid key")
})
}