Documentation
¶
Index ¶
- Constants
- Variables
- func FormatUserCode(code string) string
- type AuditLogEntry
- type AuditService
- func (s *AuditService) CleanupOldLogs(retention time.Duration) (int64, error)
- func (s *AuditService) GetAuditLogStats(startTime, endTime time.Time) (store.AuditLogStats, error)
- func (s *AuditService) GetAuditLogs(params store.PaginationParams, filters store.AuditLogFilters) ([]models.AuditLog, store.PaginationResult, error)
- func (s *AuditService) Log(ctx context.Context, entry AuditLogEntry)
- func (s *AuditService) LogSync(ctx context.Context, entry AuditLogEntry) error
- func (s *AuditService) Shutdown(ctx context.Context) error
- type AuthorizationRequest
- type AuthorizationService
- func (s *AuthorizationService) CreateAuthorizationCode(ctx context.Context, applicationID int64, ...) (plainCode string, record *models.AuthorizationCode, err error)
- func (s *AuthorizationService) ExchangeCode(ctx context.Context, ...) (*models.AuthorizationCode, error)
- func (s *AuthorizationService) GetUserAuthorization(userID string, applicationID int64) (*models.UserAuthorization, error)
- func (s *AuthorizationService) ListClientAuthorizations(ctx context.Context, clientID string) ([]UserAuthorizationWithUser, error)
- func (s *AuthorizationService) ListUserAuthorizations(ctx context.Context, userID string) ([]UserAuthorizationWithClient, error)
- func (s *AuthorizationService) RevokeAllApplicationTokens(ctx context.Context, clientID, actorUserID string) (int64, error)
- func (s *AuthorizationService) RevokeUserAuthorization(ctx context.Context, authUUID, userID string) error
- func (s *AuthorizationService) SaveUserAuthorization(ctx context.Context, userID string, applicationID int64, ...) (*models.UserAuthorization, error)
- func (s *AuthorizationService) ValidateAuthorizationRequest(clientID, redirectURI, responseType, scope, codeChallengeMethod, nonce string) (*AuthorizationRequest, error)
- type ClientResponse
- type ClientService
- func (s *ClientService) CountActiveTokens(clientID string) (int64, error)
- func (s *ClientService) CreateClient(ctx context.Context, req CreateClientRequest) (*ClientResponse, error)
- func (s *ClientService) DeleteClient(ctx context.Context, clientID, actorUserID string) error
- func (s *ClientService) GetClient(clientID string) (*models.OAuthApplication, error)
- func (s *ClientService) ListClients() ([]models.OAuthApplication, error)
- func (s *ClientService) ListClientsPaginated(params store.PaginationParams) ([]models.OAuthApplication, store.PaginationResult, error)
- func (s *ClientService) ListClientsPaginatedWithCreator(params store.PaginationParams) ([]ClientWithCreator, store.PaginationResult, error)
- func (s *ClientService) RegenerateSecret(ctx context.Context, clientID, actorUserID string) (string, error)
- func (s *ClientService) UpdateClient(ctx context.Context, clientID, actorUserID string, req UpdateClientRequest) error
- func (s *ClientService) VerifyClientSecret(clientID, clientSecret string) error
- type ClientWithCreator
- type CreateClientRequest
- type DeviceService
- func (s *DeviceService) AuthorizeDeviceCode(ctx context.Context, userCode, userID, username string) error
- func (s *DeviceService) GenerateDeviceCode(ctx context.Context, clientID, scope string) (*models.DeviceCode, error)
- func (s *DeviceService) GetClientByUserCode(userCode string) (*models.OAuthApplication, *models.DeviceCode, error)
- func (s *DeviceService) GetDeviceCode(deviceCode string) (*models.DeviceCode, error)
- func (s *DeviceService) GetDeviceCodeByUserCode(userCode string) (*models.DeviceCode, error)
- type TokenService
- func (s *TokenService) DisableToken(ctx context.Context, tokenID, actorUserID string) error
- func (s *TokenService) EnableToken(ctx context.Context, tokenID, actorUserID string) error
- func (s *TokenService) ExchangeAuthorizationCode(ctx context.Context, authCode *models.AuthorizationCode, authorizationID *uint) (*models.AccessToken, *models.AccessToken, string, error)
- func (s *TokenService) ExchangeDeviceCode(ctx context.Context, deviceCode, clientID string) (*models.AccessToken, *models.AccessToken, error)
- func (s *TokenService) GetActiveRefreshTokens(userID string) ([]models.AccessToken, error)
- func (s *TokenService) GetUserTokens(userID string) ([]models.AccessToken, error)
- func (s *TokenService) GetUserTokensWithClient(userID string) ([]TokenWithClient, error)
- func (s *TokenService) GetUserTokensWithClientPaginated(userID string, params store.PaginationParams) ([]TokenWithClient, store.PaginationResult, error)
- func (s *TokenService) IssueClientCredentialsToken(ctx context.Context, clientID, clientSecret, requestedScopes string) (*models.AccessToken, error)
- func (s *TokenService) RefreshAccessToken(ctx context.Context, refreshTokenString, clientID, requestedScopes string) (*models.AccessToken, *models.AccessToken, error)
- func (s *TokenService) RevokeAllUserTokens(userID string) error
- func (s *TokenService) RevokeToken(tokenString string) error
- func (s *TokenService) RevokeTokenByID(ctx context.Context, tokenID, actorUserID string) error
- func (s *TokenService) RevokeTokenByStatus(tokenID string) error
- func (s *TokenService) ValidateToken(ctx context.Context, tokenString string) (*token.ValidationResult, error)
- type TokenWithClient
- type UpdateClientRequest
- type UserAuthorizationWithClient
- type UserAuthorizationWithUser
- type UserService
- func (s *UserService) Authenticate(ctx context.Context, username, password string) (*models.User, error)
- func (s *UserService) AuthenticateWithOAuth(ctx context.Context, provider string, oauthUserInfo *auth.OAuthUserInfo, ...) (*models.User, error)
- func (s *UserService) GetUserByID(id string) (*models.User, error)
- func (s *UserService) InvalidateUserCache(id string)
Constants ¶
const ( ClientTypeConfidential = "confidential" ClientTypePublic = "public" )
Client type constants
const ( AuthModeLocal = "local" AuthModeHTTPAPI = "http_api" )
Variables ¶
var ( ErrInvalidAuthCodeRequest = errors.New("invalid_request") ErrAccessDeniedConsent = errors.New("access_denied") ErrUnsupportedResponseType = errors.New("unsupported_response_type") ErrInvalidAuthCodeScope = errors.New("invalid_scope") ErrInvalidRedirectURI = errors.New("invalid redirect_uri") ErrAuthCodeNotFound = errors.New("authorization code not found") ErrAuthCodeExpired = errors.New("authorization code expired") ErrAuthCodeAlreadyUsed = errors.New("authorization code already used") ErrInvalidCodeVerifier = errors.New("invalid code_verifier") ErrPKCERequired = errors.New("pkce required for public clients") ErrAuthorizationNotFound = errors.New("authorization not found") )
Authorization Code Flow errors
var ( ErrClientNotFound = errors.New("client not found") ErrInvalidClientData = errors.New("invalid client data") ErrClientNameRequired = errors.New("client name is required") ErrRedirectURIRequired = errors.New( "at least one redirect URI is required when Authorization Code Flow is enabled", ) ErrAtLeastOneGrantRequired = errors.New("at least one grant type must be enabled") )
var ( ErrInvalidClient = errors.New("invalid client_id") ErrClientInactive = errors.New("client is inactive") ErrDeviceFlowNotEnabled = errors.New("device flow not enabled for this client") ErrDeviceCodeNotFound = errors.New("device code not found") ErrDeviceCodeExpired = errors.New("device code expired") ErrUserCodeNotFound = errors.New("user code not found") )
var ( ErrAuthorizationPending = errors.New("authorization_pending") ErrSlowDown = errors.New("slow_down") ErrAccessDenied = errors.New("access_denied") ErrExpiredToken = errors.New("expired_token") ErrTokenCannotDisable = errors.New( "token cannot be disabled: only active tokens can be disabled", ) ErrTokenCannotEnable = errors.New( "token cannot be enabled: only disabled tokens can be re-enabled", ) // Client Credentials Flow errors (RFC 6749 §4.4) ErrInvalidClientCredentials = errors.New("invalid client credentials") ErrClientNotConfidential = errors.New( "client_credentials grant requires a confidential client", ) ErrClientCredentialsFlowDisabled = errors.New( "client_credentials flow is not enabled for this client", ) )
var ( ErrInvalidCredentials = errors.New("invalid username or password") ErrUserNotFound = errors.New("user not found") ErrAuthProviderFailed = errors.New("authentication provider failed") ErrUserSyncFailed = errors.New("failed to sync user from external provider") ErrUsernameConflict = errors.New("username already exists") ErrOAuthAutoRegisterDisabled = errors.New("OAuth auto-registration is disabled") )
Functions ¶
func FormatUserCode ¶
FormatUserCode formats a user code for display (e.g., "ABCDEFGH" -> "ABCD-EFGH")
Types ¶
type AuditLogEntry ¶
type AuditLogEntry struct {
EventType models.EventType
Severity models.EventSeverity
ActorUserID string
ActorUsername string
ActorIP string
ResourceType models.ResourceType
ResourceID string
ResourceName string
Action string
Details models.AuditDetails
Success bool
ErrorMessage string
UserAgent string
RequestPath string
RequestMethod string
}
AuditLogEntry represents the data needed to create an audit log entry
type AuditService ¶
type AuditService struct {
// contains filtered or unexported fields
}
AuditService handles audit logging operations
func NewAuditService ¶
func NewAuditService(s *store.Store, enabled bool, bufferSize int) *AuditService
NewAuditService creates a new audit service
func (*AuditService) CleanupOldLogs ¶
func (s *AuditService) CleanupOldLogs(retention time.Duration) (int64, error)
CleanupOldLogs deletes audit logs older than the retention period
func (*AuditService) GetAuditLogStats ¶
func (s *AuditService) GetAuditLogStats(startTime, endTime time.Time) (store.AuditLogStats, error)
GetAuditLogStats returns statistics about audit logs
func (*AuditService) GetAuditLogs ¶
func (s *AuditService) GetAuditLogs( params store.PaginationParams, filters store.AuditLogFilters, ) ([]models.AuditLog, store.PaginationResult, error)
GetAuditLogs retrieves audit logs with pagination and filtering
func (*AuditService) Log ¶
func (s *AuditService) Log(ctx context.Context, entry AuditLogEntry)
Log records an audit log entry asynchronously
func (*AuditService) LogSync ¶
func (s *AuditService) LogSync(ctx context.Context, entry AuditLogEntry) error
LogSync records an audit log entry synchronously (for critical events)
type AuthorizationRequest ¶
type AuthorizationRequest struct {
Client *models.OAuthApplication
RedirectURI string
Scopes string
State string
CodeChallenge string
CodeChallengeMethod string
Nonce string
}
AuthorizationRequest holds validated parameters for an authorization request
type AuthorizationService ¶
type AuthorizationService struct {
// contains filtered or unexported fields
}
AuthorizationService manages the OAuth 2.0 Authorization Code Flow (RFC 6749)
func NewAuthorizationService ¶
func NewAuthorizationService( s *store.Store, cfg *config.Config, auditService *AuditService, ) *AuthorizationService
func (*AuthorizationService) CreateAuthorizationCode ¶
func (s *AuthorizationService) CreateAuthorizationCode( ctx context.Context, applicationID int64, clientID, userID, redirectURI, scopes, codeChallenge, codeChallengeMethod, nonce string, ) (plainCode string, record *models.AuthorizationCode, err error)
CreateAuthorizationCode generates a one-time authorization code and saves it to the database. Returns the plaintext code (to be sent in the redirect) and the stored record.
func (*AuthorizationService) ExchangeCode ¶
func (s *AuthorizationService) ExchangeCode( ctx context.Context, plainCode, clientID, redirectURI, clientSecret, codeVerifier string, ) (*models.AuthorizationCode, error)
ExchangeCode validates a plaintext authorization code and marks it as used. The caller (TokenHandler) is responsible for issuing tokens after this returns successfully.
func (*AuthorizationService) GetUserAuthorization ¶
func (s *AuthorizationService) GetUserAuthorization( userID string, applicationID int64, ) (*models.UserAuthorization, error)
GetUserAuthorization returns the active consent record for a (user, application) pair. Returns nil, nil when no consent exists (not an error condition).
func (*AuthorizationService) ListClientAuthorizations ¶
func (s *AuthorizationService) ListClientAuthorizations( ctx context.Context, clientID string, ) ([]UserAuthorizationWithUser, error)
ListClientAuthorizations returns all active consent grants for a given client, with user details. Intended for the admin overview page.
func (*AuthorizationService) ListUserAuthorizations ¶
func (s *AuthorizationService) ListUserAuthorizations( ctx context.Context, userID string, ) ([]UserAuthorizationWithClient, error)
ListUserAuthorizations returns all active authorizations for a user with client display names.
func (*AuthorizationService) RevokeAllApplicationTokens ¶
func (s *AuthorizationService) RevokeAllApplicationTokens( ctx context.Context, clientID, actorUserID string, ) (int64, error)
RevokeAllApplicationTokens revokes all active tokens and consent records for an application. This is an admin operation that forces all users to re-authenticate.
func (*AuthorizationService) RevokeUserAuthorization ¶
func (s *AuthorizationService) RevokeUserAuthorization( ctx context.Context, authUUID, userID string, ) error
RevokeUserAuthorization revokes a user's consent for an application. It also revokes all active tokens that were issued under this authorization.
func (*AuthorizationService) SaveUserAuthorization ¶
func (s *AuthorizationService) SaveUserAuthorization( ctx context.Context, userID string, applicationID int64, clientID, scopes string, ) (*models.UserAuthorization, error)
SaveUserAuthorization creates or updates the consent record for a user+application pair.
func (*AuthorizationService) ValidateAuthorizationRequest ¶
func (s *AuthorizationService) ValidateAuthorizationRequest( clientID, redirectURI, responseType, scope, codeChallengeMethod, nonce string, ) (*AuthorizationRequest, error)
ValidateAuthorizationRequest validates all parameters of an incoming authorization request. Returns the parsed AuthorizationRequest on success.
type ClientResponse ¶
type ClientResponse struct {
*models.OAuthApplication
ClientSecretPlain string // Only populated on creation
}
type ClientService ¶
type ClientService struct {
// contains filtered or unexported fields
}
func NewClientService ¶
func NewClientService(s *store.Store, auditService *AuditService) *ClientService
func (*ClientService) CountActiveTokens ¶
func (s *ClientService) CountActiveTokens(clientID string) (int64, error)
CountActiveTokens returns the number of active tokens for a given client.
func (*ClientService) CreateClient ¶
func (s *ClientService) CreateClient( ctx context.Context, req CreateClientRequest, ) (*ClientResponse, error)
func (*ClientService) DeleteClient ¶
func (s *ClientService) DeleteClient(ctx context.Context, clientID, actorUserID string) error
func (*ClientService) GetClient ¶
func (s *ClientService) GetClient(clientID string) (*models.OAuthApplication, error)
func (*ClientService) ListClients ¶
func (s *ClientService) ListClients() ([]models.OAuthApplication, error)
func (*ClientService) ListClientsPaginated ¶
func (s *ClientService) ListClientsPaginated( params store.PaginationParams, ) ([]models.OAuthApplication, store.PaginationResult, error)
ListClientsPaginated returns paginated OAuth clients with search support
func (*ClientService) ListClientsPaginatedWithCreator ¶
func (s *ClientService) ListClientsPaginatedWithCreator( params store.PaginationParams, ) ([]ClientWithCreator, store.PaginationResult, error)
ListClientsPaginatedWithCreator returns paginated OAuth clients with creator information This method prevents N+1 queries by batch loading users via GetUsersByIDs
func (*ClientService) RegenerateSecret ¶
func (*ClientService) UpdateClient ¶
func (s *ClientService) UpdateClient( ctx context.Context, clientID, actorUserID string, req UpdateClientRequest, ) error
func (*ClientService) VerifyClientSecret ¶
func (s *ClientService) VerifyClientSecret(clientID, clientSecret string) error
type ClientWithCreator ¶
type ClientWithCreator struct {
models.OAuthApplication
CreatorUsername string // Empty string if user not found or deleted
}
ClientWithCreator combines OAuth client and creator user information for display
type CreateClientRequest ¶
type CreateClientRequest struct {
ClientName string
Description string
UserID string
Scopes string
RedirectURIs []string
CreatedBy string
ClientType string // ClientTypeConfidential or ClientTypePublic (default: ClientTypeConfidential)
EnableDeviceFlow bool // Enable Device Authorization Grant (RFC 8628)
EnableAuthCodeFlow bool // Enable Authorization Code Flow (RFC 6749)
EnableClientCredentialsFlow bool // Enable Client Credentials Grant (RFC 6749 §4.4); confidential clients only
}
type DeviceService ¶
type DeviceService struct {
// contains filtered or unexported fields
}
func NewDeviceService ¶
func NewDeviceService( s *store.Store, cfg *config.Config, auditService *AuditService, m metrics.Recorder, ) *DeviceService
func (*DeviceService) AuthorizeDeviceCode ¶
func (s *DeviceService) AuthorizeDeviceCode( ctx context.Context, userCode, userID, username string, ) error
AuthorizeDeviceCode marks a device code as authorized by a user
func (*DeviceService) GenerateDeviceCode ¶
func (s *DeviceService) GenerateDeviceCode( ctx context.Context, clientID, scope string, ) (*models.DeviceCode, error)
GenerateDeviceCode creates a new device code request
func (*DeviceService) GetClientByUserCode ¶
func (s *DeviceService) GetClientByUserCode( userCode string, ) (*models.OAuthApplication, *models.DeviceCode, error)
GetClientByUserCode retrieves the OAuth client and device code associated with a user code
func (*DeviceService) GetDeviceCode ¶
func (s *DeviceService) GetDeviceCode(deviceCode string) (*models.DeviceCode, error)
GetDeviceCode retrieves a device code by its code
func (*DeviceService) GetDeviceCodeByUserCode ¶
func (s *DeviceService) GetDeviceCodeByUserCode(userCode string) (*models.DeviceCode, error)
GetDeviceCodeByUserCode retrieves a device code by user code
type TokenService ¶
type TokenService struct {
// contains filtered or unexported fields
}
func NewTokenService ¶
func NewTokenService( s *store.Store, cfg *config.Config, ds *DeviceService, localProvider *token.LocalTokenProvider, httpProvider *token.HTTPTokenProvider, providerMode string, auditService *AuditService, m metrics.Recorder, ) *TokenService
func (*TokenService) DisableToken ¶
func (s *TokenService) DisableToken(ctx context.Context, tokenID, actorUserID string) error
DisableToken disables a token (can be re-enabled)
func (*TokenService) EnableToken ¶
func (s *TokenService) EnableToken(ctx context.Context, tokenID, actorUserID string) error
EnableToken re-enables a disabled token
func (*TokenService) ExchangeAuthorizationCode ¶
func (s *TokenService) ExchangeAuthorizationCode( ctx context.Context, authCode *models.AuthorizationCode, authorizationID *uint, ) (*models.AccessToken, *models.AccessToken, string, error)
ExchangeAuthorizationCode issues an access token, a refresh token, and (when the openid scope was granted) an OIDC ID Token for an already-validated authorization code. The AuthorizationCode record must have been validated and marked as used by AuthorizationService.ExchangeCode before calling this method. Returns: accessToken, refreshToken, idToken (empty string when openid not requested), error.
func (*TokenService) ExchangeDeviceCode ¶
func (s *TokenService) ExchangeDeviceCode( ctx context.Context, deviceCode, clientID string, ) (*models.AccessToken, *models.AccessToken, error)
ExchangeDeviceCode exchanges an authorized device code for access and refresh tokens
func (*TokenService) GetActiveRefreshTokens ¶
func (s *TokenService) GetActiveRefreshTokens(userID string) ([]models.AccessToken, error)
GetActiveRefreshTokens gets all active refresh tokens for a user
func (*TokenService) GetUserTokens ¶
func (s *TokenService) GetUserTokens(userID string) ([]models.AccessToken, error)
GetUserTokens returns all active tokens for a user
func (*TokenService) GetUserTokensWithClient ¶
func (s *TokenService) GetUserTokensWithClient(userID string) ([]TokenWithClient, error)
GetUserTokensWithClient returns all active tokens for a user with client information
func (*TokenService) GetUserTokensWithClientPaginated ¶
func (s *TokenService) GetUserTokensWithClientPaginated( userID string, params store.PaginationParams, ) ([]TokenWithClient, store.PaginationResult, error)
GetUserTokensWithClientPaginated returns paginated tokens for a user with client information
func (*TokenService) IssueClientCredentialsToken ¶ added in v0.12.0
func (s *TokenService) IssueClientCredentialsToken( ctx context.Context, clientID, clientSecret, requestedScopes string, ) (*models.AccessToken, error)
IssueClientCredentialsToken issues an access token for the client_credentials grant (RFC 6749 §4.4). Only confidential clients with EnableClientCredentialsFlow=true may use this flow. No refresh token is issued (per RFC 6749 §4.4.3).
The resulting token carries a synthetic machine identity in UserID: "client:<clientID>". This distinguishes M2M tokens from user-delegated tokens in all downstream lookups.
func (*TokenService) RefreshAccessToken ¶
func (s *TokenService) RefreshAccessToken( ctx context.Context, refreshTokenString, clientID, requestedScopes string, ) (*models.AccessToken, *models.AccessToken, error)
RefreshAccessToken generates new access token (and optionally new refresh token in rotation mode)
func (*TokenService) RevokeAllUserTokens ¶
func (s *TokenService) RevokeAllUserTokens(userID string) error
RevokeAllUserTokens revokes all tokens for a user
func (*TokenService) RevokeToken ¶
func (s *TokenService) RevokeToken(tokenString string) error
RevokeToken revokes a token by its JWT string
func (*TokenService) RevokeTokenByID ¶
func (s *TokenService) RevokeTokenByID(ctx context.Context, tokenID, actorUserID string) error
RevokeTokenByID revokes a token by its ID
func (*TokenService) RevokeTokenByStatus ¶
func (s *TokenService) RevokeTokenByStatus(tokenID string) error
RevokeTokenByStatus permanently revokes a token (uses status update, not deletion)
func (*TokenService) ValidateToken ¶
func (s *TokenService) ValidateToken( ctx context.Context, tokenString string, ) (*token.ValidationResult, error)
ValidateToken validates a JWT token using the configured provider
type TokenWithClient ¶
type TokenWithClient struct {
models.AccessToken
ClientName string
}
TokenWithClient combines token and client information for display
type UpdateClientRequest ¶
type UserAuthorizationWithClient ¶
type UserAuthorizationWithClient struct {
models.UserAuthorization
ClientName string
}
UserAuthorizationWithClient combines a UserAuthorization with its client's display name
type UserAuthorizationWithUser ¶
type UserAuthorizationWithUser struct {
models.UserAuthorization
Username string
Email string
}
UserAuthorizationWithUser combines a UserAuthorization with the authorizing user's details
type UserService ¶
type UserService struct {
// contains filtered or unexported fields
}
func NewUserService ¶
func NewUserService( s *store.Store, localProvider *auth.LocalAuthProvider, httpAPIProvider *auth.HTTPAPIAuthProvider, authMode string, oauthAutoRegister bool, auditService *AuditService, userCache cache.Cache[models.User], userCacheTTL time.Duration, ) *UserService
func (*UserService) Authenticate ¶
func (*UserService) AuthenticateWithOAuth ¶
func (s *UserService) AuthenticateWithOAuth( ctx context.Context, provider string, oauthUserInfo *auth.OAuthUserInfo, token *oauth2.Token, ) (*models.User, error)
AuthenticateWithOAuth authenticates a user via OAuth and creates/updates user account
func (*UserService) GetUserByID ¶
func (s *UserService) GetUserByID(id string) (*models.User, error)
func (*UserService) InvalidateUserCache ¶ added in v0.14.0
func (s *UserService) InvalidateUserCache(id string)
InvalidateUserCache removes the cached user entry for the given user ID. Call this after any mutation to user data to ensure stale data is not served.