Documentation
¶
Overview ¶
Package auth provides authentication and authorization services.
Package auth provides authentication and authorization services.
Index ¶
- Constants
- Variables
- func GenerateQRCode(url string, size int) (string, error)
- func GetPresetScopes(preset string) []string
- func HasAllScopes(granted []string, required ...string) bool
- func HasAnyScope(granted []string, required ...string) bool
- func HasScope(granted []string, required string) bool
- func ListAllScopes() []string
- func ListPresets() []string
- func ValidateScopes(scopes []string) error
- type APIKeyValidator
- type Claims
- type Config
- type EmailSender
- type LockoutConfig
- type LoginAttemptTracker
- type MFAConfig
- type MFAService
- func (s *MFAService) Disable(ctx context.Context, userID, code string) error
- func (s *MFAService) GenerateSetup(ctx context.Context, userID string) (*MFASetupResponse, error)
- func (s *MFAService) GetStatus(ctx context.Context, userID string) (enabled bool, backupCodesRemaining int, err error)
- func (s *MFAService) RegenerateBackupCodes(ctx context.Context, userID, code string) ([]string, error)
- func (s *MFAService) Verify(ctx context.Context, userID, code string) error
- func (s *MFAService) VerifyAndEnable(ctx context.Context, userID, code string) error
- func (s *MFAService) VerifyBackupCode(ctx context.Context, userID, code string) error
- type MFASetupResponse
- type MemoryLoginAttemptTracker
- func (t *MemoryLoginAttemptTracker) ClearAttempts(ctx context.Context, email string) error
- func (t *MemoryLoginAttemptTracker) IsLocked(ctx context.Context, email string) (bool, time.Duration, error)
- func (t *MemoryLoginAttemptTracker) RecordFailedAttempt(ctx context.Context, email string) (int, bool, error)
- type OAuthManager
- func (m *OAuthManager) GetAuthorizationURL(ctx context.Context, providerName, state, redirectURI string) (string, error)
- func (m *OAuthManager) GetLinkedAccounts(ctx context.Context, userID string) ([]repository.OAuthAccount, error)
- func (m *OAuthManager) GetProvider(name string) (*OAuthProvider, error)
- func (m *OAuthManager) GetProvidersInfo() []ProviderInfo
- func (m *OAuthManager) HandleCallback(ctx context.Context, providerName, code, redirectURI string) (*OAuthResult, error)
- func (m *OAuthManager) LinkAccount(ctx context.Context, providerName, userID, code, redirectURI string) (*OAuthResult, error)
- func (m *OAuthManager) ListProviders() []string
- func (m *OAuthManager) UnlinkAccount(ctx context.Context, userID, provider string) error
- type OAuthProvider
- func (p *OAuthProvider) Discover(ctx context.Context) error
- func (p *OAuthProvider) ExchangeCode(ctx context.Context, code, redirectURI string) (*OAuthToken, error)
- func (p *OAuthProvider) GetAuthorizationURL(state, redirectURI string) (string, error)
- func (p *OAuthProvider) GetUserInfo(ctx context.Context, accessToken string) (*OAuthUserInfo, error)
- func (p *OAuthProvider) HandleCallback(ctx context.Context, code, redirectURI string) (*OAuthResult, error)
- func (p *OAuthProvider) LinkAccount(ctx context.Context, userID, code, redirectURI string) (*OAuthResult, error)
- type OAuthResult
- type OAuthToken
- type OAuthUserInfo
- type OIDCDiscovery
- type ProviderInfo
- type RedisLoginAttemptTracker
- func (t *RedisLoginAttemptTracker) ClearAttempts(ctx context.Context, email string) error
- func (t *RedisLoginAttemptTracker) IsLocked(ctx context.Context, email string) (bool, time.Duration, error)
- func (t *RedisLoginAttemptTracker) RecordFailedAttempt(ctx context.Context, email string) (int, bool, error)
- type RegisterInput
- type Service
- func (s *Service) GenerateTokens(ctx context.Context, user *User) (*TokenPair, error)
- func (s *Service) Login(ctx context.Context, email, password string) (*User, error)
- func (s *Service) RefreshTokens(ctx context.Context, refreshToken string) (*TokenPair, *User, error)
- func (s *Service) Register(ctx context.Context, input RegisterInput) (*User, error)
- func (s *Service) ResetPassword(ctx context.Context, token, newPassword string) error
- func (s *Service) SendPasswordResetEmail(ctx context.Context, email string) error
- func (s *Service) SetLockoutTracker(tracker LoginAttemptTracker)
- func (s *Service) ValidateToken(tokenString string) (*Claims, error)
- type TokenPair
- type User
Constants ¶
const ( // Environment scopes ScopeEnvironmentsRead = "environments:read" ScopeEnvironmentsCreate = "environments:create" ScopeEnvironmentsClone = "environments:clone" ScopeEnvironmentsDelete = "environments:delete" // Flag scopes ScopeFlagsRead = "flags:read" ScopeFlagsConfigRead = "flags:config:read" ScopeFlagsConfigUpdate = "flags:config:update" // API key scopes (for creating SDK keys) ScopeAPIKeysRead = "api-keys:read" ScopeAPIKeysCreate = "api-keys:create" ScopeAPIKeysRevoke = "api-keys:revoke" // Override scopes ScopeOverridesRead = "overrides:read" ScopeOverridesCreate = "overrides:create" ScopeOverridesDelete = "overrides:delete" )
Scope constants for privileged API keys.
Variables ¶
var ( ErrInvalidCredentials = errors.New("invalid credentials") ErrUserExists = errors.New("user already exists") ErrInvalidToken = errors.New("invalid token") ErrTokenExpired = errors.New("token expired") ErrUserNotFound = errors.New("user not found") ErrAccountLocked = errors.New("account locked due to too many failed login attempts") )
Common errors
var ( ErrMFAAlreadyEnabled = errors.New("MFA is already enabled") ErrMFANotEnabled = errors.New("MFA is not enabled") ErrMFAInvalidCode = errors.New("invalid MFA code") ErrMFASetupIncomplete = errors.New("MFA setup incomplete") ErrMFABackupCode = errors.New("invalid backup code") )
MFA errors
var ( ErrOAuthDiscoveryFailed = errors.New("failed to discover OIDC configuration") ErrOAuthTokenExchange = errors.New("failed to exchange authorization code for token") ErrOAuthUserInfo = errors.New("failed to get user info from provider") ErrOAuthProviderNotFound = errors.New("OAuth provider not found") ErrOAuthEmailExists = errors.New("an account with this email already exists - please login and link this provider from account settings") ErrOAuthAlreadyLinked = errors.New("this OAuth account is already linked to another user") )
Common OAuth errors.
var ScopePresets = map[string][]string{ "preview-environment": { ScopeEnvironmentsRead, ScopeEnvironmentsCreate, ScopeEnvironmentsClone, ScopeEnvironmentsDelete, ScopeAPIKeysCreate, ScopeAPIKeysRevoke, }, "full-automation": { ScopeEnvironmentsRead, ScopeEnvironmentsCreate, ScopeEnvironmentsClone, ScopeEnvironmentsDelete, ScopeFlagsRead, ScopeFlagsConfigRead, ScopeFlagsConfigUpdate, ScopeAPIKeysRead, ScopeAPIKeysCreate, ScopeAPIKeysRevoke, ScopeOverridesRead, ScopeOverridesCreate, ScopeOverridesDelete, }, "read-only": { ScopeEnvironmentsRead, ScopeFlagsRead, ScopeFlagsConfigRead, ScopeAPIKeysRead, ScopeOverridesRead, }, }
ScopePresets provides convenience scope bundles for common use cases.
var ValidScopes = map[string]bool{ ScopeEnvironmentsRead: true, ScopeEnvironmentsCreate: true, ScopeEnvironmentsClone: true, ScopeEnvironmentsDelete: true, ScopeFlagsRead: true, ScopeFlagsConfigRead: true, ScopeFlagsConfigUpdate: true, ScopeAPIKeysRead: true, ScopeAPIKeysCreate: true, ScopeAPIKeysRevoke: true, ScopeOverridesRead: true, ScopeOverridesCreate: true, ScopeOverridesDelete: true, }
ValidScopes contains all valid scope strings.
Functions ¶
func GenerateQRCode ¶
GenerateQRCode generates a base64-encoded PNG QR code image.
func GetPresetScopes ¶
GetPresetScopes returns the scopes for a preset name, or nil if not found.
func HasAllScopes ¶
HasAllScopes checks if all required scopes are present in the granted scopes.
func HasAnyScope ¶
HasAnyScope checks if any of the required scopes is present in the granted scopes.
func ValidateScopes ¶
ValidateScopes checks that all provided scopes are valid.
Types ¶
type APIKeyValidator ¶
type APIKeyValidator struct {
// contains filtered or unexported fields
}
APIKeyValidator validates API keys for WebSocket connections.
func NewAPIKeyValidator ¶
func NewAPIKeyValidator(apiKeys repository.APIKeyRepository, cache *cache.FlagCache) *APIKeyValidator
NewAPIKeyValidator creates a new APIKeyValidator.
func (*APIKeyValidator) ValidateAPIKey ¶
func (v *APIKeyValidator) ValidateAPIKey(ctx context.Context, apiKey string) (keyID string, allowedEnvs []string, err error)
ValidateAPIKey validates an API key and returns allowed environments.
type Claims ¶
type Claims struct {
UserID string `json:"uid"`
jwt.RegisteredClaims
}
Claims represents JWT claims.
type EmailSender ¶
type EmailSender interface {
SendPasswordReset(ctx context.Context, to, name, resetToken string) error
SendWelcome(ctx context.Context, to, name string) error
}
EmailSender interface for sending emails.
type LockoutConfig ¶
type LockoutConfig struct {
// MaxAttempts is the maximum failed attempts before lockout.
MaxAttempts int
// LockoutDuration is how long the account is locked after MaxAttempts.
LockoutDuration time.Duration
// AttemptWindow is the window during which failed attempts are counted.
AttemptWindow time.Duration
}
LockoutConfig holds configuration for account lockout.
func DefaultLockoutConfig ¶
func DefaultLockoutConfig() LockoutConfig
DefaultLockoutConfig returns sensible defaults for account lockout.
type LoginAttemptTracker ¶
type LoginAttemptTracker interface {
// RecordFailedAttempt records a failed login attempt for an email.
// Returns the number of failed attempts and whether the account is locked.
RecordFailedAttempt(ctx context.Context, email string) (attempts int, locked bool, err error)
// ClearAttempts clears all failed attempts for an email (call on successful login).
ClearAttempts(ctx context.Context, email string) error
// IsLocked checks if an account is currently locked.
IsLocked(ctx context.Context, email string) (bool, time.Duration, error)
}
LoginAttemptTracker tracks failed login attempts for account lockout.
type MFAConfig ¶
type MFAConfig struct {
Issuer string // Application name shown in authenticator apps
BackupCodeLen int // Length of each backup code
BackupCodeNum int // Number of backup codes to generate
ValidationSkew uint // Allow codes this many periods before/after current
}
MFAConfig holds MFA configuration.
func DefaultMFAConfig ¶
func DefaultMFAConfig() MFAConfig
DefaultMFAConfig returns default MFA configuration.
type MFAService ¶
type MFAService struct {
// contains filtered or unexported fields
}
MFAService provides MFA functionality.
func NewMFAService ¶
func NewMFAService(config MFAConfig, users repository.UserRepository) *MFAService
NewMFAService creates a new MFA service.
func (*MFAService) Disable ¶
func (s *MFAService) Disable(ctx context.Context, userID, code string) error
Disable disables MFA for a user after verifying their code.
func (*MFAService) GenerateSetup ¶
func (s *MFAService) GenerateSetup(ctx context.Context, userID string) (*MFASetupResponse, error)
GenerateSetup creates a new MFA secret for a user (doesn't enable MFA yet).
func (*MFAService) GetStatus ¶
func (s *MFAService) GetStatus(ctx context.Context, userID string) (enabled bool, backupCodesRemaining int, err error)
GetStatus returns the MFA status for a user.
func (*MFAService) RegenerateBackupCodes ¶
func (s *MFAService) RegenerateBackupCodes(ctx context.Context, userID, code string) ([]string, error)
RegenerateBackupCodes generates new backup codes for a user.
func (*MFAService) Verify ¶
func (s *MFAService) Verify(ctx context.Context, userID, code string) error
Verify validates a TOTP code for an authenticated user.
func (*MFAService) VerifyAndEnable ¶
func (s *MFAService) VerifyAndEnable(ctx context.Context, userID, code string) error
VerifyAndEnable verifies a TOTP code and enables MFA for the user.
func (*MFAService) VerifyBackupCode ¶
func (s *MFAService) VerifyBackupCode(ctx context.Context, userID, code string) error
VerifyBackupCode validates a backup code and marks it as used.
type MFASetupResponse ¶
type MFASetupResponse struct {
Secret string `json:"secret"` // Base32 encoded secret for manual entry
QRCodeURL string `json:"qrCodeUrl"` // otpauth:// URL for QR code generation
BackupCodes []string `json:"backupCodes"` // One-time backup codes
}
MFASetupResponse contains data needed for MFA setup.
type MemoryLoginAttemptTracker ¶
type MemoryLoginAttemptTracker struct {
// contains filtered or unexported fields
}
MemoryLoginAttemptTracker uses in-memory storage for tracking login attempts. Suitable for development or single-instance deployments.
func NewMemoryLoginAttemptTracker ¶
func NewMemoryLoginAttemptTracker(config LockoutConfig) *MemoryLoginAttemptTracker
NewMemoryLoginAttemptTracker creates an in-memory login attempt tracker.
func (*MemoryLoginAttemptTracker) ClearAttempts ¶
func (t *MemoryLoginAttemptTracker) ClearAttempts(ctx context.Context, email string) error
ClearAttempts clears failed attempts after successful login.
func (*MemoryLoginAttemptTracker) IsLocked ¶
func (t *MemoryLoginAttemptTracker) IsLocked(ctx context.Context, email string) (bool, time.Duration, error)
IsLocked checks if an account is locked.
func (*MemoryLoginAttemptTracker) RecordFailedAttempt ¶
func (t *MemoryLoginAttemptTracker) RecordFailedAttempt(ctx context.Context, email string) (int, bool, error)
RecordFailedAttempt records a failed login attempt.
type OAuthManager ¶
type OAuthManager struct {
// contains filtered or unexported fields
}
OAuthManager manages multiple OAuth providers.
func NewOAuthManager ¶
func NewOAuthManager(configs []config.OIDCProviderConfig, users repository.UserRepository, oauthAccounts repository.OAuthAccountRepository) *OAuthManager
NewOAuthManager creates a new OAuth manager.
func (*OAuthManager) GetAuthorizationURL ¶
func (m *OAuthManager) GetAuthorizationURL(ctx context.Context, providerName, state, redirectURI string) (string, error)
GetAuthorizationURL returns the authorization URL for a provider.
func (*OAuthManager) GetLinkedAccounts ¶
func (m *OAuthManager) GetLinkedAccounts(ctx context.Context, userID string) ([]repository.OAuthAccount, error)
GetLinkedAccounts returns all OAuth accounts linked to a user.
func (*OAuthManager) GetProvider ¶
func (m *OAuthManager) GetProvider(name string) (*OAuthProvider, error)
GetProvider returns the OAuth provider by name.
func (*OAuthManager) GetProvidersInfo ¶
func (m *OAuthManager) GetProvidersInfo() []ProviderInfo
GetProvidersInfo returns public information about all configured providers.
func (*OAuthManager) HandleCallback ¶
func (m *OAuthManager) HandleCallback(ctx context.Context, providerName, code, redirectURI string) (*OAuthResult, error)
HandleCallback processes an OAuth callback for a provider (login flow).
func (*OAuthManager) LinkAccount ¶
func (m *OAuthManager) LinkAccount(ctx context.Context, providerName, userID, code, redirectURI string) (*OAuthResult, error)
LinkAccount links an OAuth provider to an existing user (account settings flow).
func (*OAuthManager) ListProviders ¶
func (m *OAuthManager) ListProviders() []string
ListProviders returns a list of configured provider names.
func (*OAuthManager) UnlinkAccount ¶
func (m *OAuthManager) UnlinkAccount(ctx context.Context, userID, provider string) error
UnlinkAccount removes an OAuth provider link from a user.
type OAuthProvider ¶
type OAuthProvider struct {
// contains filtered or unexported fields
}
OAuthProvider handles OAuth/OIDC authentication flows.
func NewOAuthProvider ¶
func NewOAuthProvider(cfg config.OIDCProviderConfig, users repository.UserRepository, oauthAccounts repository.OAuthAccountRepository) *OAuthProvider
NewOAuthProvider creates a new OAuth provider handler.
func (*OAuthProvider) Discover ¶
func (p *OAuthProvider) Discover(ctx context.Context) error
Discover fetches the OIDC discovery document.
func (*OAuthProvider) ExchangeCode ¶
func (p *OAuthProvider) ExchangeCode(ctx context.Context, code, redirectURI string) (*OAuthToken, error)
ExchangeCode exchanges an authorization code for tokens.
func (*OAuthProvider) GetAuthorizationURL ¶
func (p *OAuthProvider) GetAuthorizationURL(state, redirectURI string) (string, error)
GetAuthorizationURL returns the URL to redirect users to for authentication.
func (*OAuthProvider) GetUserInfo ¶
func (p *OAuthProvider) GetUserInfo(ctx context.Context, accessToken string) (*OAuthUserInfo, error)
GetUserInfo fetches user information from the provider.
func (*OAuthProvider) HandleCallback ¶
func (p *OAuthProvider) HandleCallback(ctx context.Context, code, redirectURI string) (*OAuthResult, error)
HandleCallback processes an OAuth callback and returns the authenticated user. This is for LOGIN only - it will not auto-link to existing accounts with matching emails.
func (*OAuthProvider) LinkAccount ¶
func (p *OAuthProvider) LinkAccount(ctx context.Context, userID, code, redirectURI string) (*OAuthResult, error)
LinkAccount links an OAuth provider to an existing authenticated user. This is called from account settings after user has authenticated.
type OAuthResult ¶
OAuthResult contains the result of a successful OAuth authentication.
type OAuthToken ¶
type OAuthToken struct {
AccessToken string `json:"access_token"`
TokenType string `json:"token_type"`
ExpiresIn int `json:"expires_in"`
RefreshToken string `json:"refresh_token"`
IDToken string `json:"id_token"`
}
OAuthToken represents an OAuth token response.
type OAuthUserInfo ¶
type OAuthUserInfo struct {
Sub string `json:"sub"`
Email string `json:"email"`
EmailVerified bool `json:"email_verified"`
Name string `json:"name"`
Picture string `json:"picture"`
}
OAuthUserInfo represents user information from the provider.
type OIDCDiscovery ¶
type OIDCDiscovery struct {
Issuer string `json:"issuer"`
AuthorizationEndpoint string `json:"authorization_endpoint"`
TokenEndpoint string `json:"token_endpoint"`
UserInfoEndpoint string `json:"userinfo_endpoint"`
JwksURI string `json:"jwks_uri"`
}
OIDCDiscovery holds discovered OIDC endpoints.
type ProviderInfo ¶
type ProviderInfo struct {
Name string `json:"name"`
DisplayName string `json:"displayName"`
IconURL string `json:"iconUrl,omitempty"`
}
ProviderInfo contains public information about an OAuth provider.
type RedisLoginAttemptTracker ¶
type RedisLoginAttemptTracker struct {
// contains filtered or unexported fields
}
RedisLoginAttemptTracker uses Redis for tracking login attempts.
func NewRedisLoginAttemptTracker ¶
func NewRedisLoginAttemptTracker(client *redis.Client, config LockoutConfig) *RedisLoginAttemptTracker
NewRedisLoginAttemptTracker creates a Redis-based login attempt tracker.
func (*RedisLoginAttemptTracker) ClearAttempts ¶
func (t *RedisLoginAttemptTracker) ClearAttempts(ctx context.Context, email string) error
ClearAttempts clears failed attempts after successful login.
func (*RedisLoginAttemptTracker) IsLocked ¶
func (t *RedisLoginAttemptTracker) IsLocked(ctx context.Context, email string) (bool, time.Duration, error)
IsLocked checks if an account is locked.
func (*RedisLoginAttemptTracker) RecordFailedAttempt ¶
func (t *RedisLoginAttemptTracker) RecordFailedAttempt(ctx context.Context, email string) (int, bool, error)
RecordFailedAttempt records a failed login attempt.
type RegisterInput ¶
RegisterInput contains registration data.
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
Service provides authentication functionality.
func NewService ¶
func NewService(config Config, users repository.UserRepository, sessions repository.SessionRepository, resetTokens repository.PasswordResetTokenRepository, email EmailSender) *Service
NewService creates a new auth service.
func (*Service) GenerateTokens ¶
GenerateTokens creates access and refresh tokens.
func (*Service) RefreshTokens ¶
func (s *Service) RefreshTokens(ctx context.Context, refreshToken string) (*TokenPair, *User, error)
RefreshTokens creates new tokens from a refresh token.
func (*Service) ResetPassword ¶
ResetPassword resets a user's password.
func (*Service) SendPasswordResetEmail ¶
SendPasswordResetEmail sends a password reset email.
func (*Service) SetLockoutTracker ¶
func (s *Service) SetLockoutTracker(tracker LoginAttemptTracker)
SetLockoutTracker sets the login attempt tracker for account lockout. If not set, account lockout is disabled.