Documentation
¶
Index ¶
- type FSAPIKeyStore
- func (s *FSAPIKeyStore) CreateAPIKey(userID, name string, scopes []string, expiresAt *time.Time) (fullKey string, apiKey *core.APIKey, err error)
- func (s *FSAPIKeyStore) GetAPIKeyByID(keyID string) (*core.APIKey, error)
- func (s *FSAPIKeyStore) ListUserAPIKeys(userID string) ([]*core.APIKey, error)
- func (s *FSAPIKeyStore) RevokeAPIKey(keyID string) error
- func (s *FSAPIKeyStore) UpdateAPIKeyLastUsed(keyID string) error
- func (s *FSAPIKeyStore) ValidateAPIKey(fullKey string) (*core.APIKey, error)
- type FSAppStore
- type FSChannelStore
- type FSIdentityStore
- func (s *FSIdentityStore) GetIdentity(identityType, identityValue string, createIfMissing bool) (*accounts.Identity, bool, error)
- func (s *FSIdentityStore) GetUserIdentities(userId string) ([]*accounts.Identity, error)
- func (s *FSIdentityStore) MarkIdentityVerified(identityType, identityValue string) error
- func (s *FSIdentityStore) SaveIdentity(identity *accounts.Identity) error
- func (s *FSIdentityStore) SetUserForIdentity(identityType, identityValue string, newUserId string) error
- type FSKeyStore
- func (s *FSKeyStore) DeleteKey(clientID string) error
- func (s *FSKeyStore) GetCurrentKid(clientID string) (string, error)
- func (s *FSKeyStore) GetExpectedAlg(clientID string) (string, error)
- func (s *FSKeyStore) GetKey(clientID string) (*keys.KeyRecord, error)
- func (s *FSKeyStore) GetKeyByKid(kid string) (*keys.KeyRecord, error)
- func (s *FSKeyStore) GetSigningKey(clientID string) (any, error)
- func (s *FSKeyStore) GetVerifyKey(clientID string) (any, error)
- func (s *FSKeyStore) ListKeyIDs() ([]string, error)
- func (s *FSKeyStore) ListKeys() ([]string, error)
- func (s *FSKeyStore) PutKey(rec *keys.KeyRecord) error
- func (s *FSKeyStore) RegisterKey(clientID string, key any, algorithm string) error
- type FSKidStore
- func (s *FSKidStore) Add(kid string, key any, algorithm string, clientID string, expiresAt time.Time) error
- func (s *FSKidStore) CleanExpired() error
- func (s *FSKidStore) GetKey(clientID string) (*keys.KeyRecord, error)
- func (s *FSKidStore) GetKeyByKid(kid string) (*keys.KeyRecord, error)
- func (s *FSKidStore) Remove(kid string) error
- type FSRefreshTokenStore
- func (s *FSRefreshTokenStore) CleanupExpiredTokens() error
- func (s *FSRefreshTokenStore) CreateRefreshToken(userID, clientID string, deviceInfo map[string]any, scopes []string) (*core.RefreshToken, error)
- func (s *FSRefreshTokenStore) GetRefreshToken(token string) (*core.RefreshToken, error)
- func (s *FSRefreshTokenStore) GetUserTokens(userID string) ([]*core.RefreshToken, error)
- func (s *FSRefreshTokenStore) RevokeRefreshToken(token string) error
- func (s *FSRefreshTokenStore) RevokeTokenFamily(family string) error
- func (s *FSRefreshTokenStore) RevokeUserTokens(userID string) error
- func (s *FSRefreshTokenStore) RotateRefreshToken(oldToken string) (*core.RefreshToken, error)
- type FSTokenStore
- func (s *FSTokenStore) CreateToken(userID, email string, tokenType localauth.VerificationType, ...) (*localauth.VerificationToken, error)
- func (s *FSTokenStore) DeleteToken(token string) error
- func (s *FSTokenStore) DeleteUserTokens(userID string, tokenType localauth.VerificationType) error
- func (s *FSTokenStore) GetToken(token string) (*localauth.VerificationToken, error)
- type FSUser
- type FSUserStore
- type FSUsername
- type FSUsernameStore
- func (s *FSUsernameStore) ChangeUsername(oldUsername, newUsername, userID string) error
- func (s *FSUsernameStore) GetUserByUsername(username string) (string, error)
- func (s *FSUsernameStore) ReleaseUsername(username string) error
- func (s *FSUsernameStore) ReserveUsername(username string, userID string) error
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type FSAPIKeyStore ¶
type FSAPIKeyStore struct {
StoragePath string
// contains filtered or unexported fields
}
FSAPIKeyStore stores API keys as JSON files
func NewFSAPIKeyStore ¶
func NewFSAPIKeyStore(storagePath string) *FSAPIKeyStore
NewFSAPIKeyStore creates a new file-based API key store
func (*FSAPIKeyStore) CreateAPIKey ¶
func (s *FSAPIKeyStore) CreateAPIKey(userID, name string, scopes []string, expiresAt *time.Time) (fullKey string, apiKey *core.APIKey, err error)
CreateAPIKey creates a new API key and returns the full key (only shown once) The key format is: keyID + "_" + secret
func (*FSAPIKeyStore) GetAPIKeyByID ¶
func (s *FSAPIKeyStore) GetAPIKeyByID(keyID string) (*core.APIKey, error)
GetAPIKeyByID retrieves an API key by its public ID
func (*FSAPIKeyStore) ListUserAPIKeys ¶
func (s *FSAPIKeyStore) ListUserAPIKeys(userID string) ([]*core.APIKey, error)
ListUserAPIKeys returns all API keys for a user (without secrets)
func (*FSAPIKeyStore) RevokeAPIKey ¶
func (s *FSAPIKeyStore) RevokeAPIKey(keyID string) error
RevokeAPIKey marks an API key as revoked
func (*FSAPIKeyStore) UpdateAPIKeyLastUsed ¶
func (s *FSAPIKeyStore) UpdateAPIKeyLastUsed(keyID string) error
UpdateAPIKeyLastUsed updates the last used timestamp
func (*FSAPIKeyStore) ValidateAPIKey ¶
func (s *FSAPIKeyStore) ValidateAPIKey(fullKey string) (*core.APIKey, error)
ValidateAPIKey validates a full API key and returns the key metadata if valid The fullKey format is: keyID + "_" + secret
type FSAppStore ¶ added in v0.0.81
type FSAppStore struct {
StoragePath string
// contains filtered or unexported fields
}
FSAppStore implements admin.AppRegistrationStore by persisting each registration as a JSON file under {basePath}/apps/{client_id}.json.
Mirrors the FSKeyStore design: file-per-record (so concurrent ops don't serialize on a single mutex outside this process), atomic writes via temp-file + rename (so a crash mid-write leaves either the old file or the new file intact, never a half-written one), and safeName guarding path-traversal in client_ids.
In-process concurrency is mediated by sync.RWMutex. Multi-process deployments need a backend with real transaction semantics — see GORMAppStore (#167).
func NewFSAppStore ¶ added in v0.0.81
func NewFSAppStore(storagePath string) *FSAppStore
NewFSAppStore creates a filesystem-backed AppRegistrationStore. The {basePath}/apps/ directory is created lazily on first write.
func (*FSAppStore) DeleteApp ¶ added in v0.0.81
func (s *FSAppStore) DeleteApp(clientID string) error
DeleteApp removes the registration for clientID. Returns admin.ErrAppNotFound if no such registration exists, matching InMemoryAppStore semantics.
func (*FSAppStore) GetApp ¶ added in v0.0.81
func (s *FSAppStore) GetApp(clientID string) (*admin.AppRegistration, error)
GetApp returns the registration for clientID, or admin.ErrAppNotFound if no such file exists. A corrupt JSON file surfaces as a parse error rather than ErrAppNotFound — callers should distinguish "registration absent" from "registration unreadable" so an unexpected on-disk corruption isn't silently treated as a missing client.
func (*FSAppStore) ListApps ¶ added in v0.0.81
func (s *FSAppStore) ListApps() ([]*admin.AppRegistration, error)
ListApps returns every registration in the store. Files that fail to parse are skipped (with no error returned) so a single hand-corrupted file does not lock out admin tooling — partial recovery beats total failure here. Callers needing strict integrity should validate at the store level (e.g., periodic fsck) rather than relying on ListApps.
Returns an empty slice (not an error) when the apps dir does not yet exist, matching the InMemory backend's "fresh store has no apps" shape.
func (*FSAppStore) SaveApp ¶ added in v0.0.81
func (s *FSAppStore) SaveApp(app *admin.AppRegistration) error
SaveApp persists app to disk. Overwrites any existing registration with the same client_id. Empty client_id is rejected.
type FSChannelStore ¶
type FSChannelStore struct {
StoragePath string
}
FSChannelStore stores channels as JSON files
func NewFSChannelStore ¶
func NewFSChannelStore(storagePath string) *FSChannelStore
func (*FSChannelStore) GetChannel ¶
func (*FSChannelStore) GetChannelsByIdentity ¶
func (s *FSChannelStore) GetChannelsByIdentity(identityKey string) ([]*accounts.Channel, error)
func (*FSChannelStore) SaveChannel ¶
func (s *FSChannelStore) SaveChannel(channel *accounts.Channel) error
type FSIdentityStore ¶
type FSIdentityStore struct {
StoragePath string
}
FSIdentityStore stores identities as JSON files
func NewFSIdentityStore ¶
func NewFSIdentityStore(storagePath string) *FSIdentityStore
func (*FSIdentityStore) GetIdentity ¶
func (*FSIdentityStore) GetUserIdentities ¶
func (s *FSIdentityStore) GetUserIdentities(userId string) ([]*accounts.Identity, error)
func (*FSIdentityStore) MarkIdentityVerified ¶
func (s *FSIdentityStore) MarkIdentityVerified(identityType, identityValue string) error
func (*FSIdentityStore) SaveIdentity ¶
func (s *FSIdentityStore) SaveIdentity(identity *accounts.Identity) error
func (*FSIdentityStore) SetUserForIdentity ¶
func (s *FSIdentityStore) SetUserForIdentity(identityType, identityValue string, newUserId string) error
type FSKeyStore ¶ added in v0.0.32
type FSKeyStore struct {
StoragePath string
// contains filtered or unexported fields
}
FSKeyStore implements keys.KeyStorage using filesystem storage.
func NewFSKeyStore ¶ added in v0.0.32
func NewFSKeyStore(storagePath string) *FSKeyStore
NewFSKeyStore creates a new filesystem-backed KeyStore.
func (*FSKeyStore) DeleteKey ¶ added in v0.0.32
func (s *FSKeyStore) DeleteKey(clientID string) error
func (*FSKeyStore) GetCurrentKid ¶ added in v0.0.38
func (s *FSKeyStore) GetCurrentKid(clientID string) (string, error)
func (*FSKeyStore) GetExpectedAlg ¶ added in v0.0.32
func (s *FSKeyStore) GetExpectedAlg(clientID string) (string, error)
func (*FSKeyStore) GetKey ¶ added in v0.0.38
func (s *FSKeyStore) GetKey(clientID string) (*keys.KeyRecord, error)
func (*FSKeyStore) GetKeyByKid ¶ added in v0.0.38
func (s *FSKeyStore) GetKeyByKid(kid string) (*keys.KeyRecord, error)
func (*FSKeyStore) GetSigningKey ¶ added in v0.0.32
func (s *FSKeyStore) GetSigningKey(clientID string) (any, error)
func (*FSKeyStore) GetVerifyKey ¶ added in v0.0.32
func (s *FSKeyStore) GetVerifyKey(clientID string) (any, error)
func (*FSKeyStore) ListKeyIDs ¶ added in v0.0.38
func (s *FSKeyStore) ListKeyIDs() ([]string, error)
func (*FSKeyStore) ListKeys ¶ added in v0.0.32
func (s *FSKeyStore) ListKeys() ([]string, error)
func (*FSKeyStore) RegisterKey ¶ added in v0.0.32
func (s *FSKeyStore) RegisterKey(clientID string, key any, algorithm string) error
type FSKidStore ¶ added in v0.0.83
type FSKidStore struct {
StoragePath string
// contains filtered or unexported fields
}
FSKidStore implements keys.KidStorage using filesystem storage. One file per kid under {StoragePath}/kid_keys/, mirroring FSKeyStore's file-per-record layout.
func NewFSKidStore ¶ added in v0.0.83
func NewFSKidStore(storagePath string) *FSKidStore
NewFSKidStore creates a new filesystem-backed KidStorage.
func (*FSKidStore) CleanExpired ¶ added in v0.0.83
func (s *FSKidStore) CleanExpired() error
func (*FSKidStore) GetKey ¶ added in v0.0.83
func (s *FSKidStore) GetKey(clientID string) (*keys.KeyRecord, error)
GetKey always returns ErrKeyNotFound — KidStorage is kid-indexed and has no clientID→key lookup. Matches the in-memory KidStore.
func (*FSKidStore) GetKeyByKid ¶ added in v0.0.83
func (s *FSKidStore) GetKeyByKid(kid string) (*keys.KeyRecord, error)
func (*FSKidStore) Remove ¶ added in v0.0.83
func (s *FSKidStore) Remove(kid string) error
Remove is idempotent — deleting an absent kid is not an error.
type FSRefreshTokenStore ¶
type FSRefreshTokenStore struct {
StoragePath string
// contains filtered or unexported fields
}
FSRefreshTokenStore stores refresh tokens as JSON files
func NewFSRefreshTokenStore ¶
func NewFSRefreshTokenStore(storagePath string) *FSRefreshTokenStore
NewFSRefreshTokenStore creates a new file-based refresh token store
func (*FSRefreshTokenStore) CleanupExpiredTokens ¶
func (s *FSRefreshTokenStore) CleanupExpiredTokens() error
CleanupExpiredTokens removes expired tokens (for maintenance)
func (*FSRefreshTokenStore) CreateRefreshToken ¶
func (s *FSRefreshTokenStore) CreateRefreshToken(userID, clientID string, deviceInfo map[string]any, scopes []string) (*core.RefreshToken, error)
CreateRefreshToken creates a new refresh token for a user
func (*FSRefreshTokenStore) GetRefreshToken ¶
func (s *FSRefreshTokenStore) GetRefreshToken(token string) (*core.RefreshToken, error)
GetRefreshToken retrieves a refresh token by its value
func (*FSRefreshTokenStore) GetUserTokens ¶
func (s *FSRefreshTokenStore) GetUserTokens(userID string) ([]*core.RefreshToken, error)
GetUserTokens lists all active (non-revoked, non-expired) refresh tokens for a user
func (*FSRefreshTokenStore) RevokeRefreshToken ¶
func (s *FSRefreshTokenStore) RevokeRefreshToken(token string) error
RevokeRefreshToken marks a token as revoked
func (*FSRefreshTokenStore) RevokeTokenFamily ¶
func (s *FSRefreshTokenStore) RevokeTokenFamily(family string) error
RevokeTokenFamily revokes all tokens in a family (theft detection)
func (*FSRefreshTokenStore) RevokeUserTokens ¶
func (s *FSRefreshTokenStore) RevokeUserTokens(userID string) error
RevokeUserTokens revokes all refresh tokens for a user
func (*FSRefreshTokenStore) RotateRefreshToken ¶
func (s *FSRefreshTokenStore) RotateRefreshToken(oldToken string) (*core.RefreshToken, error)
RotateRefreshToken invalidates old token and creates new one in same family Returns ErrTokenReused if the old token was already revoked (theft detection)
type FSTokenStore ¶
type FSTokenStore struct {
StoragePath string
}
FSTokenStore stores localauth verification and reset tokens as JSON files. Satisfies localauth.VerificationTokenStore.
func NewFSTokenStore ¶
func NewFSTokenStore(storagePath string) *FSTokenStore
func (*FSTokenStore) CreateToken ¶
func (s *FSTokenStore) CreateToken(userID, email string, tokenType localauth.VerificationType, expiryDuration time.Duration) (*localauth.VerificationToken, error)
func (*FSTokenStore) DeleteToken ¶
func (s *FSTokenStore) DeleteToken(token string) error
func (*FSTokenStore) DeleteUserTokens ¶
func (s *FSTokenStore) DeleteUserTokens(userID string, tokenType localauth.VerificationType) error
func (*FSTokenStore) GetToken ¶
func (s *FSTokenStore) GetToken(token string) (*localauth.VerificationToken, error)
type FSUser ¶
type FSUser struct {
UserId string `json:"user_id"`
IsActive bool `json:"is_active"`
UserProfile map[string]any `json:"profile"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
FSUser implements the oneauth.User interface
type FSUserStore ¶
type FSUserStore struct {
StoragePath string
}
FSUserStore stores users as JSON files
func NewFSUserStore ¶
func NewFSUserStore(storagePath string) *FSUserStore
func (*FSUserStore) CreateUser ¶
func (*FSUserStore) GetUserById ¶
func (s *FSUserStore) GetUserById(userId string) (accounts.User, error)
type FSUsername ¶ added in v0.0.26
type FSUsername struct {
NormalizedUsername string `json:"normalized_username"` // Lowercase for lookups
Username string `json:"username"` // Original case-preserved
UserID string `json:"user_id"`
Version int `json:"version"` // For optimistic concurrency
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
FSUsername represents a username reservation stored as JSON
type FSUsernameStore ¶ added in v0.0.26
type FSUsernameStore struct {
StoragePath string
}
FSUsernameStore implements oa.UsernameStore using filesystem storage.
Purpose ¶
Provides username uniqueness enforcement and username-based login lookup using JSON files. Each username is stored as a separate file with the normalized (lowercase) username as the filename.
File Structure ¶
{StoragePath}/
└── usernames/
├── johndoe.json # {"username": "JohnDoe", "user_id": "abc123", ...}
├── janedoe.json # {"username": "JaneDoe", "user_id": "xyz789", ...}
└── ...
Concurrency Model ¶
Uses optimistic locking with version numbers. The atomic file write (write to temp, rename) provides basic safety, but concurrent modifications to the same username should be serialized at the application level or will result in last-write-wins behavior.
Setup ¶
usernameStore := fs.NewFSUsernameStore("/var/data/myapp")
localAuth := &oneauth.LocalAuth{
UsernameStore: usernameStore,
SignupPolicy: &oneauth.SignupPolicy{
RequireUsername: true,
EnforceUsernameUnique: true,
},
}
func NewFSUsernameStore ¶ added in v0.0.26
func NewFSUsernameStore(storagePath string) *FSUsernameStore
NewFSUsernameStore creates a new filesystem-backed UsernameStore
func (*FSUsernameStore) ChangeUsername ¶ added in v0.0.26
func (s *FSUsernameStore) ChangeUsername(oldUsername, newUsername, userID string) error
ChangeUsername atomically changes a username using optimistic concurrency. Returns error if new username is already taken.
Usage ¶
Called from a "Change Username" profile page handler.
Concurrency Note ¶
This is not fully atomic across files. In a race condition where another process takes the new username between our check and creation, we attempt to restore the old username. For production systems with high concurrency, consider using a database-backed store instead.
func (*FSUsernameStore) GetUserByUsername ¶ added in v0.0.26
func (s *FSUsernameStore) GetUserByUsername(username string) (string, error)
GetUserByUsername looks up a userID by username (case-insensitive).
Usage ¶
Called by NewCredentialsValidatorWithUsername during login when user enters a username instead of email.
func (*FSUsernameStore) ReleaseUsername ¶ added in v0.0.26
func (s *FSUsernameStore) ReleaseUsername(username string) error
ReleaseUsername removes a username reservation.
When to Use ¶
Call this when:
- User deletes their account
- Admin removes a username (e.g., for policy violations)
func (*FSUsernameStore) ReserveUsername ¶ added in v0.0.26
func (s *FSUsernameStore) ReserveUsername(username string, userID string) error
ReserveUsername reserves a username for a user. Returns error if username is already taken by a different user.
Concurrency ¶
Uses file system as implicit lock. The atomic write (temp file + rename) ensures no partial writes, but concurrent reservations of the same username will result in one succeeding (the last to complete the rename).