Files
patrick 765b3537d6
CI / Web-Barrierefreiheitspruefung (axe, Tastatur, Reflow, Textabstaende) (push) Canceled after 0s
CI / Core-Modul (Build/Vet/Test) (push) Canceled after 0s
CI / DMS Security-Test-Gate (AC5, Merge-Gate) (push) Canceled after 0s
CI / DMS-Modul (Lint/Build/Test/Coverage/Artefakt) (push) Canceled after 0s
CI / DMS-Modul Supply-Chain-Scan (govulncheck) (push) Canceled after 0s
CI / Web (dms-browser) (push) Canceled after 0s
CI / Web (pdf-viewer) (push) Canceled after 0s
CI / Web (shl) (push) Canceled after 0s
Supply-Chain-Scan (Go) / govulncheck (push) Canceled after 0s
QA-15 F-07: gofmt
2026-09-22 01:01:23 +02:00

94 lines
3.4 KiB
Go

package moduleauth
import (
"context"
"testing"
"time"
)
func scoped(k keyPair, extra map[string]any) string {
now := time.Now()
claims := map[string]any{"sub": "u", "tenant": "acme", "iat": now.Unix(), "exp": now.Add(time.Hour).Unix()}
for a, b := range extra {
if b == nil {
delete(claims, a)
continue
}
claims[a] = b
}
return k.token(claims, "EdDSA")
}
func TestScopeStrictRequiresMatchingAudienceAndIssuer(t *testing.T) {
k := newKey(t, "k1")
v := NewVerifier(time.Minute, "acme", staticKeys(k)).Expect("dms", "nexarch-core", true)
ctx := context.Background()
ok := []map[string]any{
{"aud": "dms", "iss": "nexarch-core"},
{"aud": []string{"archive", "dms"}, "iss": "nexarch-core"},
}
for i, c := range ok {
if _, err := v.Verify(ctx, scoped(k, c)); err != nil {
t.Errorf("gueltig[%d] abgewiesen: %v", i, err)
}
}
bad := map[string]map[string]any{
"token fuer anderes modul": {"aud": "archive", "iss": "nexarch-core"},
"liste ohne dms": {"aud": []string{"archive", "mail"}, "iss": "nexarch-core"},
"aud fehlt (streng)": {"iss": "nexarch-core"},
"aud leer": {"aud": "", "iss": "nexarch-core"},
"aud null": {"aud": nil, "iss": "nexarch-core"},
"aud kein string/liste": {"aud": 7, "iss": "nexarch-core"},
"fremder aussteller": {"aud": "dms", "iss": "andere-stelle"},
"aussteller fehlt (streng)": {"aud": "dms"},
"aud gross geschrieben": {"aud": "DMS", "iss": "nexarch-core"},
"aud als praefix, nicht identisch": {"aud": "dms-extra", "iss": "nexarch-core"},
}
for name, c := range bad {
if _, err := v.Verify(ctx, scoped(k, c)); err == nil {
t.Errorf("%s: nicht abgewiesen", name)
}
}
}
func TestScopeTransitionAcceptsMissingAudienceButNeverForeignAudience(t *testing.T) {
k := newKey(t, "k1")
v := NewVerifier(time.Minute, "acme", staticKeys(k)).Expect("dms", "nexarch-core", false)
ctx := context.Background()
if _, err := v.Verify(ctx, scoped(k, nil)); err != nil {
t.Errorf("altes token ohne aud im uebergang abgewiesen: %v", err)
}
if _, err := v.Verify(ctx, scoped(k, map[string]any{"aud": "archive", "iss": "nexarch-core"})); err == nil {
t.Error("fremde aud im uebergang angenommen")
}
if _, err := v.Verify(ctx, scoped(k, map[string]any{"aud": "dms", "iss": "andere-stelle"})); err == nil {
t.Error("fremder aussteller im uebergang angenommen")
}
if _, err := v.Verify(ctx, scoped(k, map[string]any{"aud": "dms", "iss": "nexarch-core"})); err != nil {
t.Errorf("neues token abgewiesen: %v", err)
}
}
func TestScopeWithoutExpectationKeepsLegacyBehaviour(t *testing.T) {
k := newKey(t, "k1")
v := NewVerifier(time.Minute, "acme", staticKeys(k))
if _, err := v.Verify(context.Background(), scoped(k, map[string]any{"aud": "irgendwas"})); err != nil {
t.Errorf("ohne Expect darf aud nicht geprueft werden: %v", err)
}
}
func TestScopeTenantAndSignatureStillChecked(t *testing.T) {
k, other := newKey(t, "k1"), newKey(t, "k1")
v := NewVerifier(time.Minute, "acme", staticKeys(k)).Expect("dms", "nexarch-core", true)
good := map[string]any{"aud": "dms", "iss": "nexarch-core"}
if _, err := v.Verify(context.Background(), scoped(k, map[string]any{"aud": "dms", "iss": "nexarch-core", "tenant": "globex"})); err == nil {
t.Error("fremder mandant angenommen")
}
if _, err := v.Verify(context.Background(), scoped(other, good)); err == nil {
t.Error("fremde signatur angenommen")
}
}