package config import ( "strings" "testing" ) func validCfg(t *testing.T) *Config { t.Helper() cfg, err := Parse(strings.NewReader(minimalYAML)) if err != nil { t.Fatal(err) } return cfg } func TestBaseDNFromDomain(t *testing.T) { cases := map[string]string{ "firma.local": "DC=firma,DC=local", "ad.firma.example": "DC=ad,DC=firma,DC=example", "FIRMA.LOCAL": "DC=FIRMA,DC=LOCAL", } for in, want := range cases { got, err := BaseDNFromDomain(in) if err != nil { t.Errorf("BaseDNFromDomain(%q): %v", in, err) continue } if got != want { t.Errorf("BaseDNFromDomain(%q) = %q, want %q", in, got, want) } } if _, err := BaseDNFromDomain("firmalocal"); err == nil { t.Error("Domain ohne Punkt muss abgelehnt werden") } if _, err := BaseDNFromDomain(""); err == nil { t.Error("leere Domain muss abgelehnt werden") } } func TestEffectiveBaseDNPrefersOverride(t *testing.T) { cfg := validCfg(t) cfg.AD.BaseDN = "OU=Users,DC=firma,DC=local" if got := cfg.EffectiveBaseDN(); got != "OU=Users,DC=firma,DC=local" { t.Errorf("Override muss gewinnen, got %q", got) } cfg.AD.BaseDN = "" if got := cfg.EffectiveBaseDN(); got != "DC=firma,DC=local" { t.Errorf("Ableitung falsch, got %q", got) } } func TestValidateAcceptsMinimalConfig(t *testing.T) { if err := validCfg(t).Validate(); err != nil { t.Fatalf("minimale Config sollte gültig sein: %v", err) } } func TestValidateRejectsIPServers(t *testing.T) { cfg := validCfg(t) cfg.AD.Servers = []string{"10.1.1.10"} err := cfg.Validate() if err == nil || !strings.Contains(err.Error(), "10.1.1.10") { t.Fatalf("IP-Adresse als DC muss abgelehnt werden, got: %v", err) } } func TestValidateRejectsHTTPOPNsense(t *testing.T) { cfg := validCfg(t) cfg.OPNsense.URL = "http://fw01.firma.local" if err := cfg.Validate(); err == nil { t.Fatal("http:// muss abgelehnt werden") } } func TestValidateRejectsPatternAndRegexTogether(t *testing.T) { cfg := validCfg(t) cfg.Matching.CNRegex = "^.*$" if err := cfg.Validate(); err == nil { t.Fatal("cn_pattern und cn_regex gleichzeitig muss abgelehnt werden") } } func TestValidateRejectsBadRegex(t *testing.T) { cfg := validCfg(t) cfg.Matching.CNPattern = "" cfg.Matching.CNRegex = "([unbalanced" if err := cfg.Validate(); err == nil { t.Fatal("unkompilierbare Regex muss abgelehnt werden") } } func TestValidateCollectsMultipleErrors(t *testing.T) { cfg := validCfg(t) cfg.Portal.TLSCert = "" cfg.Portal.TLSKey = "" cfg.AD.VPNGroup = "" err := cfg.Validate() if err == nil { t.Fatal("mehrere Fehler erwartet") } for _, want := range []string{"tls_cert", "tls_key", "vpn_group"} { if !strings.Contains(err.Error(), want) { t.Errorf("Sammelfehler muss %q nennen, got: %v", want, err) } } } func TestValidateRejectsPatternWithoutPlaceholder(t *testing.T) { cfg := validCfg(t) cfg.Matching.CNPattern = "fester-cn" if err := cfg.Validate(); err == nil { t.Fatal("cn_pattern ohne {username} muss abgelehnt werden") } }