store

package
v0.4.1 Latest Latest
Warning

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

Go to latest
Published: Sep 11, 2026 License: MIT Imports: 5 Imported by: 0

Documentation

Overview

Package store defines the storage boundary of Auth-All. The application owns the database. An adapter implements these capability-oriented interfaces.

Index

Constants

View Source
const (
	MembershipActive    = "active"
	MembershipSuspended = "suspended"
)

The status values of one membership. A suspended membership keeps the row, and it holds no permission.

View Source
const (
	InvitationPending  = "pending"
	InvitationAccepted = "accepted"
	InvitationRevoked  = "revoked"
	InvitationExpired  = "expired"
)

The status values of one invitation.

Variables

View Source
var (
	// ErrNotFound reports that the requested row does not exist.
	ErrNotFound = errors.New("authall/store: not found")
	// ErrConflict reports that a uniqueness constraint rejected the write.
	ErrConflict = errors.New("authall/store: conflict")
	// ErrInvalidCursor reports a page cursor that the store cannot read.
	ErrInvalidCursor = errors.New("authall/store: invalid cursor")
)

Sentinel storage errors.

Functions

This section is empty.

Types

type APIKey added in v0.3.0

type APIKey struct {
	ID     string
	UserID string
	// Name is the label of the owner.
	Name string
	// Start is the prefix and the first characters of the random part. A list
	// shows it, so a person recognizes the key.
	Start string
	// KeyHash is the SHA-256 hex digest of the plaintext key.
	KeyHash string
	// Role is the role of the key at creation. The effective role is the lower
	// of this role and the current role of the owner.
	Role string
	// OrgID names the organization of the key. A nil value means a key of the
	// whole application. The permissions of an organization key are the
	// intersection of the key permissions and the live permissions of the
	// owner in that organization.
	OrgID      *string
	CreatedAt  time.Time
	ExpiresAt  *time.Time
	LastUsedAt *time.Time
	RevokedAt  *time.Time
	RevokedBy  *string
}

APIKey is one machine credential of a user. The plaintext key exists only in the response of the create route. The store keeps the digest.

type APIKeyStore added in v0.3.0

type APIKeyStore interface {
	// CreateAPIKey inserts one key. It returns ErrConflict when the digest
	// exists already.
	CreateAPIKey(ctx context.Context, k *APIKey) error
	// APIKeyByHash returns the key of one digest and its owner in one round
	// trip. It returns ErrNotFound when no key matches.
	APIKeyByHash(ctx context.Context, keyHash string) (*APIKey, *User, error)
	// APIKeyByID returns one key by identifier.
	APIKeyByID(ctx context.Context, id string) (*APIKey, error)
	// ListAPIKeys returns every key of one owner, and the newest comes first.
	ListAPIKeys(ctx context.Context, userID string) ([]APIKey, error)
	// RevokeAPIKey ends one key. It returns ErrNotFound when the key is
	// already revoked or absent.
	RevokeAPIKey(ctx context.Context, id, byUserID string, at time.Time) error
	// TouchAPIKey writes the last use time of one key.
	TouchAPIKey(ctx context.Context, id string, at time.Time) error
}

APIKeyStore holds the machine credentials of the API keys plugin.

type Account

type Account struct {
	ID                string
	UserID            string
	Provider          string
	ProviderAccountID string
	CreatedAt         time.Time
	UpdatedAt         time.Time
}

Account is one external provider identity owned by a user.

type AccountStore

type AccountStore interface {
	// Create inserts an account. It returns ErrConflict when the provider
	// identity is already linked to a user.
	Create(ctx context.Context, a *Account) error
	GetByProviderAccount(ctx context.Context, provider, providerAccountID string) (*Account, error)
	ListByUser(ctx context.Context, userID string) ([]Account, error)
	// Delete removes one link. It returns ErrNotFound when no link exists.
	Delete(ctx context.Context, userID, provider string) error
}

AccountStore holds external provider identities.

type ActiveOrganizationStore added in v0.4.0

