sqlitestore

package
v0.7.0 Latest Latest
Warning

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

Go to latest
Published: Oct 19, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Package sqlitestore implements auth's store ports on SQLite: the same ports pgstore implements, for a CLI, a single-host service or a test suite that has no Postgres to run against.

It uses modernc.org/sqlite, a pure-Go driver, so a binary embedding this package still cross-compiles with nothing but GOOS and GOARCH.

Its tables carry an auth_ prefix, since SQLite has no schemas, and migrate with their own goose version table, so an app keeping its own tables in the same file runs Migrate beside its own migrations and neither sees the other's history.

Where it differs from pgstore

The ports behave the same; storetest holds both to that. What differs is what SQLite is:

  • One writer at a time. Every transaction begins IMMEDIATE, taking the write lock up front, and a writer that cannot get it waits up to the busy timeout and then fails. Under sustained concurrent writes that surfaces as an error where Postgres would have queued the work.
  • Ids are TEXT. Each id is parsed as a uuid and stored in its canonical lower-case form, which is what makes an upper-case id find its row as it would against a uuid column.
  • Instants are TEXT in a fixed-width UTC layout, read back in UTC.
  • Lists (scopes, transports, recovery-code hashes) are JSON arrays.

Index

Constants

View Source
const VersionTable = "auth_goose_db_version"

VersionTable is goose's bookkeeping for the auth tables, kept apart from the app's own goose_db_version.

Variables

This section is empty.

Functions

func DSN

func DSN(path string) string

DSN returns the modernc.org/sqlite data source name Store expects for the database file at path. A host that opens its own *sql.DB and hands it to New must open it with these settings:

  • foreign_keys(1): SQLite ignores REFERENCES unless every connection asks it not to, and the cascades are part of the schema.
  • busy_timeout(5000): a writer waits for the lock rather than failing at once.
  • _txlock=immediate: a transaction takes the write lock when it begins, not at its first write, where SQLite would fail it without waiting.

func Migrate

func Migrate(ctx context.Context, db *sql.DB) error

Migrate brings the auth tables to the current version.

Types

type Store

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

Store implements every port pgstore does, and store.TxRunner, over one database.

func New

func New(db *sql.DB) *Store

New returns a Store over db, which must have been opened with DSN's settings and migrated. Open does both.

func Open

func Open(ctx context.Context, path string) (*Store, error)

Open opens (creating if needed) the SQLite database at path, configures it as Store requires and migrates it. It is the whole setup for a CLI or a small service; Close the Store when done.

path is a file. An in-memory database is refused: database/sql opens a fresh one per connection, so writes would land in databases nobody reads. A test wants a file under t.TempDir(), or memstore.

func (*Store) ClearFailedLoginAttempts

func (s *Store) ClearFailedLoginAttempts(ctx context.Context, email string) error

func (*Store) Close

func (s *Store) Close() error

Close closes the database if Open opened it, and does nothing if the host handed it to New.

func (*Store) ConsumeRefreshToken added in v0.6.0

func (s *Store) ConsumeRefreshToken(ctx context.Context, id string) (bool, error)

func (*Store) ConsumeSuperuserRefreshToken added in v0.6.0

func (s *Store) ConsumeSuperuserRefreshToken(ctx context.Context, id string) (bool, error)

func (*Store) ConsumeWebAuthnChallenge

func (s *Store) ConsumeWebAuthnChallenge(ctx context.Context, tokenHash string) (*store.WebAuthnChallenge, error)

ConsumeWebAuthnChallenge lets the DELETE decide, so two redemptions of one challenge cannot both get the row.

func (*Store) CountRecentFailedLoginAttempts

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

func (*Store) CountSuperusers

func (s *Store) CountSuperusers(ctx context.Context) (int, error)

func (*Store) CreateAccount

func (s *Store) CreateAccount(ctx context.Context, a *store.Account) error

func (*Store) CreateBoundDevice added in v0.7.0

func (s *Store) CreateBoundDevice(ctx context.Context, d *store.BoundDevice) error

func (*Store) CreateDeviceAuthorization added in v0.7.0

func (s *Store) CreateDeviceAuthorization(ctx context.Context, d *store.DeviceAuthorization) error

func (*Store) CreateEmailLoginToken

func (s *Store) CreateEmailLoginToken(ctx context.Context, t *store.EmailLoginToken) error

