112 lines
3.4 KiB
Go
112 lines
3.4 KiB
Go
package auth
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
const validJWTForTests = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ0ZXN0LXVzZXItMTIzIn0.signature"
|
|
|
|
func TestDeckAuthenticatorRejectsInvalidToken(t *testing.T) {
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
w.WriteHeader(http.StatusUnauthorized)
|
|
}))
|
|
defer server.Close()
|
|
|
|
a := NewDeckAuthenticator(DeckAPIs{"test": server.URL}, server.Client())
|
|
if _, err := a.Authenticate(context.Background(), "bad-token", "test"); err == nil {
|
|
t.Fatal("expected error for invalid token")
|
|
}
|
|
}
|
|
|
|
func TestDeckAuthenticatorAcceptsValidJWT(t *testing.T) {
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
if r.Header.Get("Authorization") == "" {
|
|
t.Fatal("expected Authorization header")
|
|
}
|
|
w.WriteHeader(http.StatusOK)
|
|
}))
|
|
defer server.Close()
|
|
|
|
a := NewDeckAuthenticator(DeckAPIs{"test": server.URL}, server.Client())
|
|
identity, err := a.Authenticate(context.Background(), validJWTForTests, "test")
|
|
if err != nil {
|
|
t.Fatalf("expected success: %v", err)
|
|
}
|
|
if identity.Sub != "test-user-123" {
|
|
t.Fatalf("unexpected sub: %q", identity.Sub)
|
|
}
|
|
if NamespaceForSub(identity.Sub) != NamespaceForSub("test-user-123") {
|
|
t.Fatalf("unexpected namespace: %q", NamespaceForSub(identity.Sub))
|
|
}
|
|
}
|
|
|
|
func TestDeckAuthenticatorCachesValidToken(t *testing.T) {
|
|
requests := 0
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
requests++
|
|
w.WriteHeader(http.StatusOK)
|
|
}))
|
|
defer server.Close()
|
|
|
|
a := NewDeckAuthenticator(DeckAPIs{"test": server.URL}, server.Client())
|
|
if _, err := a.Authenticate(context.Background(), validJWTForTests, "test"); err != nil {
|
|
t.Fatalf("first auth: %v", err)
|
|
}
|
|
if _, err := a.Authenticate(context.Background(), validJWTForTests, "test"); err != nil {
|
|
t.Fatalf("second auth: %v", err)
|
|
}
|
|
if requests != 1 {
|
|
t.Fatalf("expected 1 upstream request (cache), got %d", requests)
|
|
}
|
|
// проверяем что кэш выставлен
|
|
if v, ok := a.tokenCache.Load("test:" + validJWTForTests); !ok || time.Now().After(v.(time.Time)) {
|
|
t.Fatal("expected token to be cached with future expiry")
|
|
}
|
|
}
|
|
|
|
func TestTestAuthenticatorAcceptsJWT(t *testing.T) {
|
|
a := &TestAuthenticator{}
|
|
identity, err := a.Authenticate(context.Background(), validJWTForTests, "test")
|
|
if err != nil {
|
|
t.Fatalf("expected success: %v", err)
|
|
}
|
|
if identity.Sub != "test-user-123" {
|
|
t.Fatalf("unexpected sub: %q", identity.Sub)
|
|
}
|
|
}
|
|
|
|
func TestTestAuthenticatorAcceptsEmail(t *testing.T) {
|
|
a := &TestAuthenticator{}
|
|
identity, err := a.Authenticate(context.Background(), "user@example.com", "test")
|
|
if err != nil {
|
|
t.Fatalf("expected success: %v", err)
|
|
}
|
|
if identity.Sub != "user@example.com" {
|
|
t.Fatalf("unexpected sub: %q", identity.Sub)
|
|
}
|
|
}
|
|
|
|
func TestTestAuthenticatorRejectsInvalidToken(t *testing.T) {
|
|
a := &TestAuthenticator{}
|
|
if _, err := a.Authenticate(context.Background(), "notajwt", "test"); err == nil {
|
|
t.Fatal("expected error for non-JWT non-email token")
|
|
}
|
|
}
|
|
|
|
func TestNamespaceForSub(t *testing.T) {
|
|
ns := NamespaceForSub("test-user-123")
|
|
if len(ns) == 0 {
|
|
t.Fatal("empty namespace")
|
|
}
|
|
if ns != NamespaceForSub("test-user-123") {
|
|
t.Fatal("namespace not deterministic")
|
|
}
|
|
if NamespaceForSub("a") == NamespaceForSub("b") {
|
|
t.Fatal("different subs should produce different namespaces")
|
|
}
|
|
}
|