type ActiveOrganizationStore interface {
	// SetActiveOrganization writes the organization of one session. An empty
	// orgID ends the active organization of that session.
	SetActiveOrganization(ctx context.Context, sessionID, orgID string) error
	// ActiveOrganizationOf returns the organization of one session. An empty
	// result means that the session names no organization.
	ActiveOrganizationOf(ctx context.Context, sessionID string) (string, error)
	// ClearActiveOrganization ends the active organization of every session of
	// one user in one organization.
	ClearActiveOrganization(ctx context.Context, orgID, userID string) error
}

ActiveOrganizationStore reads and writes the active organization of a session. The active organization lives in the session row, so every instance reads it, and a revocation removes it with the session.

type CatalogInspector added in v0.3.0

type CatalogInspector interface {
	// TableColumns returns the column names of one table. It returns false when
	// the table is absent.
	TableColumns(ctx context.Context, table string) ([]string, bool, error)
}

CatalogInspector reads the state of the database from the catalog of the engine. A host that applies the exported migrations with its own tool writes no Auth-All record, so the catalog is the only source of truth.

type Credential

type Credential struct {
	UserID       string
	PasswordHash string
	CreatedAt    time.Time
	UpdatedAt    time.Time
}

Credential is the password credential of one user.

type CustomRole added in v0.4.0

type CustomRole struct {
	ID    string
	OrgID string
	Name  string
	// Permissions is the space-separated list of statements.
	Permissions string
	CreatedAt   time.Time
}

CustomRole is one role that an organization defines at run time. It stores its own statements, so a later change of a built-in role never widens it.

type CustomRoleStore added in v0.4.0

type CustomRoleStore interface {
	// CreateCustomRole inserts one role. It returns ErrConflict when the
	// organization already holds a role of that name.
	CreateCustomRole(ctx context.Context, r *CustomRole) error
	// CustomRoleByName returns one role of one organization. It returns
	// ErrNotFound when the organization holds no role of that name.
	CustomRoleByName(ctx context.Context, orgID, name string) (*CustomRole, error)
	// ListCustomRoles returns every role of one organization, ordered by name.
	ListCustomRoles(ctx context.Context, orgID string) ([]CustomRole, error)
	// DeleteCustomRole removes one role. It returns ErrNotFound when the role
	// is absent.
	DeleteCustomRole(ctx context.Context, orgID, name string) error
}

CustomRoleStore holds the custom roles of the organizations plugin.

type ExtraFields added in v0.3.0

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

ExtraFields holds the host-owned fields of one user. The key is the field name.

func NewExtraFields added in v0.3.0

func NewExtraFields(values map[string]any) *ExtraFields

NewExtraFields returns a field set with the given values.

func (*ExtraFields) Get added in v0.3.0

func (e *ExtraFields) Get(name string) (any, bool)

Get returns one value. The second result is false when the field is absent.

func (*ExtraFields) Names added in v0.3.0

func (e *ExtraFields) Names() []string

Names returns every field name in a deterministic order.

func (*ExtraFields) Set added in v0.3.0

func (e *ExtraFields) Set(name string, value any)

Set writes one value.

type Invitation added in v0.4.0

type Invitation struct {
	ID    string
	OrgID string
	// EmailNormalized is the normalized address of the invited person. The
	// acceptance compares it with the address of the signed-in user.
	EmailNormalized string
	Role            string
	InvitedBy       string
	// TokenHash is the SHA-256 hex digest of the token. The plaintext exists
	// one time, in the return value of the invitation.
	TokenHash string
	// Status is one of InvitationPending, InvitationAccepted,
	// InvitationRevoked, and InvitationExpired.
	Status    string
	ExpiresAt time.Time
	CreatedAt time.Time
}

Invitation invites one address into one organization.

type InvitationFilter added in v0.4.0

type InvitationFilter struct {
	OrgID string
	// Status keeps the invitations of one status. A nil value keeps every
	// status.
	Status *string
	Limit  int
	Cursor string
}

InvitationFilter selects and pages the invitations of one organization.

type InvitationStore added in v0.4.0

