client

package
v0.0.62 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 5, 2026 License: Apache-2.0 Imports: 16 Imported by: 0

Documentation

Overview

Package client provides client-side authentication utilities for oneauth. It includes credential storage, automatic token refresh, and HTTP client helpers.

Index

Constants

View Source
const RefreshThreshold = 5 * time.Minute

RefreshThreshold is how long before expiry to proactively refresh

Variables

This section is empty.

Functions

This section is empty.

Types

type ASMetadata added in v0.0.56

type ASMetadata struct {
	// Required
	Issuer        string `json:"issuer"`
	TokenEndpoint string `json:"token_endpoint"`

	// Recommended
	AuthorizationEndpoint string `json:"authorization_endpoint,omitempty"`
	JWKSURI               string `json:"jwks_uri,omitempty"`

	// Optional
	RegistrationEndpoint  string `json:"registration_endpoint,omitempty"`
	IntrospectionEndpoint string `json:"introspection_endpoint,omitempty"`
	RevocationEndpoint    string `json:"revocation_endpoint,omitempty"`
	UserinfoEndpoint      string `json:"userinfo_endpoint,omitempty"`

	// Supported features
	ScopesSupported               []string `json:"scopes_supported,omitempty"`
	ResponseTypesSupported        []string `json:"response_types_supported,omitempty"`
	GrantTypesSupported           []string `json:"grant_types_supported,omitempty"`
	CodeChallengeMethodsSupported []string `json:"code_challenge_methods_supported,omitempty"`
	TokenEndpointAuthMethods      []string `json:"token_endpoint_auth_methods_supported,omitempty"`
}

ASMetadata holds OAuth 2.0 Authorization Server metadata discovered from a well-known endpoint. Fields follow RFC 8414 and OpenID Connect Discovery 1.0.

See: https://www.rfc-editor.org/rfc/rfc8414#section-2

func DiscoverAS added in v0.0.56

func DiscoverAS(issuerURL string, opts ...DiscoveryOption) (*ASMetadata, error)

DiscoverAS fetches OAuth Authorization Server metadata from well-known endpoints.

It tries the following URLs in order (per RFC 8414 + OIDC Discovery):

For issuer "https://auth.example.com" (no path):

  1. https://auth.example.com/.well-known/oauth-authorization-server
  2. https://auth.example.com/.well-known/openid-configuration

For issuer "https://auth.example.com/tenant1" (with path):

  1. https://auth.example.com/.well-known/oauth-authorization-server/tenant1
  2. https://auth.example.com/tenant1/.well-known/openid-configuration

Returns the first successful response. Returns an error if all attempts fail.

See: https://www.rfc-editor.org/rfc/rfc8414#section-3

type AuthClient

type AuthClient struct {
	// contains filtered or unexported fields
}

AuthClient is an HTTP client with automatic token management

func NewAuthClient

func NewAuthClient(serverURL string, store CredentialStore, opts ...ClientOption) *AuthClient

NewAuthClient creates a new authenticated HTTP client for a server

func (*AuthClient) ClientCredentialsToken added in v0.0.56

func (c *AuthClient) ClientCredentialsToken(clientID, clientSecret string, scopes []string) (*ServerCredential, error)

ClientCredentialsToken authenticates using the client_credentials grant (RFC 6749 §4.4). This is for machine-to-machine authentication — no user context, no refresh token. The access token is stored in the credential store for subsequent API calls.

func (*AuthClient) GetCredential

func (c *AuthClient) GetCredential() (*ServerCredential, error)

GetCredential returns the stored credential for this server

func (*AuthClient) GetToken

func (c *AuthClient) GetToken() (string, error)

GetToken returns the current access token, refreshing if needed

func (*AuthClient) HTTPClient

func (c *AuthClient) HTTPClient() *http.Client

HTTPClient returns the underlying HTTP client with auth handling

func (*AuthClient) IsLoggedIn

func (c *AuthClient) IsLoggedIn() bool

IsLoggedIn returns true if there is a valid (non-expired) credential

func (*AuthClient) Login

func (c *AuthClient) Login(username, password, scope string) (*ServerCredential, error)

Login authenticates with username/password and stores the credential

func (*AuthClient) LoginWithBrowser added in v0.0.56

func (c *AuthClient) LoginWithBrowser(cfg BrowserLoginConfig) (*ServerCredential, error)

LoginWithBrowser performs an OAuth 2.0 authorization code flow with PKCE for CLI/headless clients (RFC 8252). It:

  1. Generates PKCE verifier + challenge
  2. Generates a random state parameter for CSRF protection
  3. Starts a temporary loopback HTTP server to catch the redirect
  4. Opens the user's browser to the authorization URL
  5. Waits for the callback with the authorization code
  6. Validates the state parameter
  7. Exchanges the code for tokens using the code_verifier
  8. Stores the credential via the AuthClient's CredentialStore

See: https://www.rfc-editor.org/rfc/rfc8252 (OAuth 2.0 for Native Apps) See: https://www.rfc-editor.org/rfc/rfc7636 (PKCE)

func (*AuthClient) Logout

func (c *AuthClient) Logout() error

Logout removes the credential for this server

func (*AuthClient) ServerURL

func (c *AuthClient) ServerURL() string

ServerURL returns the server URL this client is configured for

type AuthTransport

type AuthTransport struct {
	Base  http.RoundTripper
	Token string
}

AuthTransport wraps an http.RoundTripper to add Authorization headers

func NewAuthTransport

func NewAuthTransport(token string) *AuthTransport

NewAuthTransport creates an AuthTransport with the given token

func NewAuthTransportWithBase

func NewAuthTransportWithBase(base http.RoundTripper, token string) *AuthTransport

