mirror of
https://github.com/lukaszraczylo/traefikoidc.git
synced 2026-06-05 22:44:17 +00:00
e64fc7f730
* Add redis support for distributed caching * Move towards the self-provided Redis connection pool and RESP protocol implementation. Official redis client library won't work with yaegi. * fixup! Move towards the self-provided Redis connection pool and RESP protocol implementation. Official redis client library won't work with yaegi. * fixup! fixup! Move towards the self-provided Redis connection pool and RESP protocol implementation. Official redis client library won't work with yaegi. * fixup! fixup! fixup! Move towards the self-provided Redis connection pool and RESP protocol implementation. Official redis client library won't work with yaegi. * fixup! fixup! fixup! fixup! Move towards the self-provided Redis connection pool and RESP protocol implementation. Official redis client library won't work with yaegi. * fixup! fixup! fixup! fixup! fixup! Move towards the self-provided Redis connection pool and RESP protocol implementation. Official redis client library won't work with yaegi. * ... and another all nighter. * fixup! ... and another all nighter. * fixup! fixup! ... and another all nighter. * fixup! fixup! fixup! ... and another all nighter. * Resolve issue #85 by adding ability to set custom claims in JWT tokens * Remove redundant validation in auth middleware ( issue #89 ) * Add ability to set cookie prefix for session cookies ( #87 ) * fixup! Add ability to set cookie prefix for session cookies ( #87 ) * Add ability to set cookie max age - issue #91 * Potential fix for code scanning alert no. 10: Size computation for allocation may overflow Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> * fixup! Merge main into 0.8.0-redis: resolve conflicts --------- Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
264 lines
7.6 KiB
Go
264 lines
7.6 KiB
Go
//go:build !yaegi
|
|
|
|
package config
|
|
|
|
import (
|
|
"encoding/json"
|
|
"strings"
|
|
"testing"
|
|
|
|
"gopkg.in/yaml.v3"
|
|
)
|
|
|
|
// TestUnifiedConfigJSONMarshalling tests JSON marshalling with secret redaction
|
|
func TestUnifiedConfigJSONMarshalling(t *testing.T) {
|
|
config := &UnifiedConfig{
|
|
Provider: ProviderConfig{
|
|
IssuerURL: "https://auth.example.com",
|
|
ClientID: "test-client",
|
|
ClientSecret: "super-secret-value",
|
|
},
|
|
Session: SessionConfig{
|
|
Secret: "session-secret",
|
|
EncryptionKey: "32-character-encryption-key-here",
|
|
SigningKey: "signing-key-secret",
|
|
},
|
|
Redis: RedisConfig{
|
|
Password: "redis-password",
|
|
SentinelPassword: "sentinel-password",
|
|
},
|
|
}
|
|
|
|
// Marshal to JSON
|
|
jsonBytes, err := json.Marshal(config)
|
|
if err != nil {
|
|
t.Fatalf("Failed to marshal config to JSON: %v", err)
|
|
}
|
|
|
|
jsonStr := string(jsonBytes)
|
|
|
|
// Verify secrets are redacted
|
|
if !contains(jsonStr, `"clientSecret":"[REDACTED]"`) {
|
|
t.Error("ClientSecret should be redacted in JSON output")
|
|
}
|
|
if !contains(jsonStr, `"secret":"[REDACTED]"`) {
|
|
t.Error("Session.Secret should be redacted in JSON output")
|
|
}
|
|
if !contains(jsonStr, `"encryptionKey":"[REDACTED]"`) {
|
|
t.Error("Session.EncryptionKey should be redacted in JSON output")
|
|
}
|
|
if !contains(jsonStr, `"signingKey":"[REDACTED]"`) {
|
|
t.Error("Session.SigningKey should be redacted in JSON output")
|
|
}
|
|
if !contains(jsonStr, `"password":"[REDACTED]"`) {
|
|
t.Error("Redis.Password should be redacted in JSON output")
|
|
}
|
|
if !contains(jsonStr, `"sentinelPassword":"[REDACTED]"`) {
|
|
t.Error("Redis.SentinelPassword should be redacted in JSON output")
|
|
}
|
|
|
|
// Verify non-secret fields are preserved
|
|
if !contains(jsonStr, `"issuerURL":"https://auth.example.com"`) {
|
|
t.Error("IssuerURL should be preserved in JSON output")
|
|
}
|
|
if !contains(jsonStr, `"clientID":"test-client"`) {
|
|
t.Error("ClientID should be preserved in JSON output")
|
|
}
|
|
}
|
|
|
|
// TestUnifiedConfigYAMLMarshalling tests YAML marshalling with secret redaction
|
|
func TestUnifiedConfigYAMLMarshalling(t *testing.T) {
|
|
config := &UnifiedConfig{
|
|
Provider: ProviderConfig{
|
|
IssuerURL: "https://auth.example.com",
|
|
ClientID: "test-client",
|
|
ClientSecret: "super-secret-value",
|
|
},
|
|
Session: SessionConfig{
|
|
Secret: "session-secret",
|
|
EncryptionKey: "32-character-encryption-key-here",
|
|
SigningKey: "signing-key-secret",
|
|
},
|
|
Redis: RedisConfig{
|
|
Password: "redis-password",
|
|
SentinelPassword: "sentinel-password",
|
|
},
|
|
}
|
|
|
|
// Marshal to YAML
|
|
yamlBytes, err := yaml.Marshal(config)
|
|
if err != nil {
|
|
t.Fatalf("Failed to marshal config to YAML: %v", err)
|
|
}
|
|
|
|
yamlStr := string(yamlBytes)
|
|
|
|
// Verify secrets are redacted
|
|
if !contains(yamlStr, "clientSecret: '[REDACTED]'") {
|
|
t.Error("ClientSecret should be redacted in YAML output")
|
|
}
|
|
if !contains(yamlStr, "secret: '[REDACTED]'") {
|
|
t.Error("Session.Secret should be redacted in YAML output")
|
|
}
|
|
if !contains(yamlStr, "encryptionKey: '[REDACTED]'") {
|
|
t.Error("Session.EncryptionKey should be redacted in YAML output")
|
|
}
|
|
if !contains(yamlStr, "signingKey: '[REDACTED]'") {
|
|
t.Error("Session.SigningKey should be redacted in YAML output")
|
|
}
|
|
if !contains(yamlStr, "password: '[REDACTED]'") {
|
|
t.Error("Redis.Password should be redacted in YAML output")
|
|
}
|
|
if !contains(yamlStr, "sentinelPassword: '[REDACTED]'") {
|
|
t.Error("Redis.SentinelPassword should be redacted in YAML output")
|
|
}
|
|
|
|
// Verify non-secret fields are preserved
|
|
if !contains(yamlStr, "issuerURL: https://auth.example.com") {
|
|
t.Error("IssuerURL should be preserved in YAML output")
|
|
}
|
|
if !contains(yamlStr, "clientID: test-client") {
|
|
t.Error("ClientID should be preserved in YAML output")
|
|
}
|
|
}
|
|
|
|
// TestProviderConfigMarshalling tests individual struct marshalling
|
|
func TestProviderConfigMarshalling(t *testing.T) {
|
|
provider := ProviderConfig{
|
|
IssuerURL: "https://auth.example.com",
|
|
ClientID: "test-client",
|
|
ClientSecret: "super-secret-value",
|
|
}
|
|
|
|
// Test JSON marshalling
|
|
jsonBytes, err := json.Marshal(provider)
|
|
if err != nil {
|
|
t.Fatalf("Failed to marshal ProviderConfig to JSON: %v", err)
|
|
}
|
|
|
|
jsonStr := string(jsonBytes)
|
|
if !contains(jsonStr, `"clientSecret":"[REDACTED]"`) {
|
|
t.Error("ClientSecret should be redacted in JSON output")
|
|
}
|
|
if !contains(jsonStr, `"clientID":"test-client"`) {
|
|
t.Error("ClientID should be preserved in JSON output")
|
|
}
|
|
|
|
// Test YAML marshalling
|
|
yamlBytes, err := yaml.Marshal(provider)
|
|
if err != nil {
|
|
t.Fatalf("Failed to marshal ProviderConfig to YAML: %v", err)
|
|
}
|
|
|
|
yamlStr := string(yamlBytes)
|
|
if !contains(yamlStr, "clientSecret: '[REDACTED]'") {
|
|
t.Error("ClientSecret should be redacted in YAML output")
|
|
}
|
|
if !contains(yamlStr, "clientID: test-client") {
|
|
t.Error("ClientID should be preserved in YAML output")
|
|
}
|
|
}
|
|
|
|
// TestSessionConfigMarshalling tests session config marshalling
|
|
func TestSessionConfigMarshalling(t *testing.T) {
|
|
session := SessionConfig{
|
|
Name: "session-cookie",
|
|
Secret: "session-secret",
|
|
EncryptionKey: "32-character-encryption-key-here",
|
|
SigningKey: "signing-key-secret",
|
|
Domain: "example.com",
|
|
Secure: true,
|
|
}
|
|
|
|
// Test JSON marshalling
|
|
jsonBytes, err := json.Marshal(session)
|
|
if err != nil {
|
|
t.Fatalf("Failed to marshal SessionConfig to JSON: %v", err)
|
|
}
|
|
|
|
jsonStr := string(jsonBytes)
|
|
if !contains(jsonStr, `"secret":"[REDACTED]"`) {
|
|
t.Error("Secret should be redacted in JSON output")
|
|
}
|
|
if !contains(jsonStr, `"encryptionKey":"[REDACTED]"`) {
|
|
t.Error("EncryptionKey should be redacted in JSON output")
|
|
}
|
|
if !contains(jsonStr, `"signingKey":"[REDACTED]"`) {
|
|
t.Error("SigningKey should be redacted in JSON output")
|
|
}
|
|
if !contains(jsonStr, `"name":"session-cookie"`) {
|
|
t.Error("Name should be preserved in JSON output")
|
|
}
|
|
if !contains(jsonStr, `"domain":"example.com"`) {
|
|
t.Error("Domain should be preserved in JSON output")
|
|
}
|
|
}
|
|
|
|
// TestRedisConfigMarshalling tests Redis config marshalling
|
|
func TestRedisConfigMarshalling(t *testing.T) {
|
|
redis := RedisConfig{
|
|
Enabled: true,
|
|
Mode: RedisModeCluster,
|
|
Password: "redis-password",
|
|
SentinelPassword: "sentinel-password",
|
|
Addr: "localhost:6379",
|
|
DB: 1,
|
|
}
|
|
|
|
// Test JSON marshalling
|
|
jsonBytes, err := json.Marshal(redis)
|
|
if err != nil {
|
|
t.Fatalf("Failed to marshal RedisConfig to JSON: %v", err)
|
|
}
|
|
|
|
jsonStr := string(jsonBytes)
|
|
if !contains(jsonStr, `"password":"[REDACTED]"`) {
|
|
t.Error("Password should be redacted in JSON output")
|
|
}
|
|
if !contains(jsonStr, `"sentinelPassword":"[REDACTED]"`) {
|
|
t.Error("SentinelPassword should be redacted in JSON output")
|
|
}
|
|
if !contains(jsonStr, `"addr":"localhost:6379"`) {
|
|
t.Error("Addr should be preserved in JSON output")
|
|
}
|
|
if !contains(jsonStr, `"db":1`) {
|
|
t.Error("DB should be preserved in JSON output")
|
|
}
|
|
}
|
|
|
|
// TestEmptySecretsNotRedacted tests that empty secrets are not shown as redacted
|
|
func TestEmptySecretsNotRedacted(t *testing.T) {
|
|
config := &UnifiedConfig{
|
|
Provider: ProviderConfig{
|
|
IssuerURL: "https://auth.example.com",
|
|
ClientID: "test-client",
|
|
ClientSecret: "", // Empty secret
|
|
},
|
|
Session: SessionConfig{
|
|
Secret: "", // Empty secret
|
|
EncryptionKey: "", // Empty secret
|
|
},
|
|
Redis: RedisConfig{
|
|
Password: "", // Empty secret
|
|
},
|
|
}
|
|
|
|
// Marshal to JSON
|
|
jsonBytes, err := json.Marshal(config)
|
|
if err != nil {
|
|
t.Fatalf("Failed to marshal config to JSON: %v", err)
|
|
}
|
|
|
|
jsonStr := string(jsonBytes)
|
|
|
|
// Verify empty secrets are not shown as redacted
|
|
if contains(jsonStr, "[REDACTED]") {
|
|
t.Error("Empty secrets should not be shown as [REDACTED]")
|
|
}
|
|
}
|
|
|
|
// Helper function to check if string contains substring
|
|
func contains(s, substr string) bool {
|
|
return strings.Contains(s, substr)
|
|
}
|