type InvitationStore interface {
	// CreateInvitation inserts one invitation. It returns ErrConflict when the
	// digest exists already.
	CreateInvitation(ctx context.Context, i *Invitation) error
	// InvitationByTokenHash returns one invitation by its digest. It returns
	// ErrNotFound when no invitation matches.
	InvitationByTokenHash(ctx context.Context, tokenHash string) (*Invitation, error)
	// InvitationByID returns one invitation by its identifier.
	InvitationByID(ctx context.Context, id string) (*Invitation, error)
	// ConsumeInvitation marks one pending and unexpired invitation as
	// accepted, and it returns the row. It returns ErrNotFound when the
	// invitation is unknown, used, revoked, or expired.
	//
	// One statement changes the status, so ten parallel acceptances of one
	// invitation create one membership.
	ConsumeInvitation(ctx context.Context, tokenHash string, now time.Time) (*Invitation, error)
	// SetInvitationStatus writes the status of one invitation. It returns
	// ErrNotFound when the invitation does not hold the expected status.
	SetInvitationStatus(ctx context.Context, id, from, to string) error
	// ListInvitations returns one page of the invitations of one
	// organization, and the cursor of the next page.
	ListInvitations(ctx context.Context, f InvitationFilter) (invitations []Invitation, next string, err error)
	// CountPendingInvitations returns the number of pending and unexpired
	// invitations of one organization.
	CountPendingInvitations(ctx context.Context, orgID string, now time.Time) (int, error)
}

InvitationStore holds the invitations of the organizations plugin.

type MemberFilter added in v0.4.0

type MemberFilter struct {
	OrgID string
	// Role keeps the members of one role. A nil value keeps every role.
	Role *string
	// Status keeps the members of one status. A nil value keeps every status.
	Status *string
	Limit  int
	Cursor string
}

MemberFilter selects and pages the members of one organization.

type Membership added in v0.4.0

type Membership struct {
	ID     string
	OrgID  string
	UserID string
	// Role is a built-in role or a custom role of this organization.
	Role string
	// Status is MembershipActive or MembershipSuspended.
	Status   string
	JoinedAt time.Time
	// Permissions holds the statements that the credential read resolved for
	// this membership, for a custom role and for every custom team role. It is
	// empty for a membership that a plain read returned.
	Permissions string
	// TeamRoles holds the space-separated role names of every team of the
	// member. The effective permission set is the union of the organization
	// role and of every team role.
	TeamRoles string
}

Membership joins one person and one organization.

type MembershipStore added in v0.4.0

type MembershipStore interface {
	// CreateMembership inserts one membership. It returns ErrConflict when the
	// user already holds a membership of that organization.
	CreateMembership(ctx context.Context, m *Membership) error
	// MembershipOf returns the membership of one user in one organization. It
	// returns ErrNotFound when no membership exists.
	MembershipOf(ctx context.Context, orgID, userID string) (*Membership, error)
	// UpdateMembership writes the role and the status of one membership.
	UpdateMembership(ctx context.Context, m *Membership) error
	// DeleteMembership removes one membership. It returns ErrNotFound when no
	// membership exists.
	DeleteMembership(ctx context.Context, orgID, userID string) error
	// ListMembers returns one page of the members of one organization, and the
	// cursor of the next page.
	ListMembers(ctx context.Context, f MemberFilter) (members []Membership, next string, err error)
	// MembershipsOfUser returns every membership of one user.
	MembershipsOfUser(ctx context.Context, userID string) ([]Membership, error)
	// LockActiveMembersWithRole returns the identifiers of the active members
	// of one role in one organization, and it locks the rows until the
	// transaction ends.
	//
	// The caller must run it inside a write transaction. The lock makes the
	// owner guard safe under concurrent requests.
	LockActiveMembersWithRole(ctx context.Context, orgID, role string) ([]string, error)
	// CountMembers returns the number of active members of one organization.
	CountMembers(ctx context.Context, orgID string) (int, error)
}

MembershipStore holds the memberships of the organizations plugin.

type Migrator

type Migrator interface {
	// Dialect reports the SQL flavor of the adapter.
	Dialect() schema.Dialect
	// Plan returns the statements that are not applied yet.
	Plan(ctx context.Context, s *schema.Schema) ([]schema.Statement, error)
	// Apply runs the pending statements and records them.
	Apply(ctx context.Context, s *schema.Schema) ([]schema.Statement, error)
	// Check returns an actionable error when the database schema is missing or
	// outdated.
	Check(ctx context.Context, s *schema.Schema) error
}

Migrator applies the effective schema. It never runs automatically.

type OAuthState

type OAuthState struct {
	ID         string
	StateHash  string
	Provider   string
	Verifier   string
	Nonce      string
	RedirectTo string
	LinkUserID *string
	CreatedAt  time.Time
	ExpiresAt  time.Time
	ConsumedAt *time.Time
}

OAuthState is one pending OAuth authorization request.

type OAuthStateStore

type OAuthStateStore interface {
	Create(ctx context.Context, s *OAuthState) error
	// Consume atomically marks one unconsumed and unexpired state as consumed
	// and returns it.
	Consume(ctx context.Context, stateHash string, now time.Time) (*OAuthState, error)
	DeleteExpired(ctx context.Context, before time.Time) (int, error)
}

OAuthStateStore holds pending OAuth authorization requests.

type Organization added in v0.4.0

type Organization struct {
	ID   string
	Name string
	// Slug is the unique, lowercase name of the organization in a URL.
	Slug      string
	CreatedAt time.Time
	UpdatedAt time.Time
	// Extra holds the host-owned columns of the organizations table.
	Extra *ExtraFields
}

Organization is one tenant of the application.

type OrganizationFilter added in v0.4.0

type OrganizationFilter struct {
	// UserID keeps the organizations of one member. An empty value returns
	// every organization, which the administrative list needs.
	UserID string
	// Limit is the number of returned organizations.
	Limit int
	// Cursor continues an earlier page. An empty value starts at the first
	// organization.
	Cursor string
}

OrganizationFilter selects and pages a list of organizations.

type OrganizationStore added in v0.4.0

type OrganizationStore interface {
	// CreateOrganization inserts one organization. It returns ErrConflict when
	// the slug belongs to another organization.
	CreateOrganization(ctx context.Context, o *Organization) error
	// OrganizationByID returns one organization. It returns ErrNotFound when
	// no organization matches.
	OrganizationByID(ctx context.Context, id string) (*Organization, error)
	// OrganizationBySlug returns one organization by its slug.
	OrganizationBySlug(ctx context.Context, slug string) (*Organization, error)
	// UpdateOrganization writes the name, the slug, the update time, and the
	// host-owned fields. It returns ErrConflict when the slug belongs to
	// another organization, and ErrNotFound when the organization is absent.
	UpdateOrganization(ctx context.Context, o *Organization) error
	// DeleteOrganization removes one organization and every row that belongs
	// to it. The caller runs it inside a write transaction.
	DeleteOrganization(ctx context.Context, id string) error
	// ListOrganizations returns one page and the cursor of the next page. An
	// empty cursor means that no page follows. The order is stable, so no
	// organization repeats and no organization is lost.
	ListOrganizations(ctx context.Context, f OrganizationFilter) (orgs []Organization, next string, err error)
}

OrganizationStore holds the organizations of the organizations plugin.

type RateLimitCounter added in v0.3.0

type RateLimitCounter interface {
	// CountAttempt adds one attempt to the counter of key and returns the new
	// count and the start of the window. It starts a new window when the
	// running window ended before now minus window.
	CountAttempt(ctx context.Context, key string, window time.Duration, now time.Time) (count int, windowStart time.Time, err error)
	// CleanupRateLimits removes every counter whose window ended before the
	// given time. It returns the number of removed rows.
	CleanupRateLimits(ctx context.Context, before time.Time) (int, error)
}

RateLimitCounter keeps the rate-limit counters of the store-backed limiter. One statement counts one attempt, so the count is atomic across instances.

type RecoveryCodeStore added in v0.2.0

type RecoveryCodeStore interface {
	// ReplaceAll removes every code of the user and writes the supplied
	// hashes. It runs in one transaction, so a failure never leaves the user
	// with no codes.
	ReplaceAll(ctx context.Context, userID string, hashes []string) error
	// Consume removes one code of one user and reports whether a row matched.
	//
	// The match and the removal are one atomic operation. Two concurrent calls
	// that carry the same code must produce at most one true, because a
	// recovery code carries a complete sign-in.
	//
	// An unknown code reports false and no error.
	Consume(ctx context.Context, userID, codeHash string) (bool, error)
	// CountByUser returns the number of unused codes of one user.
	CountByUser(ctx context.Context, userID string) (int, error)
	// DeleteByUser removes every code of one user and returns the count.
	DeleteByUser(ctx context.Context, userID string) (int, error)
}