NewAuthTransportWithBase creates an AuthTransport with a custom base transport

func (*AuthTransport) RoundTrip

func (t *AuthTransport) RoundTrip(req *http.Request) (*http.Response, error)

RoundTrip implements http.RoundTripper

type BrowserLoginConfig added in v0.0.56

type BrowserLoginConfig struct {
	// AuthorizationEndpoint is the AS authorization URL.
	// If empty, auto-discovered via DiscoverAS(serverURL) using the
	// AuthClient's server URL.
	AuthorizationEndpoint string

	// TokenEndpoint is the AS token URL for code exchange.
	// If empty, uses the AuthClient's configured tokenEndpoint.
	TokenEndpoint string

	// ClientID identifies this client to the authorization server.
	// Required.
	ClientID string

	// Scopes to request (e.g., []string{"openid", "read", "write"}).
	Scopes []string

	// CallbackPort is the port for the loopback redirect server.
	// If 0, a random available port is chosen.
	CallbackPort int

	// Timeout for the entire flow (waiting for user to complete browser login).
	// Defaults to 5 minutes.
	Timeout time.Duration

	// OpenBrowser is called to open the authorization URL in the user's browser.
	// If nil, uses the platform default (open/xdg-open/start).
	// Set to a custom function for testing or headless environments.
	OpenBrowser func(url string) error

	// HTTPClient is used for the token exchange request.
	// If nil, uses http.DefaultClient.
	HTTPClient *http.Client
}

BrowserLoginConfig configures the authorization code + PKCE flow for CLI and headless clients.

type ClientOption

type ClientOption func(*AuthClient)

ClientOption configures an AuthClient

func WithHTTPClient

func WithHTTPClient(client *http.Client) ClientOption

WithHTTPClient sets a custom base HTTP client (for timeouts, TLS config, etc.) The transport from this client will be wrapped with auth handling.

func WithTokenEndpoint

func WithTokenEndpoint(path string) ClientOption

WithTokenEndpoint sets a custom token endpoint path

func WithTransport

func WithTransport(transport http.RoundTripper) ClientOption

WithTransport sets a custom base transport (for connection pooling, proxies, etc.)

type CredentialStore

type CredentialStore interface {
	// GetCredential retrieves a credential for a server URL
	// Returns nil, nil if no credential exists for the server
	GetCredential(serverURL string) (*ServerCredential, error)

	// SetCredential stores a credential for a server URL
	SetCredential(serverURL string, cred *ServerCredential) error

	// RemoveCredential removes a credential for a server URL
	RemoveCredential(serverURL string) error

	// ListServers returns all server URLs with stored credentials
	ListServers() ([]string, error)

	// Save persists any pending changes (for stores that batch writes)
	Save() error
}

CredentialStore defines the interface for storing and retrieving credentials

type DiscoveryOption added in v0.0.56

type DiscoveryOption func(*discoveryConfig)

DiscoveryOption configures the discovery request.

func WithHTTPClientForDiscovery added in v0.0.56

func WithHTTPClientForDiscovery(client *http.Client) DiscoveryOption

WithHTTPClientForDiscovery sets a custom HTTP client for the discovery request. Useful for testing (httptest) and custom TLS configuration.

type OAuth2TokenRequest

type OAuth2TokenRequest struct {
	GrantType    string `json:"grant_type"`
	Username     string `json:"username,omitempty"`
	Password     string `json:"password,omitempty"`
	RefreshToken string `json:"refresh_token,omitempty"`
	Scope        string `json:"scope,omitempty"`
	ClientID     string `json:"client_id,omitempty"`
	ClientSecret string `json:"client_secret,omitempty"`
	Code         string `json:"code,omitempty"`          // For authorization_code grant
	CodeVerifier string `json:"code_verifier,omitempty"` // PKCE verifier for authorization_code grant
	RedirectURI  string `json:"redirect_uri,omitempty"`  // Redirect URI for authorization_code grant
}

OAuth2TokenRequest is the request body for token endpoint

type OAuth2TokenResponse

type OAuth2TokenResponse struct {
	AccessToken  string `json:"access_token"`
	TokenType    string `json:"token_type"`
	ExpiresIn    int64  `json:"expires_in"`
	RefreshToken string `json:"refresh_token,omitempty"`
	Scope        string `json:"scope,omitempty"`
	Error        string `json:"error,omitempty"`
	ErrorDesc    string `json:"error_description,omitempty"`
}

OAuth2TokenResponse is the response from token endpoint

type ServerCredential

type ServerCredential struct {
	AccessToken  string    `json:"access_token"`
	RefreshToken string    `json:"refresh_token,omitempty"`
	TokenType    string    `json:"token_type,omitempty"`
	UserID       string    `json:"user_id,omitempty"`
	UserEmail    string    `json:"user_email,omitempty"`
	Scope        string    `json:"scope,omitempty"`
	ExpiresAt    time.Time `json:"expires_at"`
	CreatedAt    time.Time `json:"created_at"`
}

ServerCredential holds authentication info for a single server

func (*ServerCredential) HasRefreshToken

func (c *ServerCredential) HasRefreshToken() bool

HasRefreshToken returns true if a refresh token is available

func (*ServerCredential) IsExpired

func (c *ServerCredential) IsExpired() bool

IsExpired returns true if the access token has expired

func (*ServerCredential) IsExpiringSoon

func (c *ServerCredential) IsExpiringSoon(within time.Duration) bool

IsExpiringSoon returns true if the token expires within the given duration

Directories

Path Synopsis
stores
fs
Package fs provides a file system-based credential store for oneauth client.
Package fs provides a file system-based credential store for oneauth client.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL