Documentation
¶
Overview ¶
Package authletstore is memory-system's GORM-backed implementation of authlet/pkg/storage; tables match internal/migrations/<ts>_authlet_tables.sql.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func SeedUIClient ¶
func SeedUIClient(ctx context.Context, store *Store, clientID, baseURL string, logger *slog.Logger) error
SeedUIClient idempotently registers the public PKCE OAuth client the web UI authenticates as, so no operator ever hand-inserts an oauth_clients row. It runs at boot after the authlet tables are migrated, when OAuth is enabled.
Behavior:
- absent: create a public (client_secret_hash NULL, token_endpoint_auth_method "none") client with redirect_uris = [baseURL+"/ui"] and the fixed metadata.
- present and already our public/none shape: bring redirect_uris/metadata back in sync with current config (so a changed PUBLIC_BASE_URL is picked up), writing only when they actually differ.
- present but NOT our shape (a confidential client of the same id): leave it untouched and log a warning — never clobber an operator's row.
All persistence goes through the store's own helpers/models (GORM), never raw SQL.
Types ¶
type AuthletSigningKey ¶
type AuthletSigningKey struct {
ID string `gorm:"primaryKey;column:id"`
Algorithm string `gorm:"column:alg"`
PublicPEM []byte `gorm:"column:public_pem"`
PrivatePEMEncrypted []byte `gorm:"column:private_pem_encrypted"`
IsActive bool `gorm:"column:is_active;index"`
CreatedAt time.Time `gorm:"column:created_at"`
RetiresAt *time.Time `gorm:"column:retires_at"`
}
AuthletSigningKey is the GORM row for an RSA signing key. One key is active at a time; retired keys stay queryable for verification until RetiresAt.
func (AuthletSigningKey) TableName ¶
func (AuthletSigningKey) TableName() string
TableName returns the Postgres table name for AuthletSigningKey.
type FamilyRevocation ¶
type FamilyRevocation struct {
FamilyID string `gorm:"primaryKey;column:family_id"`
RevokedAt time.Time `gorm:"column:revoked_at"`
}
FamilyRevocation marks an entire token family revoked; see RevokeFamily / IsFamilyRevoked.
func (FamilyRevocation) TableName ¶
func (FamilyRevocation) TableName() string
TableName returns the Postgres table name for FamilyRevocation.
type OAuthClient ¶
type OAuthClient struct {
ClientID string `gorm:"primaryKey;column:client_id"`
ClientSecretHash []byte `gorm:"column:client_secret_hash"`
TokenEndpointAuthMethod string `gorm:"column:token_endpoint_auth_method"`
RedirectURIs StringArray `gorm:"column:redirect_uris;type:text[]"`
Metadata datatypes.JSON `gorm:"column:metadata"`
CreatedAt time.Time `gorm:"column:created_at"`
LastUsedAt time.Time `gorm:"column:last_used_at"`
ExpiresAt time.Time `gorm:"column:expires_at"`
}
OAuthClient is the GORM row for a registered OAuth client (public DCR'd or pre-registered confidential). ClientSecretHash and TokenEndpointAuthMethod are top-level columns, not in Metadata, so SQL-seeded clients skip JSON unmarshalling.
func (OAuthClient) TableName ¶
func (OAuthClient) TableName() string
TableName returns the Postgres table name for OAuthClient.
type OAuthCode ¶
type OAuthCode struct {
CodeHash string `gorm:"primaryKey;column:code_hash"`
ClientID string `gorm:"column:client_id;index"`
UserID string `gorm:"column:user_id"`
Resource string `gorm:"column:resource"`
Scope string `gorm:"column:scope"`
PKCEChallenge string `gorm:"column:pkce_challenge"`
PKCEMethod string `gorm:"column:pkce_method"`
RedirectURI string `gorm:"column:redirect_uri"`
// Nonce carries the client's OIDC nonce from /authorize to the minted
// id_token (authlet v1.0.3); without it the nonce replay-defense no-ops.
Nonce string `gorm:"column:nonce"`
ExpiresAt time.Time `gorm:"column:expires_at;index"`
}
OAuthCode is the GORM row for a short-lived authorization code. The code itself is never stored; only its hash is.
type OAuthRefreshToken ¶
type OAuthRefreshToken struct {
TokenHash string `gorm:"primaryKey;column:token_hash"`
FamilyID string `gorm:"column:family_id;index"`
ClientID string `gorm:"column:client_id;index"`
UserID string `gorm:"column:user_id;index"`
Resource string `gorm:"column:resource"`
Scope string `gorm:"column:scope"`
ReplacedBy string `gorm:"column:replaced_by"`
RevokedAt gorm.DeletedAt `gorm:"column:revoked_at"`
ExpiresAt time.Time `gorm:"column:expires_at;index"`
}
OAuthRefreshToken is the GORM row for a refresh token. ReplacedBy tracks reuse-detection state; FamilyID groups rotated tokens for whole-chain revocation.
func (OAuthRefreshToken) TableName ¶
func (OAuthRefreshToken) TableName() string
TableName returns the Postgres table name for OAuthRefreshToken.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store is memory-system's storage.Storage implementation, grouping the four sub-stores on one *gorm.DB so they share transactions and connection pooling.
func New ¶
New constructs a Store backed by db, which must already have the authlet tables migrated.
func (*Store) Clients ¶
func (s *Store) Clients() storage.ClientStore
Clients returns the ClientStore view.
func (*Store) RefreshTokens ¶
func (s *Store) RefreshTokens() storage.RefreshTokenStore
RefreshTokens returns the RefreshTokenStore view.
func (*Store) SigningKeys ¶
func (s *Store) SigningKeys() storage.SigningKeyStore
SigningKeys returns the SigningKeyStore view.
type StringArray ¶
type StringArray []string
StringArray bridges Go []string and Postgres text[]. For non-Postgres backends (sqlite in tests) it falls back to JSON-encoded storage.
func (*StringArray) Scan ¶
func (s *StringArray) Scan(src any) error
Scan implements sql.Scanner. Tries pq.StringArray first; falls back to JSON unmarshalling so the same type works against sqlite test backends.