Documentation
¶
Index ¶
- Constants
- func GetM2MTokenFromEnv() string
- func IsM2MConfigured() bool
- type AuthStatus
- type BrowserOpener
- type CredentialStore
- type Credentials
- type DeviceAuthResponse
- type HTTPClient
- type JWTClaims
- type KeyringStore
- func (s *KeyringStore) Delete() error
- func (s *KeyringStore) Exists() bool
- func (s *KeyringStore) GetActorType() (string, error)
- func (s *KeyringStore) GetM2MConfig() (*M2MConfig, error)
- func (s *KeyringStore) Load() (*Credentials, error)
- func (s *KeyringStore) Save(creds *Credentials) error
- func (s *KeyringStore) SetActorType(actorType string) error
- func (s *KeyringStore) StoreM2MConfig(config *M2MConfig) error
- func (s *KeyringStore) StoreToken(token string, expiresIn int) error
- type LoginConfig
- type M2MConfig
- type M2MManager
- type M2MTokenResponse
- type Manager
- func (m *Manager) CompleteDeviceFlow(ctx context.Context, deviceAuth *DeviceAuthResponse) (*Credentials, error)
- func (m *Manager) ConfigureM2M(config *M2MConfig) error
- func (m *Manager) GetActorType(ctx context.Context) (string, error)
- func (m *Manager) GetOrRefreshToken(ctx context.Context) (string, error)
- func (m *Manager) GetToken(ctx context.Context) (string, error)
- func (m *Manager) Login(ctx context.Context) (*Credentials, error)
- func (m *Manager) LoginMachine(ctx context.Context) error
- func (m *Manager) LoginMachineWithToken(ctx context.Context, token string) error
- func (m *Manager) Logout() error
- func (m *Manager) Refresh(ctx context.Context, creds *Credentials) (*Credentials, error)
- func (m *Manager) SaveUserInfoFromToken(token *TokenResponse) error
- func (m *Manager) StartDeviceFlow(ctx context.Context) (*DeviceAuthResponse, error)
- func (m *Manager) Status() *AuthStatus
- type MockBrowserOpener
- type MockBuilder
- func (b *MockBuilder) Build() (*Manager, *MockOAuthProvider, *MockStore)
- func (b *MockBuilder) WithDeviceFlow(resp *DeviceAuthResponse, err error) *MockBuilder
- func (b *MockBuilder) WithRefreshToken(resp *TokenResponse, err error) *MockBuilder
- func (b *MockBuilder) WithStoreError(err error) *MockBuilder
- func (b *MockBuilder) WithStoredCredentials(creds *Credentials) *MockBuilder
- func (b *MockBuilder) WithTokenPolling(responses []interface{}) *MockBuilder
- type MockHTTPClient
- type MockOAuthProvider
- func (m *MockOAuthProvider) PollForToken(ctx context.Context, deviceCode string, interval time.Duration) (*TokenResponse, error)
- func (m *MockOAuthProvider) RefreshToken(ctx context.Context, refreshToken string) (*TokenResponse, error)
- func (m *MockOAuthProvider) Reset()
- func (m *MockOAuthProvider) StartDeviceFlow(ctx context.Context) (*DeviceAuthResponse, error)
- type MockStore
- func (m *MockStore) Delete() error
- func (m *MockStore) Exists() bool
- func (m *MockStore) GetActorType() (string, error)
- func (m *MockStore) GetM2MConfig() (*M2MConfig, error)
- func (m *MockStore) Load() (*Credentials, error)
- func (m *MockStore) Save(creds *Credentials) error
- func (m *MockStore) SetActorType(actorType string) error
- func (m *MockStore) StoreM2MConfig(config *M2MConfig) error
- func (m *MockStore) StoreToken(token string, expiresIn int) error
- type OAuthClient
- func (c *OAuthClient) PollForToken(ctx context.Context, deviceCode string, interval time.Duration) (*TokenResponse, error)
- func (c *OAuthClient) RefreshToken(ctx context.Context, refreshToken string) (*TokenResponse, error)
- func (c *OAuthClient) StartDeviceFlow(ctx context.Context) (*DeviceAuthResponse, error)
- type OAuthProvider
- type TestHelpers
- func (h *TestHelpers) AccessDeniedError() *TokenError
- func (h *TestHelpers) AuthorizationPendingError() *TokenError
- func (h *TestHelpers) DeviceAuthResponse() *DeviceAuthResponse
- func (h *TestHelpers) ExpiredCredentials() *Credentials
- func (h *TestHelpers) ExpiredTokenError() *TokenError
- func (h *TestHelpers) SlowDownError() *TokenError
- func (h *TestHelpers) TokenResponse() *TokenResponse
- func (h *TestHelpers) ValidCredentials() *Credentials
- type TokenError
- type TokenResponse
Constants ¶
const ( // Default OAuth client ID for FTL authentication DefaultClientID = "client_01K2ADMPRAFT9X83PFVJBQ6T49" // Default AuthKit domain for authentication DefaultAuthKitDomain = "divine-lion-50-staging.authkit.app" // Maximum time to wait for login completion LoginTimeout = 30 * time.Minute // Keyring service name KeyringService = "ftl" // Keyring username KeyringUsername = "default" )
Constants for OAuth configuration
Variables ¶
This section is empty.
Functions ¶
func GetM2MTokenFromEnv ¶
func GetM2MTokenFromEnv() string
GetM2MTokenFromEnv gets a pre-generated M2M token from environment
func IsM2MConfigured ¶
func IsM2MConfigured() bool
IsM2MConfigured checks if M2M credentials are available
Types ¶
type AuthStatus ¶
type AuthStatus struct {
LoggedIn bool
Credentials *Credentials
Error error
NeedsRefresh bool
}
AuthStatus represents the current authentication status
type BrowserOpener ¶
BrowserOpener defines the interface for opening URLs in a browser
type CredentialStore ¶
type CredentialStore interface {
// Load retrieves stored credentials
Load() (*Credentials, error)
// Save stores credentials securely
Save(creds *Credentials) error
// Delete removes stored credentials
Delete() error
// Exists checks if credentials are stored
Exists() bool
// M2M-specific methods
StoreToken(token string, expiresIn int) error
GetM2MConfig() (*M2MConfig, error)
StoreM2MConfig(config *M2MConfig) error
SetActorType(actorType string) error
GetActorType() (string, error)
}
CredentialStore provides secure storage for authentication credentials
type Credentials ¶
type Credentials struct {
// AuthKit domain used for authentication
AuthKitDomain string `json:"authkit_domain"`
// OAuth access token
AccessToken string `json:"access_token"`
// OAuth refresh token for renewing access
RefreshToken string `json:"refresh_token,omitempty"`
// Token expiration time
ExpiresAt *time.Time `json:"expires_at,omitempty"`
// Client ID used for authentication
ClientID string `json:"client_id,omitempty"`
}
Credentials represents stored authentication credentials
func (*Credentials) IsExpired ¶
func (c *Credentials) IsExpired() bool
IsExpired checks if the access token has expired
func (*Credentials) TimeUntilExpiry ¶
func (c *Credentials) TimeUntilExpiry() time.Duration
TimeUntilExpiry returns the duration until token expiry
type DeviceAuthResponse ¶
type DeviceAuthResponse struct {
DeviceCode string `json:"device_code"`
UserCode string `json:"user_code"`
VerificationURI string `json:"verification_uri"`
VerificationURIComplete string `json:"verification_uri_complete"`
ExpiresIn int `json:"expires_in"`
Interval int `json:"interval,omitempty"`
}
DeviceAuthResponse represents the response from device authorization endpoint
type HTTPClient ¶
HTTPClient defines the interface for HTTP operations
type JWTClaims ¶
type JWTClaims struct {
// Standard claims
Subject string `json:"sub"`
Email string `json:"email"`
Name string `json:"name"`
ExpiresAt int64 `json:"exp"`
IssuedAt int64 `json:"iat"`
// WorkOS-specific claims
OrganizationID string `json:"org_id"`
Organizations []string `json:"org_ids"`
ActorType string `json:"actor_type"`
UserID string `json:"user_id"`
// Additional user info
EmailVerified bool `json:"email_verified"`
Username string `json:"username"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
}
JWTClaims represents the claims we extract from the JWT
func ExtractIDToken ¶
func ExtractIDToken(tokenResp *TokenResponse) (*JWTClaims, error)
ExtractIDToken extracts user info from an ID token if present
func ExtractUserInfo ¶
ExtractUserInfo extracts user information from a JWT token without verification This is safe because the token has already been verified by the backend
func (*JWTClaims) GetDisplayName ¶
GetDisplayName returns the best available display name for the user
type KeyringStore ¶
type KeyringStore struct{}
KeyringStore implements CredentialStore using OS keyring
func NewKeyringStore ¶
func NewKeyringStore() (*KeyringStore, error)
NewKeyringStore creates a new keyring-based credential store
func (*KeyringStore) Delete ¶
func (s *KeyringStore) Delete() error
Delete removes stored credentials from the keyring
func (*KeyringStore) Exists ¶
func (s *KeyringStore) Exists() bool
Exists checks if credentials are stored
func (*KeyringStore) GetActorType ¶
func (s *KeyringStore) GetActorType() (string, error)
GetActorType retrieves the stored actor type
func (*KeyringStore) GetM2MConfig ¶
func (s *KeyringStore) GetM2MConfig() (*M2MConfig, error)
GetM2MConfig retrieves stored M2M configuration
func (*KeyringStore) Load ¶
func (s *KeyringStore) Load() (*Credentials, error)
Load retrieves stored credentials from the keyring
func (*KeyringStore) Save ¶
func (s *KeyringStore) Save(creds *Credentials) error
Save stores credentials in the keyring
func (*KeyringStore) SetActorType ¶
func (s *KeyringStore) SetActorType(actorType string) error
SetActorType stores whether the current actor is a user or machine
func (*KeyringStore) StoreM2MConfig ¶
func (s *KeyringStore) StoreM2MConfig(config *M2MConfig) error
StoreM2MConfig stores M2M configuration
func (*KeyringStore) StoreToken ¶
func (s *KeyringStore) StoreToken(token string, expiresIn int) error
StoreToken stores just an access token (for M2M flows)
type LoginConfig ¶
type LoginConfig struct {
// Don't open browser automatically
NoBrowser bool
// Override AuthKit domain (for testing)
AuthKitDomain string
// Override OAuth client ID (for testing)
ClientID string
// Force re-authentication even if already logged in
Force bool
}
LoginConfig contains configuration for the login process
type M2MConfig ¶
type M2MConfig struct {
ClientID string `json:"client_id"`
ClientSecret string `json:"client_secret"`
Issuer string `json:"issuer,omitempty"`
OrgID string `json:"org_id,omitempty"` // Set after token exchange
}
M2MConfig holds configuration for machine-to-machine authentication
type M2MManager ¶
type M2MManager struct {
// contains filtered or unexported fields
}
M2MManager handles machine-to-machine authentication
func NewM2MManager ¶
func NewM2MManager(store CredentialStore) *M2MManager
NewM2MManager creates a new M2M authentication manager
func (*M2MManager) ExchangeCredentials ¶
func (m *M2MManager) ExchangeCredentials(ctx context.Context, config *M2MConfig) (*TokenResponse, error)
ExchangeCredentials exchanges client credentials for an access token
func (*M2MManager) LoadM2MConfig ¶
func (m *M2MManager) LoadM2MConfig() (*M2MConfig, error)
LoadM2MConfig loads M2M configuration from environment or stored config
type M2MTokenResponse ¶
type M2MTokenResponse struct {
AccessToken string `json:"access_token"`
TokenType string `json:"token_type"`
ExpiresIn int `json:"expires_in"`
}
M2MTokenResponse represents the response from the token endpoint
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager handles authentication operations
func NewManager ¶
func NewManager(store CredentialStore, config *LoginConfig) *Manager
NewManager creates a new authentication manager
func NewManagerWithMocks ¶
func NewManagerWithMocks(store CredentialStore, provider OAuthProvider, browser BrowserOpener, config *LoginConfig) *Manager
NewManagerWithMocks creates a new authentication manager with all dependencies mocked This is specifically for testing to prevent any external interactions
func NewManagerWithProvider ¶
func NewManagerWithProvider(store CredentialStore, provider OAuthProvider, config *LoginConfig) *Manager
NewManagerWithProvider creates a new authentication manager with a custom OAuth provider This is primarily for testing but can be used for custom OAuth implementations
func (*Manager) CompleteDeviceFlow ¶
func (m *Manager) CompleteDeviceFlow(ctx context.Context, deviceAuth *DeviceAuthResponse) (*Credentials, error)
CompleteDeviceFlow completes the device flow authentication
func (*Manager) ConfigureM2M ¶
ConfigureM2M stores M2M credentials for later use
func (*Manager) GetActorType ¶
GetActorType returns whether the current actor is a user or machine
func (*Manager) GetOrRefreshToken ¶
GetOrRefreshToken gets a valid token, refreshing if necessary
func (*Manager) Login ¶
func (m *Manager) Login(ctx context.Context) (*Credentials, error)
Login performs the complete OAuth device flow login
func (*Manager) LoginMachine ¶
LoginMachine performs machine login using client credentials
func (*Manager) LoginMachineWithToken ¶
LoginMachineWithToken logs in using a pre-existing M2M token
func (*Manager) Refresh ¶
func (m *Manager) Refresh(ctx context.Context, creds *Credentials) (*Credentials, error)
Refresh refreshes an expired access token
func (*Manager) SaveUserInfoFromToken ¶
func (m *Manager) SaveUserInfoFromToken(token *TokenResponse) error
SaveUserInfoFromToken extracts and saves user info from a token
func (*Manager) StartDeviceFlow ¶
func (m *Manager) StartDeviceFlow(ctx context.Context) (*DeviceAuthResponse, error)
StartDeviceFlow starts the OAuth device flow and returns device auth info
func (*Manager) Status ¶
func (m *Manager) Status() *AuthStatus
Status returns the current authentication status
type MockBrowserOpener ¶
type MockBrowserOpener struct {
// OpenURL behavior
OpenURLFunc func(url string) error
OpenURLCalls []struct {
URL string
}
// contains filtered or unexported fields
}
MockBrowserOpener is a mock implementation of BrowserOpener for testing
func (*MockBrowserOpener) OpenURL ¶
func (m *MockBrowserOpener) OpenURL(url string) error
OpenURL implements BrowserOpener
func (*MockBrowserOpener) Reset ¶
func (m *MockBrowserOpener) Reset()
Reset clears all recorded calls
type MockBuilder ¶
type MockBuilder struct {
// contains filtered or unexported fields
}
MockBuilder provides a fluent interface for building test scenarios
func (*MockBuilder) Build ¶
func (b *MockBuilder) Build() (*Manager, *MockOAuthProvider, *MockStore)
Build creates a Manager with the configured mocks
func (*MockBuilder) WithDeviceFlow ¶
func (b *MockBuilder) WithDeviceFlow(resp *DeviceAuthResponse, err error) *MockBuilder
WithDeviceFlow configures the device flow response
func (*MockBuilder) WithRefreshToken ¶
func (b *MockBuilder) WithRefreshToken(resp *TokenResponse, err error) *MockBuilder
WithRefreshToken configures the refresh token response
func (*MockBuilder) WithStoreError ¶
func (b *MockBuilder) WithStoreError(err error) *MockBuilder
WithStoreError configures a store error
func (*MockBuilder) WithStoredCredentials ¶
func (b *MockBuilder) WithStoredCredentials(creds *Credentials) *MockBuilder
WithStoredCredentials configures the stored credentials
func (*MockBuilder) WithTokenPolling ¶
func (b *MockBuilder) WithTokenPolling(responses []interface{}) *MockBuilder
WithTokenPolling configures the token polling behavior This simulates the entire polling loop, handling authorization_pending internally
type MockHTTPClient ¶
type MockHTTPClient struct {
// Do behavior
DoFunc func(req *http.Request) (*http.Response, error)
DoCalls []struct {
Req *http.Request
}
// contains filtered or unexported fields
}
MockHTTPClient is a mock implementation of HTTPClient for testing
type MockOAuthProvider ¶
type MockOAuthProvider struct {
// StartDeviceFlow behavior
StartDeviceFlowFunc func(ctx context.Context) (*DeviceAuthResponse, error)
StartDeviceFlowCalls []struct {
Ctx context.Context
}
// PollForToken behavior
PollForTokenFunc func(ctx context.Context, deviceCode string, interval time.Duration) (*TokenResponse, error)
PollForTokenCalls []struct {
Ctx context.Context
DeviceCode string
Interval time.Duration
}
// RefreshToken behavior
RefreshTokenFunc func(ctx context.Context, refreshToken string) (*TokenResponse, error)
RefreshTokenCalls []struct {
Ctx context.Context
RefreshToken string
}
// contains filtered or unexported fields
}
MockOAuthProvider is a mock implementation of OAuthProvider for testing
func (*MockOAuthProvider) PollForToken ¶
func (m *MockOAuthProvider) PollForToken(ctx context.Context, deviceCode string, interval time.Duration) (*TokenResponse, error)
PollForToken implements OAuthProvider
func (*MockOAuthProvider) RefreshToken ¶
func (m *MockOAuthProvider) RefreshToken(ctx context.Context, refreshToken string) (*TokenResponse, error)
RefreshToken implements OAuthProvider
func (*MockOAuthProvider) Reset ¶
func (m *MockOAuthProvider) Reset()
Reset clears all recorded calls
func (*MockOAuthProvider) StartDeviceFlow ¶
func (m *MockOAuthProvider) StartDeviceFlow(ctx context.Context) (*DeviceAuthResponse, error)
StartDeviceFlow implements OAuthProvider
type MockStore ¶
type MockStore struct {
// contains filtered or unexported fields
}
MockStore implements CredentialStore for testing
func NewMockStore ¶
func NewMockStore(creds *Credentials, err error) *MockStore
NewMockStore creates a mock credential store for testing
func (*MockStore) GetActorType ¶
GetActorType retrieves the stored actor type
func (*MockStore) GetM2MConfig ¶
GetM2MConfig retrieves stored M2M configuration
func (*MockStore) Load ¶
func (m *MockStore) Load() (*Credentials, error)
Load returns the mock credentials
func (*MockStore) Save ¶
func (m *MockStore) Save(creds *Credentials) error
Save stores the mock credentials
func (*MockStore) SetActorType ¶
SetActorType stores whether the current actor is a user or machine
func (*MockStore) StoreM2MConfig ¶
StoreM2MConfig stores M2M configuration
type OAuthClient ¶
type OAuthClient struct {
// contains filtered or unexported fields
}
OAuthClient handles OAuth device flow authentication
func NewOAuthClient ¶
func NewOAuthClient(authKitDomain, clientID string) *OAuthClient
NewOAuthClient creates a new OAuth client
func (*OAuthClient) PollForToken ¶
func (c *OAuthClient) PollForToken(ctx context.Context, deviceCode string, interval time.Duration) (*TokenResponse, error)
PollForToken polls the token endpoint until authentication completes
func (*OAuthClient) RefreshToken ¶
func (c *OAuthClient) RefreshToken(ctx context.Context, refreshToken string) (*TokenResponse, error)
RefreshToken refreshes an expired access token
func (*OAuthClient) StartDeviceFlow ¶
func (c *OAuthClient) StartDeviceFlow(ctx context.Context) (*DeviceAuthResponse, error)
StartDeviceFlow initiates the OAuth device flow
type OAuthProvider ¶
type OAuthProvider interface {
// StartDeviceFlow initiates the OAuth device flow
StartDeviceFlow(ctx context.Context) (*DeviceAuthResponse, error)
// PollForToken polls the token endpoint until authentication completes
PollForToken(ctx context.Context, deviceCode string, interval time.Duration) (*TokenResponse, error)
// RefreshToken refreshes an expired access token
RefreshToken(ctx context.Context, refreshToken string) (*TokenResponse, error)
}
OAuthProvider defines the interface for OAuth operations
type TestHelpers ¶
type TestHelpers struct{}
TestHelpers provides utility functions for tests
func (*TestHelpers) AccessDeniedError ¶
func (h *TestHelpers) AccessDeniedError() *TokenError
AccessDeniedError creates an access denied error
func (*TestHelpers) AuthorizationPendingError ¶
func (h *TestHelpers) AuthorizationPendingError() *TokenError
AuthorizationPendingError creates an authorization pending error
func (*TestHelpers) DeviceAuthResponse ¶
func (h *TestHelpers) DeviceAuthResponse() *DeviceAuthResponse
DeviceAuthResponse creates a test device auth response
func (*TestHelpers) ExpiredCredentials ¶
func (h *TestHelpers) ExpiredCredentials() *Credentials
ExpiredCredentials creates expired test credentials
func (*TestHelpers) ExpiredTokenError ¶
func (h *TestHelpers) ExpiredTokenError() *TokenError
ExpiredTokenError creates an expired token error
func (*TestHelpers) SlowDownError ¶
func (h *TestHelpers) SlowDownError() *TokenError
SlowDownError creates a slow down error
func (*TestHelpers) TokenResponse ¶
func (h *TestHelpers) TokenResponse() *TokenResponse
TokenResponse creates a test token response
func (*TestHelpers) ValidCredentials ¶
func (h *TestHelpers) ValidCredentials() *Credentials
ValidCredentials creates valid test credentials
type TokenError ¶
type TokenError struct {
ErrorCode string `json:"error"`
ErrorDescription string `json:"error_description,omitempty"`
}
TokenError represents an error response from token endpoint
func (*TokenError) Error ¶
func (e *TokenError) Error() string
Error implements the error interface for TokenError
func (*TokenError) IsAuthorizationPending ¶
func (e *TokenError) IsAuthorizationPending() bool
IsAuthorizationPending checks if the error indicates pending authorization
func (*TokenError) IsExpired ¶
func (e *TokenError) IsExpired() bool
IsExpired checks if the device code has expired
func (*TokenError) IsSlowDown ¶
func (e *TokenError) IsSlowDown() bool
IsSlowDown checks if we should slow down polling
type TokenResponse ¶
type TokenResponse struct {
AccessToken string `json:"access_token"`
TokenType string `json:"token_type"`
ExpiresIn int `json:"expires_in,omitempty"`
RefreshToken string `json:"refresh_token,omitempty"`
IDToken string `json:"id_token,omitempty"`
}
TokenResponse represents the response from token endpoint