package auth import ( "testing" "time" "golang.org/x/crypto/bcrypt" ) func newTestAuth(t *testing.T, ttl time.Duration) *Authenticator { t.Helper() hash, err := bcrypt.GenerateFromPassword([]byte("s3cret"), bcrypt.MinCost) if err != nil { t.Fatalf("hash: %v", err) } return New("admin", hash, []byte("test-secret"), ttl) } func TestLoginAndVerify(t *testing.T) { a := newTestAuth(t, time.Hour) token, err := a.Login("admin", "s3cret") if err != nil { t.Fatalf("login: %v", err) } sub, err := a.Verify(token) if err != nil { t.Fatalf("verify: %v", err) } if sub != "admin" { t.Fatalf("sub = %q, want admin", sub) } } func TestLoginWrongCredentials(t *testing.T) { a := newTestAuth(t, time.Hour) if _, err := a.Login("admin", "nope"); err == nil { t.Fatal("expected error for wrong password") } if _, err := a.Login("other", "s3cret"); err == nil { t.Fatal("expected error for wrong username") } } func TestVerifyRejectsTampered(t *testing.T) { a := newTestAuth(t, time.Hour) token, _ := a.Login("admin", "s3cret") if _, err := a.Verify(token + "x"); err == nil { t.Fatal("expected bad signature error") } if _, err := a.Verify("not.a.token"); err == nil { t.Fatal("expected malformed/decoding error") } } func TestVerifyRejectsExpired(t *testing.T) { a := newTestAuth(t, -time.Minute) token, _ := a.Login("admin", "s3cret") if _, err := a.Verify(token); err == nil { t.Fatal("expected expired token error") } }