postgres

package
v0.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 7, 2026 License: Apache-2.0 Imports: 9 Imported by: 0

Documentation

Overview

Package postgres provides the PostgreSQL-backed ulinzi.Store implementation (wave-1: opaque-session validation + permission resolution) over the "security" schema, using pgx.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Store

type Store struct {
	// contains filtered or unexported fields
}

Store implements ulinzi.Store against a pgx connection pool.

func New

func New(pool *pgxpool.Pool) *Store

New returns a Store backed by the given pool.

func (*Store) AddPasskey added in v0.4.0

func (s *Store) AddPasskey(ctx context.Context, p *ulinzi.AppUserPasskey) error

AddPasskey inserts a new passkey. The unique credential_id index rejects duplicates.

func (*Store) AppendChained

func (s *Store) AppendChained(ctx context.Context, e ulinzi.AuditEvent, hashFn func(prevHash string) string) error

AppendChained appends a hash-chained audit row. It serializes concurrent appends with a transaction-scoped advisory lock, reads the previous row's hash, computes this row's hash via hashFn(prevHash), and inserts atomically.

func (*Store) BumpSecurityStamp

func (s *Store) BumpSecurityStamp(ctx context.Context, userID uuid.UUID, newStamp string) error

BumpSecurityStamp rotates a user's security stamp (forces global logout).

func (*Store) CountRecentFailures

func (s *Store) CountRecentFailures(ctx context.Context, email string, since time.Time) (int, error)

CountRecentFailures counts failed attempts for email at or after since.

func (*Store) CreateSession

func (s *Store) CreateSession(ctx context.Context, rec *ulinzi.SessionRecord, loginCompletedAt time.Time) error

func (*Store) CreateUser

func (s *Store) CreateUser(ctx context.Context, id uuid.UUID, email, normalizedEmail, passwordHash, securityStamp string) error

func (*Store) DeleteExpiredMfaCodes

func (s *Store) DeleteExpiredMfaCodes(ctx context.Context) (int64, error)

DeleteExpiredMfaCodes prunes stale replay-ledger rows. Run on a schedule.

func (*Store) EnforceSessionCap

func (s *Store) EnforceSessionCap(ctx context.Context, userID uuid.UUID, max int) error

EnforceSessionCap deletes a user's active sessions beyond the newest max (MaxSessionsPerUser). A max <= 0 is a no-op.

func (*Store) GetActiveLockout

func (s *Store) GetActiveLockout(ctx context.Context, email string) (*ulinzi.ActiveLockout, error)

GetActiveLockout returns the most recent lockout row not yet admin-unlocked (even if expired), or nil.

func (*Store) GetActiveSessionPolicy

func (s *Store) GetActiveSessionPolicy(ctx context.Context) (*ulinzi.SessionPolicy, error)

func (*Store) GetIdpConfigByProvider added in v0.4.0

func (s *Store) GetIdpConfigByProvider(ctx context.Context, provider string) (*ulinzi.IdpConfiguration, error)

GetIdpConfigByProvider returns the config row for a provider, or nil if none.

func (*Store) GetLockoutPolicy

func (s *Store) GetLockoutPolicy(ctx context.Context) (*ulinzi.LockoutPolicy, error)

GetLockoutPolicy returns the most recently updated lockout policy, or nil.

func (*Store) GetMfa

func (s *Store) GetMfa(ctx context.Context, userID uuid.UUID) (*ulinzi.AppUserMfa, error)

func (*Store) GetPasskeyByCredentialID added in v0.4.0

func (s *Store) GetPasskeyByCredentialID(ctx context.Context, credentialID string) (*ulinzi.AppUserPasskey, error)

GetPasskeyByCredentialID looks up a passkey by its globally-unique credential id, or nil if none.

func (*Store) GetPasswordPolicy

func (s *Store) GetPasswordPolicy(ctx context.Context) (*ulinzi.PasswordPolicy, error)

GetPasswordPolicy returns the most recently updated password policy, or nil if none is configured (callers fall back to ulinzi.DefaultPasswordPolicy).

func (*Store) GetSessionByID

func (s *Store) GetSessionByID(ctx context.Context, sessionID string) (*ulinzi.SessionRecord, error)

func (*Store) GetUserAuthByEmail

func (s *Store) GetUserAuthByEmail(ctx context.Context, normalizedEmail string) (*ulinzi.UserAuth, error)

func (*Store) GetUserAuthByID

func (s *Store) GetUserAuthByID(ctx context.Context, id uuid.UUID) (*ulinzi.UserAuth, error)

func (*Store) GetUserByID

func (s *Store) GetUserByID(ctx context.Context, id uuid.UUID) (*ulinzi.User, error)

func (*Store) GetUserIDByExternalLogin added in v0.4.0

func (s *Store) GetUserIDByExternalLogin(ctx context.Context, provider ulinzi.IdentityProvider, providerKey string) (uuid.UUID, bool, error)