func (*Store) CreateEmailVerificationToken

func (s *Store) CreateEmailVerificationToken(ctx context.Context, t *store.EmailVerificationToken) error

func (*Store) CreateInvitation added in v0.7.0

func (s *Store) CreateInvitation(ctx context.Context, i *store.Invitation) error

func (*Store) CreateMember added in v0.7.0

func (s *Store) CreateMember(ctx context.Context, m *store.Member) error

func (*Store) CreatePasswordResetToken

func (s *Store) CreatePasswordResetToken(ctx context.Context, t *store.PasswordResetToken) error

func (*Store) CreatePendingTwoFactorSession

func (s *Store) CreatePendingTwoFactorSession(ctx context.Context, p *store.PendingTwoFactorSession) error

func (*Store) CreatePersonalAccessToken added in v0.7.0

func (s *Store) CreatePersonalAccessToken(ctx context.Context, t *store.PersonalAccessToken) error

func (*Store) CreateRefreshToken

func (s *Store) CreateRefreshToken(ctx context.Context, t *store.RefreshToken) error

func (*Store) CreateSuperuser

func (s *Store) CreateSuperuser(ctx context.Context, su *store.Superuser) error

func (*Store) CreateSuperuserPendingTwoFactorSession

func (s *Store) CreateSuperuserPendingTwoFactorSession(ctx context.Context, p *store.PendingTwoFactorSession) error

func (*Store) CreateSuperuserRefreshToken

func (s *Store) CreateSuperuserRefreshToken(ctx context.Context, t *store.SuperuserRefreshToken) error

func (*Store) CreateSuperuserTOTPSettings

func (s *Store) CreateSuperuserTOTPSettings(ctx context.Context, t *store.TOTPSettings) error

func (*Store) CreateTOTPSettings

func (s *Store) CreateTOTPSettings(ctx context.Context, t *store.TOTPSettings) error

func (*Store) CreateTeam added in v0.7.0

func (s *Store) CreateTeam(ctx context.Context, t *store.Team) error

func (*Store) CreateUser

func (s *Store) CreateUser(ctx context.Context, u *store.User) error

func (*Store) CreateWebAuthnChallenge

func (s *Store) CreateWebAuthnChallenge(ctx context.Context, c *store.WebAuthnChallenge) error

func (*Store) CreateWebAuthnCredential

func (s *Store) CreateWebAuthnCredential(ctx context.Context, c *store.WebAuthnCredential) error

func (*Store) DB

func (s *Store) DB() *sql.DB

DB exposes the handle, for an app keeping its own tables in the same file.

func (*Store) DeleteAccount

func (s *Store) DeleteAccount(ctx context.Context, id string) error

func (*Store) DeleteDeviceAuthorization added in v0.7.0

func (s *Store) DeleteDeviceAuthorization(ctx context.Context, id string) error

DeleteDeviceAuthorization succeeds for a row that is already gone: the device package deletes a resolved authorization and ignores the result.

func (*Store) DeleteEmailLoginTokens

func (s *Store) DeleteEmailLoginTokens(ctx context.Context, email string, kind store.EmailLoginKind) error

func (*Store) DeleteMember added in v0.7.0

func (s *Store) DeleteMember(ctx context.Context, id string) error

func (*Store) DeletePINCredential added in v0.7.0

func (s *Store) DeletePINCredential(ctx context.Context, userID string) error

func (*Store) DeletePendingTwoFactorSession

func (s *Store) DeletePendingTwoFactorSession(ctx context.Context, id string) error

func (*Store) DeleteSuperuserPendingTwoFactorSession

func (s *Store) DeleteSuperuserPendingTwoFactorSession(ctx context.Context, id string) error

func (*Store) DeleteSuperuserTOTPSettings

func (s *Store) DeleteSuperuserTOTPSettings(ctx context.Context, superuserID string) error

func (*Store) DeleteTOTPSettings

func (s *Store) DeleteTOTPSettings(ctx context.Context, userID string) error

func (*Store) DeleteTeam added in v0.7.0

func (s *Store) DeleteTeam(ctx context.Context, id string) error

DeleteTeam takes the team's members and invitations with it.

func (*Store) DeleteUserEmailVerificationTokens

func (s *Store) DeleteUserEmailVerificationTokens(ctx context.Context, userID string) error