RecoveryCodeStore holds the recovery codes of the second factor.

A recovery code is a first factor and a second factor at once, so the store keeps only the SHA-256 hash. A recovery code carries about 49 bits from a random source, so it needs no slow password hash.

type RowDeleter added in v0.4.0

type RowDeleter interface {
	// DeleteRows removes every row of table whose column holds value. It
	// returns the number of removed rows.
	DeleteRows(ctx context.Context, table, column string, value any) (int, error)
}

RowDeleter removes the rows of one table that hold one value in one column. A plugin uses it to remove its own rows in the transaction of another operation, for example the deletion of an organization.

The caller must supply a fixed table name and a fixed column name, and no value from a request, so the statement carries no injected SQL.

type RowWriter added in v0.3.0

type RowWriter interface {
	// InsertRow inserts one row. It returns ErrConflict when a uniqueness
	// constraint refuses the row.
	InsertRow(ctx context.Context, table string, columns []string, values []any) error
}

RowWriter writes one row of a table that a plugin owns. A plugin uses it for a small table that needs no typed store, for example the bootstrap guard.

The caller must supply a fixed column list and no value from a request, so the statement carries no injected SQL.

type SchemaConfigurable added in v0.3.0

type SchemaConfigurable interface {
	// UseSchema sets the physical names and types. It reports an error when the
	// store cannot serve the options.
	UseSchema(o schema.Options) error
}

SchemaConfigurable accepts the physical schema options of the host. Auth-All calls it during construction when the host uses a table prefix or another identifier type.

type Session

type Session struct {
	ID         string
	UserID     string
	TokenHash  string
	CreatedAt  time.Time
	ExpiresAt  time.Time
	LastSeenAt time.Time
}

Session is one database-backed opaque session. TokenHash never holds a plaintext token.

type SessionOrgReader added in v0.4.0

type SessionOrgReader interface {
	// SessionWithUserAndMembership returns the session of a token hash, its
	// user, the active organization, and the membership. The organization and
	// the membership are nil when the session names no organization, or when
	// the membership is gone.
	SessionWithUserAndMembership(ctx context.Context, tokenHash string) (*Session, *User, *Organization, *Membership, error)
}

SessionOrgReader reads a session, its user, the active organization, and the membership of that organization in one round trip. A permission check then costs no extra store access.

type SessionRevoker added in v0.3.0

type SessionRevoker interface {
	// DeleteSessionsExcept removes every session of the owner of sessionID,
	// except that session. It returns the number of removed sessions, and it
	// returns zero when the session does not exist.
	DeleteSessionsExcept(ctx context.Context, sessionID string) (int, error)
}

SessionRevoker revokes the other sessions of one owner in one statement.

type SessionStore

type SessionStore interface {
	Create(ctx context.Context, s *Session) error
	GetByTokenHash(ctx context.Context, tokenHash string) (*Session, error)
	// ListByUser returns every session of one user, and the newest comes
	// first. It returns an empty result for a user without a session.
	ListByUser(ctx context.Context, userID string) ([]Session, error)
	// Touch updates last_seen_at. It returns ErrNotFound when the session no
	// longer exists, so a revoked session cannot be resurrected.
	Touch(ctx context.Context, id string, at time.Time) error
	Delete(ctx context.Context, id string) error
	DeleteByUser(ctx context.Context, userID string) (int, error)
	DeleteExpired(ctx context.Context, before time.Time) (int, error)
}

SessionStore holds database-backed sessions.

type SessionUserReader added in v0.3.0

type SessionUserReader interface {
	// SessionWithUser returns the session of a token hash and its user. It
	// returns ErrNotFound when no session matches.
	SessionWithUser(ctx context.Context, tokenHash string) (*Session, *User, error)
}

SessionUserReader reads a session and its user in one round trip. A store that does not implement it costs one more round trip for each request.

type Store

