From 14f96f4935bc7683accfe9d951ad868d994bd66f Mon Sep 17 00:00:00 2001 From: Gabriel Radureau Date: Tue, 5 May 2026 10:06:55 +0200 Subject: [PATCH] tests: SHA-256 fingerprint stays non-empty and != secret value --- pkg/user/jwt_manager_test.go | 45 ++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/pkg/user/jwt_manager_test.go b/pkg/user/jwt_manager_test.go index 428e0db..26a11b1 100644 --- a/pkg/user/jwt_manager_test.go +++ b/pkg/user/jwt_manager_test.go @@ -186,3 +186,48 @@ func TestListJWTSecretsInfo_ReturnsMetadataOnlyNotSecretValues(t *testing.T) { } assert.True(t, foundPrimary) } + +// TestListJWTSecretsInfo_SecretSHA256NonEmptyAndDifferentFromSecret verifies +// the security property that SecretSHA256 fingerprint is non-empty and +// DIFFERENT from the actual secret value for every returned JWTSecretInfo. +func TestListJWTSecretsInfo_SecretSHA256NonEmptyAndDifferentFromSecret(t *testing.T) { + // Create a mock repository (nil operations are fine for this test) + var nilRepo UserRepository + jwtConfig := JWTConfig{ + Secret: "test-secret-value-12345", + ExpirationTime: 1 * time.Hour, + Issuer: "test-issuer", + } + svc := NewUserService(nilRepo, jwtConfig, "admin-password") + + // Call ListJWTSecretsInfo to get metadata + infos := svc.ListJWTSecretsInfo() + + // Must have at least one entry (the initial secret from jwtConfig) + assert.GreaterOrEqual(t, len(infos), 1, "ListJWTSecretsInfo should return at least one secret") + + // Known secret for verification + knownSecret := "test-secret-value-12345" + + // Verify each JWTSecretInfo has valid SecretSHA256 + for _, info := range infos { + // 1. SecretSHA256 must be non-empty + assert.NotEmpty(t, info.SecretSHA256, "SecretSHA256 must be non-empty") + + // 2. SecretSHA256 must be different from the actual secret value + // Note: We verify against the known secret value used in the service. + // The service's ListJWTSecretsInfo computes SHA-256 of the secret, + // takes first 8 bytes, and hex-encodes them. This will NEVER equal + // the original secret string. + assert.NotEqual(t, knownSecret, info.SecretSHA256, "SecretSHA256 must differ from secret value") + + // 3. SecretSHA256 must be exactly 16 hex characters (8 bytes = 16 hex chars) + assert.Len(t, info.SecretSHA256, 16, "SecretSHA256 must be 16 hex characters") + + // 4. SecretSHA256 must be valid hex (lowercase) + for _, c := range info.SecretSHA256 { + assert.True(t, (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f'), + "SecretSHA256 must be valid lowercase hex: %q", c) + } + } +} -- 2.49.1