func (*Store) DeleteUserPasswordResetTokens

func (s *Store) DeleteUserPasswordResetTokens(ctx context.Context, userID string) error

func (*Store) DeleteWebAuthnCredential

func (s *Store) DeleteWebAuthnCredential(ctx context.Context, id string) error

func (*Store) GetAccount

func (s *Store) GetAccount(ctx context.Context, id string) (*store.Account, error)

func (*Store) GetAccountByProvider

func (s *Store) GetAccountByProvider(ctx context.Context, provider, providerAccountID string) (*store.Account, error)

func (*Store) GetBoundDevice added in v0.7.0

func (s *Store) GetBoundDevice(ctx context.Context, id string) (*store.BoundDevice, error)

func (*Store) GetBoundDeviceByTokenHash added in v0.7.0

func (s *Store) GetBoundDeviceByTokenHash(ctx context.Context, hash string) (*store.BoundDevice, error)

GetBoundDeviceByTokenHash returns revoked and expired devices too: the service reads both columns itself.

func (*Store) GetDeviceAuthorizationByDeviceCodeHash added in v0.7.0

func (s *Store) GetDeviceAuthorizationByDeviceCodeHash(ctx context.Context, hash string) (*store.DeviceAuthorization, error)

func (*Store) GetDeviceAuthorizationByUserCode added in v0.7.0

func (s *Store) GetDeviceAuthorizationByUserCode(ctx context.Context, userCode string) (*store.DeviceAuthorization, error)

func (*Store) GetEmailLoginTokenByEmail

func (s *Store) GetEmailLoginTokenByEmail(ctx context.Context, email string, kind store.EmailLoginKind) (*store.EmailLoginToken, error)

func (*Store) GetEmailLoginTokenByHash

func (s *Store) GetEmailLoginTokenByHash(ctx context.Context, hash string) (*store.EmailLoginToken, error)

func (*Store) GetEmailVerificationTokenByHash

func (s *Store) GetEmailVerificationTokenByHash(ctx context.Context, hash string) (*store.EmailVerificationToken, error)

func (*Store) GetInvitation added in v0.7.0

func (s *Store) GetInvitation(ctx context.Context, id string) (*store.Invitation, error)

func (*Store) GetInvitationByTokenHash added in v0.7.0

func (s *Store) GetInvitationByTokenHash(ctx context.Context, hash string) (*store.Invitation, error)

GetInvitationByTokenHash returns every status, not only pending: the service reads Status to refuse a revoked or accepted invitation.

func (*Store) GetMember added in v0.7.0

func (s *Store) GetMember(ctx context.Context, id string) (*store.Member, error)

func (*Store) GetMemberByUserAndTeam added in v0.7.0

func (s *Store) GetMemberByUserAndTeam(ctx context.Context, userID, teamID string) (*store.Member, error)

GetMemberByUserAndTeam never matches a member without a user: the equality is false against NULL.

func (*Store) GetPINCredential added in v0.7.0

func (s *Store) GetPINCredential(ctx context.Context, userID string) (*store.PINCredential, error)

func (*Store) GetPasswordResetTokenByHash

func (s *Store) GetPasswordResetTokenByHash(ctx context.Context, hash string) (*store.PasswordResetToken, error)

func (*Store) GetPendingTwoFactorSessionByHash

func (s *Store) GetPendingTwoFactorSessionByHash(ctx context.Context, hash string) (*store.PendingTwoFactorSession, error)

func (*Store) GetPersonalAccessToken added in v0.7.0

func (s *Store) GetPersonalAccessToken(ctx context.Context, id string) (*store.PersonalAccessToken, error)

func (*Store) GetPersonalAccessTokenByHash added in v0.7.0

func (s *Store) GetPersonalAccessTokenByHash(ctx context.Context, hash string) (*store.PersonalAccessToken, error)

GetPersonalAccessTokenByHash returns revoked and expired tokens too: the service reads both columns itself.

func (*Store) GetRefreshTokenByHash

func (s *Store) GetRefreshTokenByHash(ctx context.Context, hash string) (*store.RefreshToken, error)

func (*Store) GetSuperuserByEmail

func (s *Store) GetSuperuserByEmail(ctx context.Context, email string) (*store.Superuser, error)

func (*Store) GetSuperuserByID