type Store interface {
	Users() UserStore
	Accounts() AccountStore
	Sessions() SessionStore
	Tokens() TokenStore
	OAuthStates() OAuthStateStore
	TOTP() TOTPStore
	RecoveryCodes() RecoveryCodeStore

	// Transaction runs fn inside one database transaction. The Store passed to
	// fn performs every operation inside that transaction.
	Transaction(ctx context.Context, fn func(Store) error) error

	// Migrator returns the schema migrator of the adapter.
	Migrator() Migrator

	// Close releases adapter resources. It does not close a database handle
	// owned by the application.
	Close() error
}

Store is the storage boundary of Auth-All.

type TOTP added in v0.2.0

type TOTP struct {
	UserID string
	Secret string
	// ConfirmedAt is nil until the user proves one code. An unconfirmed
	// enrolment never authenticates a sign-in.
	ConfirmedAt *time.Time
	// LastStep is the last accepted time step. The sign-in gate refuses a step
	// that is not greater than this value, which stops a replay of one code
	// inside its own window.
	LastStep  int64
	CreatedAt time.Time
	UpdatedAt time.Time
}

TOTP is the time-based one-time password enrolment of one user.

Secret holds the base32 shared secret. Auth-All does not encrypt it, because Auth-All holds no application key, and a key that the library invents lives in the same database as the secret. An application that needs encryption at rest applies it at the column or at the volume.

type TOTPStore added in v0.2.0

type TOTPStore interface {
	// Get returns the enrolment of one user. It returns ErrNotFound when the
	// user holds no secret.
	Get(ctx context.Context, userID string) (*TOTP, error)
	// Upsert writes the enrolment of one user and replaces any existing row.
	// A replacement clears the confirmation and the last step, because a new
	// secret starts a new enrolment.
	Upsert(ctx context.Context, t *TOTP) error
	// Confirm marks the enrolment of one user as proven. It returns
	// ErrNotFound when the user holds no secret.
	Confirm(ctx context.Context, userID string, at time.Time) error
	// AdvanceStep records step when it is greater than the stored step, and
	// reports whether the write happened.
	//
	// The comparison and the write are one atomic operation. Two concurrent
	// calls that carry the same step must produce at most one true, because a
	// read followed by a later write would let an attacker replay one stolen
	// code across parallel requests.
	//
	// It returns ErrNotFound when the user holds no secret.
	AdvanceStep(ctx context.Context, userID string, step int64) (bool, error)
	// Delete removes the enrolment of one user. It returns ErrNotFound when
	// the user holds no secret.
	Delete(ctx context.Context, userID string) error
}

TOTPStore holds the TOTP enrolment of each user.

type Team added in v0.4.0

type Team struct {
	ID    string
	OrgID string
	Name  string
	// Role is the role of the team. An empty value carries no permission.
	Role      string
	CreatedAt time.Time
}

Team groups members inside one organization.

type TeamStore added in v0.4.0

type TeamStore interface {
	// CreateTeam inserts one team. It returns ErrConflict when the
	// organization already holds a team of that name.
	CreateTeam(ctx context.Context, t *Team) error
	// TeamByID returns one team. It returns ErrNotFound when no team matches.
	TeamByID(ctx context.Context, id string) (*Team, error)
	// ListTeams returns every team of one organization, ordered by name.
	ListTeams(ctx context.Context, orgID string) ([]Team, error)
	// DeleteTeam removes one team and its team memberships. The organization
	// memberships stay.
	DeleteTeam(ctx context.Context, id string) error
	// AddTeamMember puts one user in one team. It returns ErrConflict when the
	// user is already a member of that team.
	AddTeamMember(ctx context.Context, teamID, userID string) error
	// RemoveTeamMember takes one user out of one team.
	RemoveTeamMember(ctx context.Context, teamID, userID string) error
	// ListTeamMembers returns the identifiers of the members of one team.
	ListTeamMembers(ctx context.Context, teamID string) ([]string, error)
	// TeamsOfUser returns every team of one user in one organization.
	TeamsOfUser(ctx context.Context, orgID, userID string) ([]Team, error)
}

TeamStore holds the teams of the organizations plugin.

type Token

type Token struct {
	ID         string
	UserID     *string
	Kind       string
	Identifier string
	TokenHash  string
	CreatedAt  time.Time
	ExpiresAt  time.Time
	ConsumedAt *time.Time
}

