Files
og/internal/auth/oidc_test.go
T
2026-09-11 06:14:38 +02:00

64 lines
2.4 KiB
Go

package auth
import (
"context"
"crypto"
"crypto/rand"
"crypto/rsa"
"crypto/sha256"
"encoding/base64"
"encoding/json"
"fmt"
"math/big"
"net/http"
"net/http/httptest"
"testing"
"time"
"github.com/example/ollama-fair-gateway/internal/config"
)
func TestOIDCVerifierRS256(t *testing.T) {
key, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
t.Fatal(err)
}
var issuer string
mux := http.NewServeMux()
srv := httptest.NewServer(mux)
defer srv.Close()
issuer = srv.URL
mux.HandleFunc("/.well-known/openid-configuration", func(w http.ResponseWriter, r *http.Request) {
_ = json.NewEncoder(w).Encode(map[string]any{"issuer": issuer, "jwks_uri": issuer + "/jwks"})
})
mux.HandleFunc("/jwks", func(w http.ResponseWriter, r *http.Request) {
e := big.NewInt(int64(key.PublicKey.E)).Bytes()
_ = json.NewEncoder(w).Encode(map[string]any{"keys": []any{map[string]any{"kty": "RSA", "kid": "k1", "alg": "RS256", "n": base64.RawURLEncoding.EncodeToString(key.PublicKey.N.Bytes()), "e": base64.RawURLEncoding.EncodeToString(e)}}})
})
v, err := NewOIDCVerifier(context.Background(), config.OIDCConfig{Enabled: true, Issuer: issuer, Audience: "gateway", TenantClaim: "tenant", ApplicationClaim: "azp", GroupsClaim: "groups", AdminGroups: []string{"admins"}, ClockSkew: config.Duration(time.Second), JWKSRefreshMinInterval: config.Duration(time.Second), AllowedAlgorithms: []string{"RS256"}})
if err != nil {
t.Fatal(err)
}
now := time.Now()
tok := signRS256(t, key, "k1", map[string]any{"iss": issuer, "aud": "gateway", "sub": "alice", "tenant": "team-a", "azp": "web", "groups": []string{"admins"}, "exp": now.Add(time.Minute).Unix(), "nbf": now.Add(-time.Second).Unix()})
id, err := v.Verify(context.Background(), tok)
if err != nil {
t.Fatal(err)
}
if id.Tenant != "team-a" || id.Subject != "alice" || id.Application != "web" || !id.IsAdmin() {
t.Fatalf("unexpected identity: %#v", id)
}
}
func signRS256(t *testing.T, key *rsa.PrivateKey, kid string, claims map[string]any) string {
t.Helper()
h, _ := json.Marshal(map[string]any{"alg": "RS256", "typ": "JWT", "kid": kid})
p, _ := json.Marshal(claims)
a := base64.RawURLEncoding.EncodeToString(h) + "." + base64.RawURLEncoding.EncodeToString(p)
sum := sha256.Sum256([]byte(a))
sig, err := rsa.SignPKCS1v15(rand.Reader, key, crypto.SHA256, sum[:])
if err != nil {
t.Fatal(err)
}
return fmt.Sprintf("%s.%s", a, base64.RawURLEncoding.EncodeToString(sig))
}