func (s *Store) GetSuperuserByID(ctx context.Context, id string) (*store.Superuser, error)

func (*Store) GetSuperuserPendingTwoFactorSessionByHash

func (s *Store) GetSuperuserPendingTwoFactorSessionByHash(ctx context.Context, hash string) (*store.PendingTwoFactorSession, error)

func (*Store) GetSuperuserRefreshTokenByHash

func (s *Store) GetSuperuserRefreshTokenByHash(ctx context.Context, hash string) (*store.SuperuserRefreshToken, error)

func (*Store) GetSuperuserTOTPSettings

func (s *Store) GetSuperuserTOTPSettings(ctx context.Context, superuserID string) (*store.TOTPSettings, error)

func (*Store) GetTOTPSettingsByUserID

func (s *Store) GetTOTPSettingsByUserID(ctx context.Context, userID string) (*store.TOTPSettings, error)

func (*Store) GetTeam added in v0.7.0

func (s *Store) GetTeam(ctx context.Context, id string) (*store.Team, error)

func (*Store) GetTeamBySlug added in v0.7.0

func (s *Store) GetTeamBySlug(ctx context.Context, slug string) (*store.Team, error)

func (*Store) GetUserByEmail

func (s *Store) GetUserByEmail(ctx context.Context, email string) (*store.User, error)

func (*Store) GetUserByID

func (s *Store) GetUserByID(ctx context.Context, id string) (*store.User, error)

func (*Store) GetWebAuthnCredential

func (s *Store) GetWebAuthnCredential(ctx context.Context, id string) (*store.WebAuthnCredential, error)

func (*Store) GetWebAuthnCredentialByCredentialID

func (s *Store) GetWebAuthnCredentialByCredentialID(ctx context.Context, credentialID []byte) (*store.WebAuthnCredential, error)

func (*Store) IncrementEmailLoginTokenAttempts

func (s *Store) IncrementEmailLoginTokenAttempts(ctx context.Context, id string) (int, error)

IncrementEmailLoginTokenAttempts lets the database compute the count, so parallel guesses each cost one.

func (*Store) IsAccountLocked

func (s *Store) IsAccountLocked(ctx context.Context, userID string) (bool, error)

func (*Store) ListAccountsByUser

func (s *Store) ListAccountsByUser(ctx context.Context, userID string) ([]*store.Account, error)

func (*Store) ListActiveRefreshTokens

func (s *Store) ListActiveRefreshTokens(ctx context.Context, userID string) ([]*store.RefreshToken, error)

func (*Store) ListActiveSuperuserRefreshTokens

func (s *Store) ListActiveSuperuserRefreshTokens(ctx context.Context, superuserID string) ([]*store.SuperuserRefreshToken, error)

func (*Store) ListBoundDevicesByUser added in v0.7.0

func (s *Store) ListBoundDevicesByUser(ctx context.Context, userID string) ([]*store.BoundDevice, error)

func (*Store) ListInvitationsByTeam added in v0.7.0

func (s *Store) ListInvitationsByTeam(ctx context.Context, teamID string) ([]*store.Invitation, error)

func (*Store) ListMembersByTeam added in v0.7.0

func (s *Store) ListMembersByTeam(ctx context.Context, teamID string) ([]*store.Member, error)

ListMembersByTeam lists every member, active or not, since the last-owner check reads Role and IsActive itself. Inside a transaction it needs no lock of its own: the transaction already holds SQLite's write lock, so that check and the write it guards cannot interleave with another.

func (*Store) ListMembershipsByUser added in v0.7.0

func (s *Store) ListMembershipsByUser(ctx context.Context, userID string) ([]*store.Member, error)

func (*Store) ListPersonalAccessTokensByUser added in v0.7.0

func (s *Store) ListPersonalAccessTokensByUser(ctx context.Context, userID string) ([]*store.PersonalAccessToken, error)

func (*Store) ListSuperusers

func (s *Store) ListSuperusers(ctx context.Context) ([]*store.Superuser, error)

func (*Store) ListWebAuthnCredentialsByUser

func (s *Store) ListWebAuthnCredentialsByUser(ctx context.Context, userID string) ([]*store.WebAuthnCredential, error)

func (*Store) LockAccount

func (s *Store) LockAccount(ctx context.Context, userID string) error

func (*Store) MarkEmailLoginTokenUsed