Token is one one-time token. TokenHash never holds a plaintext token.

type TokenStore

type TokenStore interface {
	Create(ctx context.Context, t *Token) error
	// Consume atomically marks one unconsumed and unexpired token as consumed
	// and returns it. Two concurrent calls for the same token must produce at
	// most one success. It returns ErrNotFound otherwise.
	Consume(ctx context.Context, kind, tokenHash string, now time.Time) (*Token, error)
	// Get returns a token without consuming it.
	Get(ctx context.Context, kind, tokenHash string) (*Token, error)
	// DeleteByIdentifier removes every outstanding token of one kind for one
	// identifier.
	DeleteByIdentifier(ctx context.Context, kind, identifier string) error
	DeleteExpired(ctx context.Context, before time.Time) (int, error)
}

TokenStore holds one-time tokens.

type User

type User struct {
	ID              string
	Email           string
	EmailNormalized string
	EmailVerifiedAt *time.Time
	DisplayName     string
	ImageURL        string
	CreatedAt       time.Time
	UpdatedAt       time.Time
	// Role is the role name of the user. An empty value means the default role
	// of the roles plugin.
	Role string
	// DisabledAt blocks sign-in and every credential of the user when it is
	// not nil.
	DisabledAt *time.Time
	// MustChangePassword blocks every protected route until the user sets a
	// new password.
	MustChangePassword bool
	// Extra holds the host-owned user fields. It is nil when the host declared
	// no field.
	//
	// The field is a pointer, so a User value stays comparable. A v1
	// application that compares two users keeps its behavior.
	Extra *ExtraFields
}

User is one Auth-All user.

type UserAdminStore added in v0.3.0

type UserAdminStore interface {
	// ListUsers returns one page of users and the cursor of the next page. An
	// empty cursor means that no page follows. The order is stable, so no user
	// repeats and no user is lost.
	ListUsers(ctx context.Context, f UserListFilter) (users []User, next string, err error)
	// LockEnabledUsersWithRole returns the identifiers of the enabled users of
	// one role and locks the rows until the transaction ends.
	//
	// The caller must run it inside a write transaction. The lock makes the
	// last-admin guard safe under concurrent requests.
	LockEnabledUsersWithRole(ctx context.Context, role string) ([]string, error)
}

UserAdminStore reads and locks the users of an administrative operation.

type UserListFilter added in v0.3.0

type UserListFilter struct {
	// EmailPrefix keeps the users whose normalized email starts with the
	// value.
	EmailPrefix string
	// Role keeps the users of one role. A nil value keeps every role. An
	// empty string keeps the users whose role column is empty.
	Role *string
	// Disabled keeps the disabled users when it is true, and the enabled
	// users when it is false. A nil value keeps both.
	Disabled *bool
	// Limit is the number of returned users.
	Limit int
	// Cursor continues an earlier page. An empty value starts at the first
	// user.
	Cursor string
}

UserListFilter selects and pages the users of an administrative list.

type UserStore

type UserStore interface {
	// Create inserts a user. It returns ErrConflict when the normalized email
	// is already taken.
	Create(ctx context.Context, u *User) error
	GetByID(ctx context.Context, id string) (*User, error)
	GetByNormalizedEmail(ctx context.Context, normalized string) (*User, error)
	// Update writes the mutable user fields.
	Update(ctx context.Context, u *User) error
	// Delete removes a user and every owned row.
	Delete(ctx context.Context, id string) error

	GetCredential(ctx context.Context, userID string) (*Credential, error)
	// SetCredential inserts or replaces the password credential of a user.
	SetCredential(ctx context.Context, c *Credential) error
	DeleteCredential(ctx context.Context, userID string) error
}

UserStore holds users and password credentials.

Directories

Path Synopsis
Package postgres provides the PostgreSQL storage adapter for Auth-All.
Package postgres provides the PostgreSQL storage adapter for Auth-All.
Package sqlite provides the SQLite storage adapter for Auth-All.
Package sqlite provides the SQLite storage adapter for Auth-All.
Package storetest holds the behavioral contract suite that every Auth-All storage adapter must pass.
Package storetest holds the behavioral contract suite that every Auth-All storage adapter must pass.

Jump to

Keyboard shortcuts

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