Documentation
¶
Overview ¶
Package omniauth is a pure-Go (no cgo) reimplementation of the engine of Ruby's OmniAuth — the Rack middleware and strategy framework that standardises multi-provider authentication — matching the observable behaviour of the `omniauth` gem (OmniAuth 2.x, MRI 4.0.5).
It models the parts of OmniAuth that are interpreter-independent and provider -agnostic: the request/callback routing state-machine over the `/auth/:provider` and `/auth/:provider/callback` paths, the allowed-request-methods gate, the request-phase CSRF (AuthenticityTokenProtection) hook, the shape of the AuthHash (provider/uid/info/credentials/extra), and the failure flow that redirects to `/auth/failure?message=…&strategy=…`. The provider-specific bodies — what a request phase redirects to, what a callback phase resolves the identity to — and the HTTP session are host concerns, supplied through the StrategyPhase seam and the Rack env.
The Rack environment, request and response types come from github.com/go-ruby-rack/rack, so this package composes with the rest of the go-ruby-* Rack stack without a second Rack model. The package is the OmniAuth backend for go-embedded-ruby, but is a standalone, reusable module with no dependency on the Ruby runtime — a sibling of go-ruby-rack and go-ruby-erb.
Index ¶
- Constants
- func AuthenticityTokenProtection(valid func(env any) bool) func(env any) error
- type App
- type AppFunc
- type AuthHash
- func (h *AuthHash) Credentials() *AuthHash
- func (h *AuthHash) Delete(key string) (any, bool)
- func (h *AuthHash) Extra() *AuthHash
- func (h *AuthHash) Get(key string) any
- func (h *AuthHash) GetOK(key string) (any, bool)
- func (h *AuthHash) GetString(key string) string
- func (h *AuthHash) Has(key string) bool
- func (h *AuthHash) Info() *InfoHash
- func (h *AuthHash) Keys() []string
- func (h *AuthHash) Len() int
- func (h *AuthHash) Provider() string
- func (h *AuthHash) Set(key string, val any) *AuthHash
- func (h *AuthHash) SetUID(uid string) *AuthHash
- func (h *AuthHash) UID() string
- func (h *AuthHash) ValidQ() bool
- type AuthenticityError
- type Builder
- type Config
- type Error
- type FailureEndpoint
- type InfoHash
- type NoSessionError
- type Options
- type PhaseResult
- type Response
- type Strategies
- type Strategy
- type StrategyPhase
Constants ¶
const ( // PhaseRequest is the request phase: kick off authentication, typically by // redirecting the browser to the provider. PhaseRequest = "request" // PhaseCallback is the callback phase: the provider has returned, resolve the // authenticated identity into an [AuthHash]. PhaseCallback = "callback" )
Phase names passed to a StrategyPhase.
Variables ¶
This section is empty.
Functions ¶
func AuthenticityTokenProtection ¶
AuthenticityTokenProtection builds a request_validation_phase hook that fails with an AuthenticityError unless valid reports the request's CSRF token good. The token check itself (session vs request param) is the host's, kept out of this pure-Go core; this wires the raise/allow decision faithfully.
Types ¶
type App ¶
App is a Rack application: it receives an env and returns a response, or an error to propagate (a raised exception in Rack terms). Each Strategy is an App that wraps the downstream App.
func PassThroughApp ¶
func PassThroughApp() App
PassThroughApp returns a terminal 404 app, handy as the base of a Build when the middleware stack is meant to fully own the request.
type AuthHash ¶
type AuthHash struct {
// contains filtered or unexported fields
}
AuthHash models OmniAuth::AuthHash: the indifferent-access hash that a strategy's callback phase builds and exposes at env["omniauth.auth"]. Ruby's AuthHash keys symbols and strings the same; here keys are plain strings, so h.Get("uid") and h.Get(:uid) collapse to the one lookup. A canonical auth hash carries the top-level "provider" and "uid" plus the "info", "credentials" and "extra" sub-hashes. Keys iterate in first-insertion order, matching Ruby Hash.
func AuthHashOf ¶
AuthHashOf builds an AuthHash from pairs, applied in order via Set.
func (*AuthHash) Credentials ¶
Credentials returns the "credentials" sub-hash, creating it on first access.
func (*AuthHash) GetString ¶
GetString returns the string value for key, or "" if absent or non-string.
func (*AuthHash) Info ¶
Info returns the "info" sub-hash as an InfoHash, creating it (and adopting a plain sub-hash already stored there) on first access, like AuthHash#info.
type AuthenticityError ¶
type AuthenticityError struct {
Base *Error
}
AuthenticityError is raised by the request-validation (CSRF) hook when the authenticity token is missing or wrong — OmniAuth::AuthenticityError. It maps to the "authenticity_error" failure key.
func NewAuthenticityError ¶
func NewAuthenticityError(msg string) *AuthenticityError
NewAuthenticityError builds an AuthenticityError with the given message.
func (*AuthenticityError) Error ¶
func (e *AuthenticityError) Error() string
Error implements the error interface.
func (*AuthenticityError) MessageKeyValue ¶
func (e *AuthenticityError) MessageKeyValue() string
MessageKeyValue returns the failure message key.
func (*AuthenticityError) Unwrap ¶
func (e *AuthenticityError) Unwrap() error
Unwrap exposes the base error.
type Builder ¶
type Builder struct {
// contains filtered or unexported fields
}
Builder mounts providers as a stack of Strategy middlewares over an app, mirroring OmniAuth::Builder (a Rack::Builder that adds a `provider` DSL).
func NewBuilder ¶
func NewBuilder(config *Config, strategies *Strategies) *Builder
NewBuilder returns a Builder that resolves providers through strategies under config. Both must be non-nil.
func (*Builder) Build ¶
Build wraps app with the mounted providers, outermost first (the first provider mounted sees the request first, as with Rack `use` ordering). It fails if a mounted provider was never registered in the Strategies.
type Config ¶
type Config struct {
// PathPrefix is the mount point for the auth routes (default "/auth"), so the
// request path is "<PathPrefix>/<provider>" and the callback is
// "<PathPrefix>/<provider>/callback".
PathPrefix string
// AllowedRequestMethods lists the upper-case HTTP verbs permitted on the
// request path. Empty means the OmniAuth 2.x default, POST only.
AllowedRequestMethods []string
// RequireSession makes the middleware raise a [NoSessionError] when a request
// arrives without a Rack session (env["rack.session"]). Default true.
RequireSession bool
// TestMode short-circuits the strategies to the mock flow: the request phase
// redirects straight to the callback and the callback phase serves a mocked
// auth hash from MockAuth / MockFailure instead of talking to a provider.
TestMode bool
// MockAuth maps a provider name (or "default") to the auth hash its mocked
// callback yields in TestMode.
MockAuth map[string]*AuthHash
// MockFailure maps a provider name to a failure key; a mocked callback for
// such a provider takes the failure flow in TestMode.
MockFailure map[string]string
// FailureRaiseOut makes the default failure endpoint propagate the error
// instead of redirecting — OmniAuth's raise_out! for dev/test environments.
FailureRaiseOut bool
// RequestValidationPhase is the request-phase CSRF hook
// (OmniAuth's request_validation_phase / AuthenticityTokenProtection). A
// non-nil error it returns takes the failure flow. nil disables the check.
RequestValidationPhase func(env any) error
// BeforeRequestPhase and BeforeCallbackPhase run just before the respective
// phase, mirroring OmniAuth.config.before_request_phase / before_callback_phase.
BeforeRequestPhase func(env any)
BeforeCallbackPhase func(env any)
// OnFailure resolves a failure into a response. fail! sets
// env["omniauth.error"], ["omniauth.error.type"] and ["omniauth.error.strategy"]
// before calling it. Default is the [FailureEndpoint] redirect.
OnFailure func(env rack.Env) (Response, error)
// Logger receives (level, message) log lines; nil discards them.
Logger func(level, message string)
}
Config holds the engine-wide settings, the analogue of OmniAuth.config. The zero value is not usable; build one with DefaultConfig and adjust.
func DefaultConfig ¶
func DefaultConfig() *Config
DefaultConfig returns a Config with OmniAuth 2.x defaults: "/auth" prefix, POST-only request methods, session required, the failure redirect wired up.
type Error ¶
type Error struct {
// MessageKey is the symbolic failure reason (e.g. "invalid_credentials").
MessageKey string
// Msg is the human-readable message.
Msg string
// Err is an optional wrapped cause.
Err error
}
Error is the base OmniAuth error (OmniAuth::Error). It carries the failure message key that the failure flow reflects into `/auth/failure?message=<key>` — the machine-readable reason, distinct from the human message.
func (*Error) MessageKeyValue ¶
MessageKeyValue returns the failure message key. It is promoted to the specific error types below, so the engine can extract a key from any OmniAuth error uniformly.
type FailureEndpoint ¶
type FailureEndpoint struct {
// contains filtered or unexported fields
}
FailureEndpoint is the default on_failure handler — OmniAuth::FailureEndpoint. It reads the failure context that fail! stored in the env and either propagates the error (raise_out!) or redirects the browser to the failure path `<prefix>/failure?message=<key>&strategy=<name>`.
func NewFailureEndpoint ¶
func NewFailureEndpoint(env rack.Env, config *Config) *FailureEndpoint
NewFailureEndpoint wraps env and config for a single failure resolution.
func (*FailureEndpoint) Call ¶
func (f *FailureEndpoint) Call() (Response, error)
Call resolves the failure: it raises out (returns the stored error) when FailureRaiseOut is set, otherwise it redirects to the failure path.
type InfoHash ¶
type InfoHash struct {
*AuthHash
}
InfoHash models OmniAuth::AuthHash::InfoHash — the "info" sub-hash whose #name is derived from the other name-like fields when absent.
type NoSessionError ¶
type NoSessionError struct {
Base *Error
}
NoSessionError is raised when a request reaches the middleware without a Rack session — OmniAuth::NoSessionError. Unlike a strategy failure it is not redirected; it propagates to the host, which must mount a session store ahead of OmniAuth.
func NewNoSessionError ¶
func NewNoSessionError(msg string) *NoSessionError
NewNoSessionError builds a NoSessionError with the given message.
func (*NoSessionError) Error ¶
func (e *NoSessionError) Error() string
Error implements the error interface.
func (*NoSessionError) MessageKeyValue ¶
func (e *NoSessionError) MessageKeyValue() string
MessageKeyValue returns the failure message key.
func (*NoSessionError) Unwrap ¶
func (e *NoSessionError) Unwrap() error
Unwrap exposes the base error.
type Options ¶
type Options struct {
// PathPrefix overrides Config.PathPrefix for this strategy when non-empty.
PathPrefix string
// RequestPath overrides the derived request path when non-empty.
RequestPath string
// CallbackPath overrides the derived callback path when non-empty.
CallbackPath string
// Args carries arbitrary provider options (client id/secret, scope, …).
Args map[string]any
}
Options are per-strategy settings, the analogue of a strategy's options block. A zero Options is fine; unset fields fall back to the engine Config.
type PhaseResult ¶
type PhaseResult struct {
// Response short-circuits the phase with this response.
Response *Response
// Auth is the callback-phase resolved identity.
Auth *AuthHash
// Fail, when non-empty, is the failure message key to fail with.
Fail string
// Err is the error carried into the failure env alongside Fail.
Err error
}
PhaseResult is what a StrategyPhase returns to the engine.
For PhaseRequest, set Response to the provider redirect (or any short-circuit response). For PhaseCallback, set Auth to the resolved identity — the engine stores it at env["omniauth.auth"] and calls through to the app — or set Response to short-circuit. Either phase may instead set Fail (with an optional Err) to take the failure flow.
type Response ¶
Response is a Rack response tuple `[status, headers, body]`, the value a Rack application (and thus each middleware phase) returns. Headers reuses rack.Headers so it composes with the rest of the go-ruby-* Rack stack.
type Strategies ¶
type Strategies struct {
// contains filtered or unexported fields
}
Strategies is the provider registry — the analogue of the OmniAuth::Strategies namespace. A provider registers its StrategyPhase under a name, and a Builder resolves each mounted provider through it. This decouples the set of available providers from the middleware stack.
func (*Strategies) Lookup ¶
func (r *Strategies) Lookup(name string) (StrategyPhase, bool)
Lookup returns the phase handler registered for name.
func (*Strategies) Names ¶
func (r *Strategies) Names() []string
Names returns the registered provider names in registration order.
func (*Strategies) Register ¶
func (r *Strategies) Register(name string, phase StrategyPhase) *Strategies
Register adds (or replaces) the phase handler for a provider name and returns the registry for chaining.
type Strategy ¶
type Strategy struct {
// contains filtered or unexported fields
}
Strategy is one provider's middleware instance: it wraps the downstream App, intercepts that provider's request and callback paths, and passes everything else through. It is OmniAuth::Strategy — the unit `Builder#provider` mounts.
func NewStrategy ¶
func NewStrategy(name string, app App, phase StrategyPhase, config *Config, options *Options) *Strategy
NewStrategy builds a Strategy for provider name that wraps app, running phase for its request/callback bodies under config. options may be nil.
type StrategyPhase ¶
type StrategyPhase func(name, phase string, env any) PhaseResult
StrategyPhase is the provider seam: the engine calls it with the provider name, the phase ("request" or "callback") and the Rack env (typed `any` so the seam is free of this package's Rack choice), and it returns a PhaseResult. This is where provider-specific logic — OAuth redirects, token exchange, identity mapping — lives, outside this pure engine.
