Documentation
¶
Overview ¶
Package testutil provides reusable test infrastructure for oneauth integration tests. It is intended to be imported by downstream projects (mcpkit, relay, etc.) as well as oneauth's own test suites.
Two categories of helpers:
TestAuthServer — an in-process authorization server with RSA keys, JWKS, token endpoint, and AS metadata (RFC 8414).
Shared OAuth helpers — standalone functions that work against any RFC-compliant OAuth server (TestAuthServer, Keycloak, Auth0, etc.).
Note: The client/ package has production-grade equivalents (client.DiscoverAS, client.AuthClient.ClientCredentialsToken) with proper error handling, retries, and credential storage. These testutil helpers are intentionally simpler: they take *testing.T, call t.Fatal on error, and return plain structs for test ergonomics. They also include test-only functions (ParseJWTClaims, GetPasswordToken) that have no production equivalent.
Index ¶
- func FetchJWKS(t *testing.T, jwksURI string) map[string]any
- func ParseJWTClaims(t *testing.T, tokenStr string) map[string]any
- func ParseJWTHeader(t *testing.T, tokenStr string) map[string]any
- type OIDCConfig
- type Option
- type TestAuthServer
- func (s *TestAuthServer) AdminKey() string
- func (s *TestAuthServer) Issuer() string
- func (s *TestAuthServer) JWKSURL() string
- func (s *TestAuthServer) MintToken(userID string, scopes []string) (string, error)
- func (s *TestAuthServer) MintTokenWithClaims(claims jwt.MapClaims) (string, error)
- func (s *TestAuthServer) TokenEndpoint() string
- func (s *TestAuthServer) URL() string
- type TokenResponse
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func FetchJWKS ¶
FetchJWKS fetches the raw JWKS JSON from the given URI and returns it as a map. Calls t.Fatal on any error.
func ParseJWTClaims ¶
ParseJWTClaims decodes the payload (claims) of a JWT without verifying the signature. For test introspection only — never use in production. Calls t.Fatal on any error.
Types ¶
type OIDCConfig ¶
type OIDCConfig struct {
Issuer string `json:"issuer"`
TokenEndpoint string `json:"token_endpoint"`
JWKSURI string `json:"jwks_uri"`
AuthorizationEndpoint string `json:"authorization_endpoint,omitempty"`
IntrospectionEndpoint string `json:"introspection_endpoint,omitempty"`
RegistrationEndpoint string `json:"registration_endpoint,omitempty"`
ScopesSupported []string `json:"scopes_supported,omitempty"`
}
OIDCConfig holds discovered OIDC / OAuth Authorization Server endpoints. See: https://www.rfc-editor.org/rfc/rfc8414#section-2
func DiscoverOIDC ¶
func DiscoverOIDC(t *testing.T, issuerURL string) OIDCConfig
DiscoverOIDC fetches and parses the OpenID Connect / OAuth Authorization Server Metadata document from issuerURL/.well-known/openid-configuration. Calls t.Fatal on any error.
type Option ¶
type Option func(*config)
Option configures a TestAuthServer.
func WithAdminKey ¶
WithAdminKey sets the admin API key required for app registration endpoints. Default: "testutil-admin-key".
func WithAudience ¶
WithAudience sets the JWT audience claim on minted tokens. Default: "" (no audience restriction).
func WithIssuer ¶
WithIssuer sets the JWT issuer claim and the issuer field in AS metadata. Default: "testutil-issuer" (overridden to server URL after start).
func WithScopes ¶
WithScopes sets the scopes_supported field in AS metadata. Default: ["read", "write", "admin"].
type TestAuthServer ¶
type TestAuthServer struct {
// Server is the underlying httptest.Server. Use URL() for the base URL.
Server *httptest.Server
// APIAuth is the configured API authentication handler (RS256).
APIAuth *apiauth.APIAuth
// KeyStore holds the server's RSA key and any registered app keys.
KeyStore keys.KeyStorage
// Registrar manages app registrations and serves the /apps/ endpoints.
Registrar *admin.AppRegistrar
// contains filtered or unexported fields
}
TestAuthServer is an in-process oneauth authorization server for integration tests. It generates an RSA 2048 key pair, serves JWKS, issues tokens via the client_credentials grant, and provides OAuth AS metadata (RFC 8414).
The server is cleaned up automatically via t.Cleanup — callers never need to call Close manually.
Endpoints served:
GET /_ah/health — health check POST /api/token — token endpoint (client_credentials) POST /oauth/introspect — token introspection (RFC 7662) GET /.well-known/jwks.json — JWKS public key (RFC 7517) GET /.well-known/openid-configuration — AS metadata (RFC 8414) POST /apps/register — app registration POST /apps/dcr — dynamic client registration (RFC 7591)
func NewTestAuthServer ¶
func NewTestAuthServer(t *testing.T, opts ...Option) *TestAuthServer
NewTestAuthServer creates and starts an in-process authorization server with an RSA 2048 key pair. The server is automatically shut down via t.Cleanup when the test completes.
The server signs JWTs with RS256 and serves the public key via JWKS. Apps can be registered via /apps/register or /apps/dcr (RFC 7591), and tokens can be obtained via /api/token (client_credentials grant).
func (*TestAuthServer) AdminKey ¶
func (s *TestAuthServer) AdminKey() string
AdminKey returns the admin API key configured for this server.
func (*TestAuthServer) Issuer ¶
func (s *TestAuthServer) Issuer() string
Issuer returns the JWT issuer configured for this server.
func (*TestAuthServer) JWKSURL ¶
func (s *TestAuthServer) JWKSURL() string
JWKSURL returns the JWKS endpoint URL.
func (*TestAuthServer) MintToken ¶
func (s *TestAuthServer) MintToken(userID string, scopes []string) (string, error)
MintToken creates a valid RS256 JWT with standard claims for the given user and scopes. This is a fast path that bypasses the HTTP token endpoint — no network round-trip is involved.
The token includes: sub, iss, aud (if configured), type ("access"), scopes, iat, exp (15 min), jti, and a kid header matching the server's JWKS-published key.
See: https://www.rfc-editor.org/rfc/rfc7519 (JWT)
func (*TestAuthServer) MintTokenWithClaims ¶
func (s *TestAuthServer) MintTokenWithClaims(claims jwt.MapClaims) (string, error)
MintTokenWithClaims creates an RS256 JWT with arbitrary claims. Standard defaults (iss, iat, exp) are set but can be overridden by the provided claims map. This is useful for testing edge cases: wrong issuer, expired tokens, missing claims, etc.
The kid header is always set to match the server's JWKS key.
See: https://www.rfc-editor.org/rfc/rfc7519 (JWT)
func (*TestAuthServer) TokenEndpoint ¶
func (s *TestAuthServer) TokenEndpoint() string
TokenEndpoint returns the token endpoint URL.
func (*TestAuthServer) URL ¶
func (s *TestAuthServer) URL() string
URL returns the base URL of the test auth server (e.g., "http://127.0.0.1:PORT").
type TokenResponse ¶
type TokenResponse struct {
AccessToken string `json:"access_token"`
TokenType string `json:"token_type"`
ExpiresIn int `json:"expires_in"`
Scope string `json:"scope"`
RefreshToken string `json:"refresh_token,omitempty"`
}
TokenResponse holds the token endpoint response fields. See: https://www.rfc-editor.org/rfc/rfc6749#section-5.1
func GetClientCredentialsToken ¶
func GetClientCredentialsToken(t *testing.T, tokenEndpoint, clientID, clientSecret string, scopes ...string) TokenResponse
GetClientCredentialsToken acquires a token using the OAuth 2.0 client_credentials grant. Works against any RFC 6749-compliant token endpoint. Calls t.Fatal on any error.
func GetPasswordToken ¶
func GetPasswordToken(t *testing.T, tokenEndpoint, clientID, clientSecret, username, password string) TokenResponse
GetPasswordToken acquires a token using the OAuth 2.0 resource owner password credentials grant. Works against any RFC 6749-compliant token endpoint. Calls t.Fatal on any error.