package session import ( "sync" "sync/atomic" "testing" "time" ) // TestSigner_TTLNotShared beweist Fix #1: IssueWithRoleTTL darf das geteilte // s.TTL nicht mehr mutieren. Unter `go test -race` schlägt die alte Version // als Data-Race an; zusätzlich prüfen wir, dass parallele normale Logins nie // die kurze TOTP-TTL erben. func TestSigner_TTLNotShared(t *testing.T) { s := NewSigner([]byte("0123456789abcdef0123456789abcdef"), nil, time.Hour) var wg sync.WaitGroup var bad int32 for i := 0; i < 200; i++ { wg.Add(2) go func() { defer wg.Done() _, _, _ = s.IssueWithRoleTTL("a", "totp_pending", 2*time.Minute) }() go func() { defer wg.Done() _, tok, err := s.IssueWithRole("b", "admin") if err != nil { atomic.AddInt32(&bad, 1) return } // Normale Session muss ~1h gelten, nie die 2-Min-TOTP-TTL. if tok.Exp-tok.Iat < int64((30 * time.Minute).Seconds()) { atomic.AddInt32(&bad, 1) } }() } wg.Wait() if bad > 0 { t.Fatalf("%d normale Tokens bekamen eine zu kurze TTL → geteilter Zustand", bad) } // TTL-Override wirkt weiterhin korrekt für den TOTP-Token. _, ptok, _ := s.IssueWithRoleTTL("x", "totp_pending", 2*time.Minute) if d := ptok.Exp - ptok.Iat; d > int64((3 * time.Minute).Seconds()) { t.Fatalf("totp-pending TTL = %ds, want ~120s", d) } }