func (s *Store) MarkEmailLoginTokenUsed(ctx context.Context, id string, usedAt time.Time) error

MarkEmailLoginTokenUsed is a compare-and-set: no row means another redemption won.

func (*Store) MarkEmailVerificationTokenUsed

func (s *Store) MarkEmailVerificationTokenUsed(ctx context.Context, id string) error

func (*Store) MarkPasswordResetTokenUsed

func (s *Store) MarkPasswordResetTokenUsed(ctx context.Context, id string) error

func (*Store) RecordFailedLoginAttempt

func (s *Store) RecordFailedLoginAttempt(ctx context.Context, a *store.FailedLoginAttempt) error

func (*Store) RevokeAllBoundDevices added in v0.7.0

func (s *Store) RevokeAllBoundDevices(ctx context.Context, userID string, at time.Time) (int, error)

func (*Store) RevokeAllSuperuserRefreshTokens

func (s *Store) RevokeAllSuperuserRefreshTokens(ctx context.Context, superuserID string) error

func (*Store) RevokeAllUserRefreshTokens

func (s *Store) RevokeAllUserRefreshTokens(ctx context.Context, userID string) error

func (*Store) RevokeBoundDevice added in v0.7.0

func (s *Store) RevokeBoundDevice(ctx context.Context, id string, at time.Time) error

func (*Store) RevokeRefreshToken

func (s *Store) RevokeRefreshToken(ctx context.Context, id string) error

func (*Store) RevokeSuperuserRefreshToken

func (s *Store) RevokeSuperuserRefreshToken(ctx context.Context, id string) error

func (*Store) RunInTx

func (s *Store) RunInTx(ctx context.Context, fn func(ctx context.Context) error) (err error)

RunInTx runs fn in one transaction. store.TxRunner requires every store call made with fn's context to join it, so q reads the transaction back out of the context; a call inside an open transaction joins that one.

func (*Store) SetPINCredential added in v0.7.0

func (s *Store) SetPINCredential(ctx context.Context, c *store.PINCredential) error

SetPINCredential replaces an existing PIN in place, keeping the row's created_at.

func (*Store) TouchBoundDevice added in v0.7.0

func (s *Store) TouchBoundDevice(ctx context.Context, id string, at time.Time) error

TouchBoundDevice does not touch a revoked device, so a use racing a revocation cannot write over it.

func (*Store) TouchRefreshToken

func (s *Store) TouchRefreshToken(ctx context.Context, id string, expiresAt time.Time) error

TouchRefreshToken does not extend a revoked session back to life.

func (*Store) UnlockAccount

func (s *Store) UnlockAccount(ctx context.Context, userID string) error

func (*Store) UpdateAccount

func (s *Store) UpdateAccount(ctx context.Context, a *store.Account) error

func (*Store) UpdateDeviceAuthorization added in v0.7.0

func (s *Store) UpdateDeviceAuthorization(ctx context.Context, d *store.DeviceAuthorization) error

func (*Store) UpdateInvitation added in v0.7.0

func (s *Store) UpdateInvitation(ctx context.Context, i *store.Invitation) error

func (*Store) UpdateMember added in v0.7.0

func (s *Store) UpdateMember(ctx context.Context, m *store.Member) error

func (*Store) UpdatePersonalAccessToken added in v0.7.0

func (s *Store) UpdatePersonalAccessToken(ctx context.Context, t *store.PersonalAccessToken) error

func (*Store) UpdateSuperuser

func (s *Store) UpdateSuperuser(ctx context.Context, su *store.Superuser) error

func (*Store) UpdateSuperuserTOTPSettings

func (s *Store) UpdateSuperuserTOTPSettings(ctx context.Context, t *store.TOTPSettings) error

func (*Store) UpdateTOTPSettings

func (s *Store) UpdateTOTPSettings(ctx context.Context, t *store.TOTPSettings) error

func (*Store) UpdateTeam added in v0.7.0

func (s *Store) UpdateTeam(ctx context.Context, t *store.Team) error

func (*Store) UpdateUser

func (s *Store) UpdateUser(ctx context.Context, u *store.User) error

func (*Store) UpdateWebAuthnCredential

func (s *Store) UpdateWebAuthnCredential(ctx context.Context, c *store.WebAuthnCredential) error

Jump to

Keyboard shortcuts

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