Documentation
¶
Index ¶
- Variables
- func GetDialector(driver, dsn string) (gorm.Dialector, error)
- func RegisterDriver(name string, factory DriverFactory)
- type AuditLogFilters
- type AuditLogStats
- type DashboardCounts
- type DriverFactory
- type PaginationParams
- type PaginationResult
- type Store
- func (s *Store) AuthorizeDeviceCode(id int64, userID string) error
- func (s *Store) Close(ctx context.Context) error
- func (s *Store) CountActiveTokensByCategory(category string) (int64, error)
- func (s *Store) CountActiveTokensByClientID(clientID string) (int64, error)
- func (s *Store) CountClientsByStatus(status string) (int64, error)
- func (s *Store) CountPendingDeviceCodes() (int64, error)
- func (s *Store) CountTotalDeviceCodes() (int64, error)
- func (s *Store) CountUsersByRole(role string) (int64, error)
- func (s *Store) CreateAccessToken(token *models.AccessToken) error
- func (s *Store) CreateAuditLog(log *models.AuditLog) error
- func (s *Store) CreateAuditLogBatch(logs []*models.AuditLog) error
- func (s *Store) CreateAuthorizationCode(code *models.AuthorizationCode) error
- func (s *Store) CreateClient(client *models.OAuthApplication) error
- func (s *Store) CreateDeviceCode(dc *models.DeviceCode) error
- func (s *Store) CreateOAuthConnection(conn *models.OAuthConnection) error
- func (s *Store) CreateUser(user *models.User) error
- func (s *Store) DB() *gorm.DBdeprecated
- func (s *Store) DeleteClient(clientID string) error
- func (s *Store) DeleteDeviceCodeByID(id int64) error
- func (s *Store) DeleteExpiredDeviceCodes() error
- func (s *Store) DeleteExpiredTokens() error
- func (s *Store) DeleteOAuthConnection(id string) error
- func (s *Store) DeleteOAuthConnectionsByUserID(userID string) error
- func (s *Store) DeleteOldAuditLogs(olderThan time.Time) (int64, error)
- func (s *Store) DeleteUser(id string) error
- func (s *Store) FindUserByNormalizedEmail(email string) (*models.User, error)
- func (s *Store) GetAccessTokenByHash(hash string) (*models.AccessToken, error)
- func (s *Store) GetAccessTokenByID(tokenID string) (*models.AccessToken, error)
- func (s *Store) GetActiveTokenHashesByAuthorizationID(authorizationID uint) ([]string, error)
- func (s *Store) GetActiveTokenHashesByClientID(clientID string) ([]string, error)
- func (s *Store) GetActiveTokenHashesByFamilyID(familyID string) ([]string, error)
- func (s *Store) GetAuditLogStats(startTime, endTime time.Time) (AuditLogStats, error)
- func (s *Store) GetAuditLogsPaginated(params PaginationParams, filters AuditLogFilters) ([]models.AuditLog, PaginationResult, error)
- func (s *Store) GetAuthorizationCodeByHash(hash string) (*models.AuthorizationCode, error)
- func (s *Store) GetClient(clientID string) (*models.OAuthApplication, error)
- func (s *Store) GetClientAuthorizations(clientID string) ([]models.UserAuthorization, error)
- func (s *Store) GetClientByIntID(id int64) (*models.OAuthApplication, error)
- func (s *Store) GetClientsByIDs(clientIDs []string) (map[string]*models.OAuthApplication, error)
- func (s *Store) GetDashboardCounts() (DashboardCounts, error)
- func (s *Store) GetDeviceCodeByUserCode(userCode string) (*models.DeviceCode, error)
- func (s *Store) GetDeviceCodesByID(deviceCodeID string) ([]*models.DeviceCode, error)
- func (s *Store) GetOAuthConnection(provider, providerUserID string) (*models.OAuthConnection, error)
- func (s *Store) GetOAuthConnectionByUserAndID(userID, connectionID string) (*models.OAuthConnection, error)
- func (s *Store) GetOAuthConnectionByUserAndProvider(userID, provider string) (*models.OAuthConnection, error)
- func (s *Store) GetOAuthConnectionsByUserID(userID string) ([]models.OAuthConnection, error)
- func (s *Store) GetTokenHashesByUserID(userID string) ([]string, error)
- func (s *Store) GetTokensByCategoryAndStatus(userID, category, status string) ([]models.AccessToken, error)
- func (s *Store) GetTokensByUserID(userID string) ([]models.AccessToken, error)
- func (s *Store) GetTokensByUserIDPaginated(userID string, params PaginationParams) ([]models.AccessToken, PaginationResult, error)
- func (s *Store) GetTokensPaginated(params PaginationParams) ([]models.AccessToken, PaginationResult, error)
- func (s *Store) GetUserAuthorization(userID string, applicationID int64) (*models.UserAuthorization, error)
- func (s *Store) GetUserAuthorizationByUUID(authUUID, userID string) (*models.UserAuthorization, error)
- func (s *Store) GetUserByEmail(email string) (*models.User, error)
- func (s *Store) GetUserByExternalID(externalID, authSource string) (*models.User, error)
- func (s *Store) GetUserByID(id string) (*models.User, error)
- func (s *Store) GetUserByUsername(username string) (*models.User, error)
- func (s *Store) GetUserStatsByUserID(userID string) (types.UserStatsCounts, error)
- func (s *Store) GetUsersByIDs(userIDs []string) (map[string]*models.User, error)
- func (s *Store) Health() error
- func (s *Store) ListClientsByUserID(userID string, params PaginationParams) ([]models.OAuthApplication, PaginationResult, error)
- func (s *Store) ListClientsPaginated(params PaginationParams) ([]models.OAuthApplication, PaginationResult, error)
- func (s *Store) ListUserAuthorizations(userID string) ([]models.UserAuthorization, error)
- func (s *Store) ListUsersPaginated(params PaginationParams) ([]models.User, PaginationResult, error)
- func (s *Store) MarkAuthorizationCodeUsed(id uint) error
- func (s *Store) RevokeAllActiveTokensByClientID(clientID string) (int64, error)
- func (s *Store) RevokeAllUserAuthorizationsByClientID(clientID string) error
- func (s *Store) RevokeAllUserAuthorizationsByUserID(userID string) error
- func (s *Store) RevokeToken(tokenID string) error
- func (s *Store) RevokeTokenFamily(familyID string) (int64, error)
- func (s *Store) RevokeTokensByAuthorizationID(authorizationID uint) error
- func (s *Store) RevokeTokensByClientID(clientID string) error
- func (s *Store) RevokeTokensByUserID(userID string) error
- func (s *Store) RevokeUserAuthorization(authUUID, userID string) (*models.UserAuthorization, error)
- func (s *Store) RunInTransaction(fn func(tx core.Store) error) error
- func (s *Store) UpdateClient(client *models.OAuthApplication) error
- func (s *Store) UpdateDeviceCode(dc *models.DeviceCode) error
- func (s *Store) UpdateOAuthConnection(conn *models.OAuthConnection) error
- func (s *Store) UpdateTokenLastUsedAt(tokenID string, t time.Time) error
- func (s *Store) UpdateTokenStatus(tokenID, status string) error
- func (s *Store) UpdateUser(user *models.User) error
- func (s *Store) UpsertExternalUser(username, externalID, authSource, email, fullName string) (*models.User, error)
- func (s *Store) UpsertUserAuthorization(auth *models.UserAuthorization) error
Constants ¶
This section is empty.
Variables ¶
var ( // ErrUsernameConflict is returned when a username already exists ErrUsernameConflict = errors.New("username already exists") // ErrExternalUserMissingIdentity is returned by UpsertExternalUser when // one of the required identity fields (username, externalID, authSource, // or — on create — email) is blank after trimming. Without a stable // identity we cannot safely create or link a user. ErrExternalUserMissingIdentity = errors.New( "external user missing required identity field (username, external_id, auth_source, or email)", ) // ErrAmbiguousEmail is returned by FindUserByNormalizedEmail when more // than one row matches the whitespace-normalized email — a signal that // legacy data contains duplicates differing only in incidental // whitespace, which must be deduped manually before the caller can // proceed. GetUserByEmail (exact indexed match) never returns this. ErrAmbiguousEmail = errors.New( "multiple users match the normalized email; manual deduplication required", ) // ErrAuthCodeAlreadyUsed is returned by MarkAuthorizationCodeUsed when the // code was already consumed by a concurrent request (0 rows updated). ErrAuthCodeAlreadyUsed = errors.New("authorization code already used") // ErrDeviceCodeAlreadyAuthorized is returned by AuthorizeDeviceCode when the // device code was already authorized by a concurrent request (0 rows updated). ErrDeviceCodeAlreadyAuthorized = errors.New("device code already authorized") )
var ( NewPaginationParams = types.NewPaginationParams CalculatePagination = types.CalculatePagination )
Re-export functions.
Functions ¶
func GetDialector ¶
GetDialector returns a GORM dialector for the given driver name and DSN
func RegisterDriver ¶
func RegisterDriver(name string, factory DriverFactory)
RegisterDriver allows registering custom database drivers
Types ¶
type AuditLogFilters ¶
type AuditLogFilters = types.AuditLogFilters
Re-export types from store/types for backward compatibility.
type AuditLogStats ¶
type AuditLogStats = types.AuditLogStats
Re-export types from store/types for backward compatibility.
type DashboardCounts ¶ added in v0.24.0
type DashboardCounts = types.DashboardCounts
Re-export types from store/types for backward compatibility.
type DriverFactory ¶
DriverFactory is a function that creates a gorm.Dialector
type PaginationParams ¶
type PaginationParams = types.PaginationParams
Re-export types from store/types for backward compatibility.
type PaginationResult ¶
type PaginationResult = types.PaginationResult
Re-export types from store/types for backward compatibility.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
func (*Store) AuthorizeDeviceCode ¶ added in v0.24.0
AuthorizeDeviceCode atomically marks a device code as authorized by a user. It uses a WHERE clause to ensure only one concurrent request wins; the loser receives ErrDeviceCodeAlreadyAuthorized (0 rows updated).
func (*Store) CountActiveTokensByCategory ¶
CountActiveTokensByCategory counts active, non-expired tokens by category
func (*Store) CountActiveTokensByClientID ¶
CountActiveTokensByClientID counts active tokens for a specific client
func (*Store) CountClientsByStatus ¶ added in v0.17.0
CountClientsByStatus returns the number of clients with the given status
func (*Store) CountPendingDeviceCodes ¶
CountPendingDeviceCodes counts pending (not yet authorized) device codes
func (*Store) CountTotalDeviceCodes ¶
CountTotalDeviceCodes counts all non-expired device codes
func (*Store) CountUsersByRole ¶ added in v0.24.0
CountUsersByRole returns the number of active users with the given role. Only active users are counted so that disabled admins do not inflate the "last admin" guard used by disable/delete operations.
func (*Store) CreateAccessToken ¶
func (s *Store) CreateAccessToken(token *models.AccessToken) error
func (*Store) CreateAuditLog ¶
CreateAuditLog creates a single audit log entry
func (*Store) CreateAuditLogBatch ¶
CreateAuditLogBatch creates multiple audit log entries in a single transaction
func (*Store) CreateAuthorizationCode ¶
func (s *Store) CreateAuthorizationCode(code *models.AuthorizationCode) error
CreateAuthorizationCode persists a new authorization code
func (*Store) CreateClient ¶
func (s *Store) CreateClient(client *models.OAuthApplication) error
func (*Store) CreateDeviceCode ¶
func (s *Store) CreateDeviceCode(dc *models.DeviceCode) error
CreateDeviceCode creates a new device code
func (*Store) CreateOAuthConnection ¶
func (s *Store) CreateOAuthConnection(conn *models.OAuthConnection) error
CreateOAuthConnection creates a new OAuth connection
func (*Store) CreateUser ¶
CreateUser creates a new user
func (*Store) DeleteClient ¶
func (*Store) DeleteDeviceCodeByID ¶
DeleteDeviceCodeByID deletes device code by ID (primary key)
func (*Store) DeleteExpiredDeviceCodes ¶
func (*Store) DeleteExpiredTokens ¶
func (*Store) DeleteOAuthConnection ¶
DeleteOAuthConnection deletes an OAuth connection by ID
func (*Store) DeleteOAuthConnectionsByUserID ¶ added in v0.24.0
DeleteOAuthConnectionsByUserID deletes all OAuth connections for a user.
func (*Store) DeleteOldAuditLogs ¶
DeleteOldAuditLogs deletes audit logs older than the specified time
func (*Store) DeleteUser ¶
DeleteUser deletes a user by ID
func (*Store) FindUserByNormalizedEmail ¶ added in v0.27.0
FindUserByNormalizedEmail looks up a user by email with whitespace- tolerant matching on the stored side. When more than one row ties to the normalized value, it returns ErrAmbiguousEmail instead of picking a non-deterministic winner. Intended for the OAuth auto-link flow where binding a verified provider to the wrong local user must be prevented.
Performance: the lookup is a `TRIM(email) = ?` scan bounded by LIMIT 2, which is NOT backed by the UNIQUE email index. Callers that do not need whitespace tolerance (the common case — admin uniqueness checks, etc.) should use GetUserByEmail instead.
Known limitation: Go's strings.TrimSpace strips Unicode whitespace while SQL TRIM() only removes ASCII spaces by default on SQLite and Postgres. The write paths in this package trim on insert/update, so newly stored rows stay free of both kinds; only pre-existing legacy rows containing exotic whitespace (tabs, NBSP, …) would miss this lookup.
func (*Store) GetAccessTokenByHash ¶ added in v0.15.0
func (s *Store) GetAccessTokenByHash(hash string) (*models.AccessToken, error)
func (*Store) GetAccessTokenByID ¶
func (s *Store) GetAccessTokenByID(tokenID string) (*models.AccessToken, error)
func (*Store) GetActiveTokenHashesByAuthorizationID ¶ added in v0.24.0
GetActiveTokenHashesByAuthorizationID returns token hashes for all active tokens linked to a specific UserAuthorization. Used for cache invalidation before bulk revocation.
func (*Store) GetActiveTokenHashesByClientID ¶ added in v0.24.0
GetActiveTokenHashesByClientID returns token hashes for all active tokens belonging to a specific client. Used for cache invalidation before bulk revocation.
func (*Store) GetActiveTokenHashesByFamilyID ¶ added in v0.23.0
GetActiveTokenHashesByFamilyID returns token hashes for all active tokens in a family. Used for cache invalidation before bulk revocation.
func (*Store) GetAuditLogStats ¶
func (s *Store) GetAuditLogStats(startTime, endTime time.Time) (AuditLogStats, error)
GetAuditLogStats returns statistics about audit logs in a given time range
func (*Store) GetAuditLogsPaginated ¶
func (s *Store) GetAuditLogsPaginated( params PaginationParams, filters AuditLogFilters, ) ([]models.AuditLog, PaginationResult, error)
GetAuditLogsPaginated retrieves audit logs with pagination and filtering
func (*Store) GetAuthorizationCodeByHash ¶
func (s *Store) GetAuthorizationCodeByHash(hash string) (*models.AuthorizationCode, error)
GetAuthorizationCodeByHash retrieves an authorization code by its SHA-256 hash
func (*Store) GetClient ¶
func (s *Store) GetClient(clientID string) (*models.OAuthApplication, error)
func (*Store) GetClientAuthorizations ¶
func (s *Store) GetClientAuthorizations(clientID string) ([]models.UserAuthorization, error)
GetClientAuthorizations returns all active consent records for a client, ordered by grant date
func (*Store) GetClientByIntID ¶
func (s *Store) GetClientByIntID(id int64) (*models.OAuthApplication, error)
GetClientByIntID retrieves an OAuth application by its integer primary key
func (*Store) GetClientsByIDs ¶
func (*Store) GetDashboardCounts ¶ added in v0.24.0
func (s *Store) GetDashboardCounts() (DashboardCounts, error)
GetDashboardCounts returns all dashboard metrics in a single raw SQL query using scalar subselects. Works on both SQLite and PostgreSQL.
func (*Store) GetDeviceCodeByUserCode ¶
func (s *Store) GetDeviceCodeByUserCode(userCode string) (*models.DeviceCode, error)
GetDeviceCodeByUserCode retrieves a device code by user code
func (*Store) GetDeviceCodesByID ¶
func (s *Store) GetDeviceCodesByID(deviceCodeID string) ([]*models.DeviceCode, error)
GetDeviceCodesByID retrieves all device codes with matching ID suffix Used for hash verification during token exchange
func (*Store) GetOAuthConnection ¶
func (s *Store) GetOAuthConnection( provider, providerUserID string, ) (*models.OAuthConnection, error)
GetOAuthConnection finds an OAuth connection by provider and provider user ID
func (*Store) GetOAuthConnectionByUserAndID ¶ added in v0.26.0
func (s *Store) GetOAuthConnectionByUserAndID( userID, connectionID string, ) (*models.OAuthConnection, error)
GetOAuthConnectionByUserAndID finds an OAuth connection by user ID and connection ID.
func (*Store) GetOAuthConnectionByUserAndProvider ¶
func (s *Store) GetOAuthConnectionByUserAndProvider( userID, provider string, ) (*models.OAuthConnection, error)
GetOAuthConnectionByUserAndProvider finds an OAuth connection by user ID and provider
func (*Store) GetOAuthConnectionsByUserID ¶
func (s *Store) GetOAuthConnectionsByUserID(userID string) ([]models.OAuthConnection, error)
GetOAuthConnectionsByUserID returns all OAuth connections for a user
func (*Store) GetTokenHashesByUserID ¶ added in v0.24.0
GetTokenHashesByUserID returns token hashes for all tokens belonging to a user (any status). Unlike GetActiveTokenHashesBy*, this includes revoked/disabled tokens because the caller (RevokeTokensByUserID) performs a hard DELETE regardless of status.
func (*Store) GetTokensByCategoryAndStatus ¶
func (s *Store) GetTokensByCategoryAndStatus( userID, category, status string, ) ([]models.AccessToken, error)
GetTokensByCategoryAndStatus returns tokens filtered by category and status
func (*Store) GetTokensByUserID ¶
func (s *Store) GetTokensByUserID(userID string) ([]models.AccessToken, error)
func (*Store) GetTokensByUserIDPaginated ¶
func (s *Store) GetTokensByUserIDPaginated( userID string, params PaginationParams, ) ([]models.AccessToken, PaginationResult, error)
GetTokensByUserIDPaginated returns paginated tokens for a user with search support.
func (*Store) GetTokensPaginated ¶ added in v0.24.0
func (s *Store) GetTokensPaginated( params PaginationParams, ) ([]models.AccessToken, PaginationResult, error)
GetTokensPaginated returns paginated tokens across all users with search support. Search additionally matches against username and email (via subquery).
func (*Store) GetUserAuthorization ¶
func (s *Store) GetUserAuthorization( userID string, applicationID int64, ) (*models.UserAuthorization, error)
GetUserAuthorization retrieves the active consent record for a (user, application) pair
func (*Store) GetUserAuthorizationByUUID ¶
func (s *Store) GetUserAuthorizationByUUID( authUUID, userID string, ) (*models.UserAuthorization, error)
GetUserAuthorizationByUUID retrieves an authorization by its public UUID, scoped to the owner
func (*Store) GetUserByEmail ¶
GetUserByEmail finds a user by the exact email address, using the UNIQUE index on the column. The input is trimmed with strings.TrimSpace before matching so callers can pass user-entered values safely, but the stored side is not normalized — legacy rows whose stored email carries incidental whitespace will NOT be found by this method. Callers that must protect against ambiguous legacy duplicates (notably the OAuth auto-link path) should use FindUserByNormalizedEmail instead; that path pays for a non-indexed TRIM-based scan in exchange for whitespace tolerance and ambiguity detection.
func (*Store) GetUserByExternalID ¶
GetUserByExternalID finds a user by their external ID and auth source
func (*Store) GetUserByUsername ¶
func (*Store) GetUserStatsByUserID ¶ added in v0.24.0
func (s *Store) GetUserStatsByUserID(userID string) (types.UserStatsCounts, error)
GetUserStatsByUserID returns all user stats (active tokens, OAuth connections, active authorizations) in a single database query using subqueries.
func (*Store) GetUsersByIDs ¶
GetUsersByIDs batch loads users by IDs using WHERE IN to prevent N+1 queries
func (*Store) ListClientsByUserID ¶ added in v0.17.0
func (s *Store) ListClientsByUserID( userID string, params PaginationParams, ) ([]models.OAuthApplication, PaginationResult, error)
ListClientsByUserID returns paginated OAuth clients owned by the given user
func (*Store) ListClientsPaginated ¶
func (s *Store) ListClientsPaginated( params PaginationParams, ) ([]models.OAuthApplication, PaginationResult, error)
ListClientsPaginated returns paginated OAuth clients with search and optional status filter support
func (*Store) ListUserAuthorizations ¶
func (s *Store) ListUserAuthorizations(userID string) ([]models.UserAuthorization, error)
ListUserAuthorizations returns all active authorizations for a user, newest first
func (*Store) ListUsersPaginated ¶ added in v0.24.0
func (s *Store) ListUsersPaginated( params PaginationParams, ) ([]models.User, PaginationResult, error)
ListUsersPaginated returns paginated users with search, role, and auth source filtering.
func (*Store) MarkAuthorizationCodeUsed ¶
MarkAuthorizationCodeUsed atomically sets UsedAt only when the code has not yet been consumed. The WHERE clause includes "used_at IS NULL" so that a concurrent request that races past the application-level IsUsed() check will update 0 rows and receive ErrAuthCodeAlreadyUsed, preventing double issuance.
func (*Store) RevokeAllActiveTokensByClientID ¶
RevokeAllActiveTokensByClientID revokes every active token for a client and returns the count
func (*Store) RevokeAllUserAuthorizationsByClientID ¶
RevokeAllUserAuthorizationsByClientID invalidates all active consent records for a client
func (*Store) RevokeAllUserAuthorizationsByUserID ¶ added in v0.24.0
RevokeAllUserAuthorizationsByUserID invalidates all active consent records for a user.
func (*Store) RevokeToken ¶
func (*Store) RevokeTokenFamily ¶ added in v0.20.0
RevokeTokenFamily revokes all active tokens that share the same TokenFamilyID. This is used for refresh token rotation replay detection: when a revoked refresh token is reused, all tokens in the family must be invalidated to prevent stolen token abuse.
func (*Store) RevokeTokensByAuthorizationID ¶
RevokeTokensByAuthorizationID revokes all active tokens linked to a specific UserAuthorization
func (*Store) RevokeTokensByClientID ¶
func (*Store) RevokeTokensByUserID ¶
func (*Store) RevokeUserAuthorization ¶
func (s *Store) RevokeUserAuthorization( authUUID, userID string, ) (*models.UserAuthorization, error)
RevokeUserAuthorization marks an authorization as revoked and returns the record
func (*Store) RunInTransaction ¶ added in v0.20.0
RunInTransaction executes fn inside a database transaction. The Store passed to fn operates within the transaction scope.
func (*Store) UpdateClient ¶
func (s *Store) UpdateClient(client *models.OAuthApplication) error
func (*Store) UpdateDeviceCode ¶
func (s *Store) UpdateDeviceCode(dc *models.DeviceCode) error
UpdateDeviceCode updates a device code
func (*Store) UpdateOAuthConnection ¶
func (s *Store) UpdateOAuthConnection(conn *models.OAuthConnection) error
UpdateOAuthConnection updates an existing OAuth connection
func (*Store) UpdateTokenLastUsedAt ¶ added in v0.20.0
UpdateTokenLastUsedAt updates the last_used_at timestamp of a token
func (*Store) UpdateTokenStatus ¶
UpdateTokenStatus updates the status of a token
func (*Store) UpdateUser ¶
UpdateUser updates an existing user
func (*Store) UpsertExternalUser ¶
func (s *Store) UpsertExternalUser( username, externalID, authSource, email, fullName string, ) (*models.User, error)
UpsertExternalUser creates or updates a user from external authentication
func (*Store) UpsertUserAuthorization ¶
func (s *Store) UpsertUserAuthorization(auth *models.UserAuthorization) error
UpsertUserAuthorization creates a new consent record or re-activates and updates an existing one. Uses a single atomic INSERT ... ON CONFLICT DO UPDATE to avoid the race condition that arises from a non-atomic SELECT-then-INSERT/UPDATE pattern.