@@ -31,6 +31,134 @@ func TestReadYMLSettingsRejectsUnknownField(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadYMLSettingsAppliesAuthDefaults(t *testing.T) {
|
||||
tmpDir := t.TempDir()
|
||||
settingsPath := filepath.Join(tmpDir, "vctp.yml")
|
||||
content := `settings:
|
||||
log_level: "info"
|
||||
`
|
||||
if err := os.WriteFile(settingsPath, []byte(content), 0o600); err != nil {
|
||||
t.Fatalf("failed to write settings file: %v", err)
|
||||
}
|
||||
|
||||
logger := slog.New(slog.NewTextHandler(io.Discard, nil))
|
||||
s := New(logger, settingsPath)
|
||||
if err := s.ReadYMLSettings(); err != nil {
|
||||
t.Fatalf("expected settings to load, got error: %v", err)
|
||||
}
|
||||
|
||||
got := s.Values.Settings
|
||||
if got.AuthMode != authModeDisabled {
|
||||
t.Fatalf("expected default auth_mode=%q, got %q", authModeDisabled, got.AuthMode)
|
||||
}
|
||||
if got.AuthTokenLifespanMinutes != defaultAuthTokenLifespanMinutes {
|
||||
t.Fatalf("expected default auth_token_lifespan_minutes=%d, got %d", defaultAuthTokenLifespanMinutes, got.AuthTokenLifespanMinutes)
|
||||
}
|
||||
if got.AuthJWTIssuer != defaultAuthJWTIssuer {
|
||||
t.Fatalf("expected default auth_jwt_issuer=%q, got %q", defaultAuthJWTIssuer, got.AuthJWTIssuer)
|
||||
}
|
||||
if got.AuthJWTAudience != defaultAuthJWTAudience {
|
||||
t.Fatalf("expected default auth_jwt_audience=%q, got %q", defaultAuthJWTAudience, got.AuthJWTAudience)
|
||||
}
|
||||
if got.AuthClockSkewSeconds != defaultAuthClockSkewSeconds {
|
||||
t.Fatalf("expected default auth_clock_skew_seconds=%d, got %d", defaultAuthClockSkewSeconds, got.AuthClockSkewSeconds)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadYMLSettingsRejectsInvalidAuthMode(t *testing.T) {
|
||||
tmpDir := t.TempDir()
|
||||
settingsPath := filepath.Join(tmpDir, "vctp.yml")
|
||||
content := `settings:
|
||||
auth_mode: "sometimes"
|
||||
`
|
||||
if err := os.WriteFile(settingsPath, []byte(content), 0o600); err != nil {
|
||||
t.Fatalf("failed to write settings file: %v", err)
|
||||
}
|
||||
|
||||
logger := slog.New(slog.NewTextHandler(io.Discard, nil))
|
||||
s := New(logger, settingsPath)
|
||||
err := s.ReadYMLSettings()
|
||||
if err == nil {
|
||||
t.Fatal("expected invalid auth_mode to fail")
|
||||
}
|
||||
if !strings.Contains(strings.ToLower(err.Error()), "auth_mode") {
|
||||
t.Fatalf("expected error to mention auth_mode, got: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadYMLSettingsRejectsAuthEnabledWithoutSigningKey(t *testing.T) {
|
||||
tmpDir := t.TempDir()
|
||||
settingsPath := filepath.Join(tmpDir, "vctp.yml")
|
||||
content := `settings:
|
||||
auth_enabled: true
|
||||
auth_mode: "required"
|
||||
ldap_bind_address: "ldaps://ldap.example.com:636"
|
||||
ldap_base_dn: "dc=example,dc=com"
|
||||
auth_group_role_mappings:
|
||||
"cn=vctp-admin,ou=groups,dc=example,dc=com": "admin"
|
||||
`
|
||||
if err := os.WriteFile(settingsPath, []byte(content), 0o600); err != nil {
|
||||
t.Fatalf("failed to write settings file: %v", err)
|
||||
}
|
||||
|
||||
logger := slog.New(slog.NewTextHandler(io.Discard, nil))
|
||||
s := New(logger, settingsPath)
|
||||
err := s.ReadYMLSettings()
|
||||
if err == nil {
|
||||
t.Fatal("expected auth_enabled=true without signing key to fail")
|
||||
}
|
||||
if !strings.Contains(strings.ToLower(err.Error()), "auth_jwt_signing_key") {
|
||||
t.Fatalf("expected error to mention auth_jwt_signing_key, got: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadYMLSettingsAcceptsValidAuthConfigAndNormalizesMappings(t *testing.T) {
|
||||
tmpDir := t.TempDir()
|
||||
settingsPath := filepath.Join(tmpDir, "vctp.yml")
|
||||
content := `settings:
|
||||
auth_enabled: true
|
||||
auth_mode: "REQUIRED"
|
||||
auth_jwt_signing_key: "c2VjcmV0"
|
||||
auth_token_lifespan_minutes: 90
|
||||
auth_jwt_issuer: " custom-issuer "
|
||||
auth_jwt_audience: " custom-audience "
|
||||
auth_clock_skew_seconds: 15
|
||||
ldap_bind_address: "ldaps://ldap.example.com:636"
|
||||
ldap_base_dn: "dc=example,dc=com"
|
||||
ldap_groups:
|
||||
- " cn=vctp-viewers,ou=groups,dc=example,dc=com "
|
||||
auth_group_role_mappings:
|
||||
" cn=vctp-admins,ou=groups,dc=example,dc=com ": " ADMIN "
|
||||
"cn=vctp-viewers,ou=groups,dc=example,dc=com": "viewer"
|
||||
`
|
||||
if err := os.WriteFile(settingsPath, []byte(content), 0o600); err != nil {
|
||||
t.Fatalf("failed to write settings file: %v", err)
|
||||
}
|
||||
|
||||
logger := slog.New(slog.NewTextHandler(io.Discard, nil))
|
||||
s := New(logger, settingsPath)
|
||||
if err := s.ReadYMLSettings(); err != nil {
|
||||
t.Fatalf("expected valid auth config, got error: %v", err)
|
||||
}
|
||||
|
||||
got := s.Values.Settings
|
||||
if got.AuthMode != authModeRequired {
|
||||
t.Fatalf("expected normalized auth_mode=%q, got %q", authModeRequired, got.AuthMode)
|
||||
}
|
||||
if got.AuthJWTIssuer != "custom-issuer" {
|
||||
t.Fatalf("expected trimmed auth_jwt_issuer, got %q", got.AuthJWTIssuer)
|
||||
}
|
||||
if got.AuthJWTAudience != "custom-audience" {
|
||||
t.Fatalf("expected trimmed auth_jwt_audience, got %q", got.AuthJWTAudience)
|
||||
}
|
||||
if len(got.LDAPGroups) != 1 || got.LDAPGroups[0] != "cn=vctp-viewers,ou=groups,dc=example,dc=com" {
|
||||
t.Fatalf("expected ldap_groups to be compacted+trimmed, got %#v", got.LDAPGroups)
|
||||
}
|
||||
if got.AuthGroupRoleMappings["cn=vctp-admins,ou=groups,dc=example,dc=com"] != authRoleAdmin {
|
||||
t.Fatalf("expected admin mapping to normalize role to %q, got %#v", authRoleAdmin, got.AuthGroupRoleMappings)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSecureSettingsFileMode(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
|
||||
Reference in New Issue
Block a user