Documentation
¶
Overview ¶
Package auth provides the handwritten authentication layer for the Fulla Go client (the generated API surface lives in the sibling package github.com/voidvec/fulla/clients/go/generated).
Token lifecycle is deliberately handwritten, never generated (client-sdk design D5): refresh rotation, lockout and family revocation are too sensitive to template.
Confidential client credentials always travel as HTTP Basic: token_endpoint_auth_method=client_secret_basic; the server rejects the body form for such clients (F-017).
Index ¶
- Constants
- func CreateChallenge(verifier string) string
- func CreateVerifier() (string, error)
- func FetchClientCredentialsToken(ctx context.Context, baseURL, clientID, clientSecret string, scopes []string) (*oauth2.Token, error)
- func NewBasicAuthClient(baseURL, clientID, clientSecret string) (*generated.ClientWithResponses, error)
- func NewM2MClient(ctx context.Context, baseURL, clientID, clientSecret string, scopes []string) (*generated.ClientWithResponses, error)
- func NormalizeBaseURL(baseURL string) string
- func ParseAuthorizationResponse(redirectURL string) (code, state, errCode string, err error)
- type AuthCodeFlow
- type AuthError
- type PkcePair
- type TokenResponse
Constants ¶
const ( TokenURLPath = "/oauth2/token" AuthorizeURLPath = "/oauth2/authorize" )
TokenURLPath and AuthorizeURLPath are the stable request shapes this package depends on (never the generated code's internals).
Variables ¶
This section is empty.
Functions ¶
func CreateChallenge ¶
CreateChallenge derives the S256 code challenge (RFC 7636 section 4.2): BASE64URL(SHA256(ASCII(verifier))) without padding.
func CreateVerifier ¶
CreateVerifier returns a new RFC 7636 section 4.1 code verifier (64 url-safe base64 characters, 384 bits of entropy).
func FetchClientCredentialsToken ¶
func FetchClientCredentialsToken(ctx context.Context, baseURL, clientID, clientSecret string, scopes []string) (*oauth2.Token, error)
FetchClientCredentialsToken performs a one-shot client_credentials token fetch (no caching). Useful for scripts and benchmarks; long-lived callers should prefer NewM2MClient.
func NewBasicAuthClient ¶
func NewBasicAuthClient(baseURL, clientID, clientSecret string) (*generated.ClientWithResponses, error)
NewBasicAuthClient returns a generated client whose every request carries HTTP Basic client credentials -- for endpoints that authenticate the CALLING CLIENT rather than a user bearer token (POST /oauth2/introspect RFC 7662 section 2.1, POST /oauth2/revoke), where credentials must travel via HTTP Basic (F-017; the body form is rejected).
func NewM2MClient ¶
func NewM2MClient(ctx context.Context, baseURL, clientID, clientSecret string, scopes []string) (*generated.ClientWithResponses, error)
NewM2MClient returns a generated client whose every request carries a valid client_credentials Bearer token. Tokens are fetched lazily, cached, refreshed ahead of expiry and across concurrent requests (all handled by golang.org/x/oauth2 clientcredentials -- deliberately not reinvented).
func NormalizeBaseURL ¶
NormalizeBaseURL strips trailing slashes so endpoint concatenation is safe.
func ParseAuthorizationResponse ¶
ParseAuthorizationResponse extracts code/state/error from the redirect_uri the server sent the browser back to. The caller MUST verify state matches before trusting code.
Types ¶
type AuthCodeFlow ¶
type AuthCodeFlow struct {
BaseURL string
ClientID string
ClientSecret string
RedirectURI string
Scopes []string
HTTPClient *http.Client
}
AuthCodeFlow is the helper for the authorization-code grant (RFC 6749 section 4.1 + PKCE RFC 7636). The browser round-trip is NOT automated: build the authorize URL, send the user there, then exchange the code.
A non-empty clientSecret makes the flow CONFIDENTIAL (HTTP Basic on every token request, F-017); an empty one models a PUBLIC client that identifies itself via the client_id form field.
func NewAuthCodeFlow ¶
func NewAuthCodeFlow(baseURL, clientID, clientSecret, redirectURI string, scopes []string) *AuthCodeFlow
NewAuthCodeFlow constructs the flow. httpClient may be nil (http.DefaultClient).
func (*AuthCodeFlow) BuildAuthorizeURL ¶
func (f *AuthCodeFlow) BuildAuthorizeURL(state string, pkce *PkcePair) (string, error)
BuildAuthorizeURL builds the GET /oauth2/authorize URL to send the user's browser to. state is RECOMMENDED (anti-CSRF, RFC 6749 section 10.12) and must be verified on the way back; pkce may be nil.
func (*AuthCodeFlow) ExchangeCode ¶
func (f *AuthCodeFlow) ExchangeCode(ctx context.Context, code, codeVerifier string) (*TokenResponse, error)
ExchangeCode POSTs grant_type=authorization_code. codeVerifier is REQUIRED when the authorize request carried a code_challenge (the server enforces PKCE completion).
func (*AuthCodeFlow) Refresh ¶
func (f *AuthCodeFlow) Refresh(ctx context.Context, refreshToken string) (*TokenResponse, error)
Refresh POSTs grant_type=refresh_token. Fulla rotates refresh tokens on every use (migration V008): always adopt the new RefreshToken from the returned response.
type AuthError ¶
AuthError carries an RFC 6749 section 5.2 token-endpoint rejection.
type PkcePair ¶
PkcePair bundles a generated verifier with its S256 challenge.
func NewPkcePair ¶
NewPkcePair generates a fresh verifier/challenge pair.
type TokenResponse ¶
type TokenResponse struct {
AccessToken string `json:"access_token"`
TokenType string `json:"token_type"`
ExpiresIn int `json:"expires_in"`
RefreshToken string `json:"refresh_token,omitempty"`
Scope string `json:"scope,omitempty"`
IDToken string `json:"id_token,omitempty"`
}
TokenResponse is the token-endpoint success body (RFC 6749 section 5.1). Only the fields the authorization server actually emits are modelled; unknown fields are ignored.