GetUserIDByExternalLogin resolves the local user id for (provider, providerKey), or ok=false when no link exists.

func (*Store) GetUserPermissions

func (s *Store) GetUserPermissions(ctx context.Context, userID uuid.UUID) ([]string, error)

func (*Store) GetUserRoles

func (s *Store) GetUserRoles(ctx context.Context, userID uuid.UUID) ([]string, error)

func (*Store) InsertLockout

func (s *Store) InsertLockout(ctx context.Context, email string, userID *string, lockoutCount, failedCount int, lockedAt time.Time, expiresAt *time.Time) error

InsertLockout appends a new account_lockouts row (expiresAt nil => permanent).

func (*Store) LinkExternalLogin added in v0.4.0

func (s *Store) LinkExternalLogin(ctx context.Context, login ulinzi.UserLogin) error

LinkExternalLogin idempotently upserts an external login on its composite key.

func (*Store) ListExternalLogins added in v0.4.0

func (s *Store) ListExternalLogins(ctx context.Context, userID uuid.UUID) ([]ulinzi.UserLogin, error)

ListExternalLogins returns all external links for a user (ordered by provider).

func (*Store) ListIdpConfigs added in v0.4.0

func (s *Store) ListIdpConfigs(ctx context.Context) ([]ulinzi.IdpConfiguration, error)

ListIdpConfigs returns every configured provider, ordered by provider.

func (*Store) ListPasskeysByUserID added in v0.4.0

func (s *Store) ListPasskeysByUserID(ctx context.Context, userID uuid.UUID) ([]ulinzi.AppUserPasskey, error)

ListPasskeysByUserID returns a user's passkeys, oldest first.

func (*Store) RecordLoginAttempt

func (s *Store) RecordLoginAttempt(ctx context.Context, a ulinzi.LoginAttempt) error

RecordLoginAttempt appends one row to security.login_attempts.

func (*Store) RemovePasskeyByUserAndCredentialID added in v0.4.0

func (s *Store) RemovePasskeyByUserAndCredentialID(ctx context.Context, userID uuid.UUID, credentialID string) (bool, error)

RemovePasskeyByUserAndCredentialID deletes a user's passkey, reporting whether a row was removed.

func (*Store) RevokeSession

func (s *Store) RevokeSession(ctx context.Context, sessionID, reason string, at time.Time) error

func (*Store) TouchSession

func (s *Store) TouchSession(ctx context.Context, id uuid.UUID, at time.Time) error

func (*Store) TryClaimMfaCode

func (s *Store) TryClaimMfaCode(ctx context.Context, userID uuid.UUID, codeHash string, ttl time.Duration) (bool, error)

TryClaimMfaCode atomically records a one-time use of codeHash for userID. It returns true on first use, false when a live (non-expired) claim already exists (a replay). An expired collision row is reclaimed. It fails closed on error.

The UNIQUE (user_id, code_hash) index makes the claim atomic: the INSERT ... ON CONFLICT DO UPDATE ... WHERE (expired) updates + RETURNs only when the prior claim has expired; a live claim leaves the WHERE false, so RETURNING yields no row (ErrNoRows) => replay.

func (*Store) UnlinkExternalLogin added in v0.4.0

func (s *Store) UnlinkExternalLogin(ctx context.Context, provider ulinzi.IdentityProvider, providerKey string) (bool, error)

UnlinkExternalLogin removes an external login, reporting whether a row existed.

func (*Store) UnlockAccount

func (s *Store) UnlockAccount(ctx context.Context, email, reason string, byUserID *string, at time.Time) error

UnlockAccount closes all open lockouts for the email (admin unlock).

func (*Store) UpdatePasskeySignCount added in v0.4.0

func (s *Store) UpdatePasskeySignCount(ctx context.Context, id uuid.UUID, signCount uint32) error

UpdatePasskeySignCount persists the monotonic signature counter after a successful assertion.

func (*Store) UpdatePasswordHash

func (s *Store) UpdatePasswordHash(ctx context.Context, id uuid.UUID, passwordHash string) error

func (*Store) UpsertIdpConfig added in v0.4.0

func (s *Store) UpsertIdpConfig(ctx context.Context, c *ulinzi.IdpConfiguration) error

UpsertIdpConfig inserts or fully replaces the row for c.Provider. The caller (ulinzi.IdpConfigService) has already merged partial updates and encrypted any secrets, so this is a straight full-row write.

func (*Store) UpsertMfa

func (s *Store) UpsertMfa(ctx context.Context, m *ulinzi.AppUserMfa) error

func (*Store) VerifyAuditChain

func (s *Store) VerifyAuditChain(ctx context.Context, hashFn func(prevHash string, e ulinzi.AuditEvent) string) (bool, int64, error)

VerifyAuditChain walks the audit log in seq order and recomputes each row's hash. It returns ok=false and the seq of the first row whose prev-linkage or stored hash does not match.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL