Documentation
¶
Index ¶
- Variables
- func BuildAuthCodeURL(config *oauth2.Config, state, verifier string, ...) string
- func CallbackParams(ctx context.Context) url.Values
- func ContextWithCallbackParams(ctx context.Context, params url.Values) context.Context
- func ContextWithIDTokenNonce(ctx context.Context, nonce string) context.Context
- func DecodeIDTokenClaims(idToken string) (map[string]any, error)
- func FetchUserInfoJSON(ctx context.Context, client *http.Client, ...) (map[string]any, error)
- func IDTokenNonce(ctx context.Context) string
- func New(opts ...ConfigOption) *oauthPlugin
- func VerifyIDTokenClaims(ctx context.Context, issuer, clientID, idToken string) (map[string]any, error)
- func VerifyIDTokenNonce(claims map[string]any, expected string) error
- type API
- type ActiveTokens
- type CallbackError
- type ConfigOption
- func WithAllowLinkingDifferentEmails() ConfigOption
- func WithCookieName(name string) ConfigOption
- func WithCookieTTL(ttl time.Duration) ConfigOption
- func WithDatabaseState() ConfigOption
- func WithDecryptTokens(decryptTokens func(secret []byte, tokens *OAuthTokens) (*OAuthTokens, error)) ConfigOption
- func WithDisableRedirect() ConfigOption
- func WithDisableTokensEncryption() ConfigOption
- func WithEncryptTokens(encryptTokens func(secret []byte, tokens *OAuthTokens) (*OAuthTokens, error)) ConfigOption
- func WithGetUserInfo(...) ConfigOption
- func WithMapProfileToUser(mapProfileToUser func(info *limen.OAuthAccountProfile) map[string]any) ConfigOption
- func WithProviders(providers ...Provider) ConfigOption
- func WithRequireExplicitSignUp() ConfigOption
- func WithSecret(key string) ConfigOption
- type IDTokenNonceProvider
- type IDTokenVerifier
- type OAuthAuthorizeURLData
- type OAuthTokens
- type PKCEEnabledProvider
- type Provider
- type ProviderUserInfo
- type ResponseMode
- type ResponseModeProvider
- type StateStore
- type TokenExchanger
- type TokenRefresher
- type TokenResponse
Constants ¶
This section is empty.
Variables ¶
var ( ErrOAuthStateInvalid = limen.NewLimenError("invalid or expired OAuth state", http.StatusBadRequest, nil) ErrMissingStateCookie = limen.NewLimenError("missing OAuth state cookie; ensure cookies are enabled", http.StatusBadRequest, nil) ErrAccountNotFound = limen.NewLimenError("account not found", http.StatusNotFound, nil) ErrProviderRequired = limen.NewLimenError("provider is required", http.StatusUnprocessableEntity, nil) ErrCannotUnlinkOnlyAccount = limen.NewLimenError("cannot unlink the only account", http.StatusConflict, nil) ErrProviderNotFound = limen.NewLimenError("oauth provider not found", http.StatusNotFound, nil) ErrOAuthProviderMismatch = limen.NewLimenError("oauth provider does not match state", http.StatusBadRequest, nil) ErrPKCEVerifierNotFound = limen.NewLimenError("PKCE verifier not found", http.StatusBadRequest, nil) ErrAccountAlreadyLinkedToAnotherUser = limen.NewLimenError("this provider account is already linked to another user", http.StatusConflict, nil) ErrAccountCannotBeLinkedToDifferentEmail = limen.NewLimenError("user cannot be linked to this provider account because the email does not match", http.StatusConflict, nil) ErrOAuthEmailNotVerified = limen.NewLimenError("provider email is not verified", http.StatusUnauthorized, nil) ErrOAuthLocalEmailNotVerified = limen.NewLimenError("local email must be verified before account linking", http.StatusUnauthorized, nil) ErrNoRefreshToken = limen.NewLimenError("no refresh token available for this account", http.StatusBadRequest, nil) )
Functions ¶
func BuildAuthCodeURL ¶
func BuildAuthCodeURL(config *oauth2.Config, state, verifier string, authOpts ...oauth2.AuthCodeOption) string
BuildAuthCodeURL builds the OAuth2 authorization URL using the provider's config. state and verifier are required for CSRF and PKCE; authOpts add provider-specific params (e.g. AccessTypeOffline).
func CallbackParams ¶
CallbackParams retrieves the callback query parameters stored in ctx, or nil.
func ContextWithCallbackParams ¶
ContextWithCallbackParams returns a child context carrying the raw callback query parameters. Providers can retrieve them via CallbackParams inside GetUserInfo to access IdP-specific extras (e.g. Apple's first-login user payload).
func ContextWithIDTokenNonce ¶
ContextWithIDTokenNonce returns a child context carrying the expected OIDC nonce.
func DecodeIDTokenClaims ¶
DecodeIDTokenClaims decodes the payload segment of a JWT without verification.
NOTE: This does not verify the token, so it is not safe to use for any purpose other than to get the claims from the id_token returned by the provider.
func FetchUserInfoJSON ¶
func FetchUserInfoJSON(ctx context.Context, client *http.Client, providerName, endpointURL, accessToken string, extraHeaders map[string]string) (map[string]any, error)
FetchUserInfoJSON performs a GET request to the given URL with a Bearer token and decodes the JSON response into a map. Shared by REST-based OAuth providers.
func IDTokenNonce ¶
IDTokenNonce retrieves the expected OIDC nonce stored in ctx, or an empty string.
func New ¶
func New(opts ...ConfigOption) *oauthPlugin
func VerifyIDTokenClaims ¶
Types ¶
type API ¶
type API interface {
GetAuthorizationURL(ctx context.Context, providerName string, request *OAuthAuthorizeURLData) (string, string, error)
ExchangeAuthorizationCodeForTokens(ctx context.Context, provider Provider, stateData map[string]any, code string) (*TokenResponse, error)
GetUserInfoWithTokens(ctx context.Context, provider Provider, token *TokenResponse) (*limen.OAuthAccountProfile, error)
HandleOAuthCallback(ctx context.Context, providerName, code, state, cookieNonce string, callbackErr *CallbackError) (*limen.OAuthAccountProfile, map[string]any, error)
AuthenticateWithProvider(ctx context.Context, providerName, code, state, cookieNonce string, callbackErr *CallbackError) (*limen.AuthenticationResult, map[string]any, error)
CreateOrLinkAccount(ctx context.Context, info *limen.OAuthAccountProfile) (*limen.AuthenticationResult, error)
LinkAccountToCurrentUser(ctx context.Context, user *limen.User, info *limen.OAuthAccountProfile) (*limen.AuthenticationResult, error)
ListAccountsForUser(ctx context.Context, userID any) ([]*limen.Account, error)
UnlinkAccount(ctx context.Context, user *limen.User, providerName string) error
GetAccessToken(ctx context.Context, userID any, providerName string) (*ActiveTokens, error)
RefreshAccessToken(ctx context.Context, userID any, providerName string) (*ActiveTokens, error)
}
API is the public interface for the OAuth plugin. Use the Use function to obtain a type-safe reference from a Limen instance.
type ActiveTokens ¶
type ActiveTokens struct {
AccessToken string `json:"access_token"`
RefreshToken string `json:"refresh_token,omitempty"`
IDToken string `json:"id_token,omitempty"`
AccessTokenExpiresAt *time.Time `json:"access_token_expires_at,omitempty"`
Scope string `json:"scope,omitempty"`
}
ActiveTokens holds the decrypted OAuth tokens for a user's provider account.
type CallbackError ¶
type CallbackError struct {
Code string // required – e.g. "access_denied", "invalid_scope"
Description string // optional – human-readable explanation
}
CallbackError represents a structured OAuth error returned by the authorization server in the callback query string (RFC 6749 Section 4.1.2.1).
func (*CallbackError) Error ¶
func (e *CallbackError) Error() string
func (*CallbackError) ToLimenError ¶
func (e *CallbackError) ToLimenError() *limen.LimenError
ToLimenError converts the provider callback error into an LimenError that carries the structured OAuth fields in its Details so the handler layer can forward them in redirects or JSON responses.
type ConfigOption ¶
type ConfigOption func(*config)
func WithAllowLinkingDifferentEmails ¶
func WithAllowLinkingDifferentEmails() ConfigOption
WithAllowLinkingDifferentEmails allows linking user with a different email to the one in the OAuth profile.
Be careful with this option as it can lead to account takeover if not used correctly.
func WithCookieName ¶
func WithCookieName(name string) ConfigOption
WithCookieName sets the name of the cookie used to store the OAuth state.
func WithCookieTTL ¶
func WithCookieTTL(ttl time.Duration) ConfigOption
WithCookieTTL sets the TTL of the cookie used to store the OAuth state.
func WithDatabaseState ¶
func WithDatabaseState() ConfigOption
WithDatabaseState uses the database to store the OAuth state tokens.
func WithDecryptTokens ¶
func WithDecryptTokens(decryptTokens func(secret []byte, tokens *OAuthTokens) (*OAuthTokens, error)) ConfigOption
WithDecryptTokens sets the function to decrypt the OAuth tokens. The secret passed to the function is the same as the secret passed to WithSecret.
func WithDisableRedirect ¶
func WithDisableRedirect() ConfigOption
WithDisableRedirect disables the redirect to the redirect URI after the OAuth callback.
func WithDisableTokensEncryption ¶
func WithDisableTokensEncryption() ConfigOption
WithDisableTokensEncryption disables the encryption of OAuth tokens. When enabled, tokens are not encrypted and are stored in plain text.
func WithEncryptTokens ¶
func WithEncryptTokens(encryptTokens func(secret []byte, tokens *OAuthTokens) (*OAuthTokens, error)) ConfigOption
WithEncryptTokens sets the function to encrypt the OAuth tokens. The secret passed to the function is the same as the secret passed to WithSecret.
func WithGetUserInfo ¶
func WithGetUserInfo(getUserInfo func(ctx context.Context, provider string, token *TokenResponse) (*ProviderUserInfo, error)) ConfigOption
WithGetUserInfo sets the function to get the user info from the provider. The function is called with the provider name and token and should return the user info.
func WithMapProfileToUser ¶
func WithMapProfileToUser(mapProfileToUser func(info *limen.OAuthAccountProfile) map[string]any) ConfigOption
WithMapProfileToUser sets the function to map the OAuth profile to a user additional fields.
func WithProviders ¶
func WithProviders(providers ...Provider) ConfigOption
WithProviders registers one or more OAuth providers (e.g. Google, GitHub).
func WithRequireExplicitSignUp ¶
func WithRequireExplicitSignUp() ConfigOption
WithRequireExplicitSignUp disables new users signing in via OAuth and error if the user is not found.
func WithSecret ¶
func WithSecret(key string) ConfigOption
WithSecret sets the 32-byte secret used for encrypting OAuth tokens at rest and stateless state tokens. The key must be exactly 32 bytes (e.g. 32 ASCII characters). If not set, the plugin uses Config.Secret when available.
type IDTokenNonceProvider ¶
type IDTokenNonceProvider interface {
IDTokenNonceEnabled() bool
}
IDTokenNonceProvider is optional. If a Provider implements it and returns true, the base module sends a nonce authorization parameter and exposes the expected nonce to GetUserInfo for provider-side ID token claim validation.
type IDTokenVerifier ¶
func NewIDTokenVerifier ¶
func NewIDTokenVerifier(issuer, clientID string) IDTokenVerifier
type OAuthAuthorizeURLData ¶
type OAuthTokens ¶
type PKCEEnabledProvider ¶
type PKCEEnabledProvider interface {
PKCEEnabled() bool
}
PKCEEnabledProvider is optional. If a Provider implements it and PKCEEnabled() returns false, the authorization URL is built without code_challenge and the token exchange is performed without code_verifier (for providers like LinkedIn that do not support PKCE).
type Provider ¶
type Provider interface {
// Name returns the provider identifier (e.g., "google", "github").
Name() string
// OAuth2Config returns the OAuth2 client config and optional auth-code options
// (e.g. AccessTypeOffline for Google). The base module uses these for
// BuildAuthCodeURL and ExchangeCode.
OAuth2Config() (*oauth2.Config, []oauth2.AuthCodeOption)
// GetUserInfo fetches the user's profile from the provider using the access token.
GetUserInfo(ctx context.Context, token *TokenResponse) (*ProviderUserInfo, error)
}
Provider is implemented by each OAuth provider plugin (Google, GitHub, etc.). The base module uses OAuth2Config for standard authorization URL and token exchange; GetUserInfo is the only provider-specific call.
type ProviderUserInfo ¶
type ProviderUserInfo struct {
ID string
Email string
EmailVerified bool
Name string
AvatarURL string
Raw map[string]any
}
ProviderUserInfo holds the user profile returned by an OAuth provider.
type ResponseMode ¶
type ResponseMode string
ResponseMode represents the OAuth 2.0 response_mode parameter that controls how the authorization server returns result parameters to the client.
const ( ResponseModeQuery ResponseMode = "query" ResponseModeFormPost ResponseMode = "form_post" )
type ResponseModeProvider ¶
type ResponseModeProvider interface {
ResponseMode() ResponseMode
}
ResponseModeProvider is optional. If a Provider implements it and returns a non-default mode, the base module adds the response_mode parameter to the authorization URL and registers a POST callback route to handle form_post responses from the IdP.
type StateStore ¶
type StateStore interface {
// Generate creates a new state token and a cookie value (nonce for database store,
// encrypted payload for stateless store).
Generate(ctx context.Context, data map[string]any) (stateToken string, cookieValue string, err error)
// Validate verifies the state token and cookie value, ensures the token has not
// expired, and returns the data map that was passed to Generate.
Validate(ctx context.Context, stateToken string, cookieValue string) (map[string]any, error)
}
type TokenExchanger ¶
type TokenExchanger interface {
ExchangeAuthorizationCode(ctx context.Context, code, codeVerifier, redirectURI string) (*TokenResponse, error)
}
TokenExchanger is optional. If a Provider also implements TokenExchanger, the base module uses it for code-for-token exchange instead of ExchangeCode.
type TokenRefresher ¶
type TokenRefresher interface {
RefreshToken(ctx context.Context, refreshToken string) (*TokenResponse, error)
}
TokenRefresher is optional. If a Provider also implements TokenRefresher, the base module uses it to refresh an access token instead of the standard oauth2 refresh flow.
type TokenResponse ¶
type TokenResponse struct {
AccessToken string
RefreshToken string
ExpiresAt time.Time
TokenType string
Scope string
IDToken string
AdditionalData map[string]any
}
TokenResponse holds the OAuth2 token exchange response.
func ExchangeCode ¶
func ExchangeCode(ctx context.Context, config *oauth2.Config, code, codeVerifier string) (*TokenResponse, error)
ExchangeCode exchanges an authorization code for tokens using the provider's config. codeVerifier is required when PKCE was used on the authorization URL.
func RefreshToken ¶
func RefreshToken(ctx context.Context, config *oauth2.Config, refreshToken string) (*TokenResponse, error)
RefreshToken uses the standard oauth2.TokenSource to exchange a refresh token for a new access token via the provider's token endpoint.