plugin

package
v0.3.0 Latest Latest
Warning

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

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

Documentation

Overview

Package plugin is the public extension surface of Auth-All.

A plugin contributes HTTP routes, schema tables, lifecycle hooks, and OpenAPI operations. A plugin reaches Auth-All only through the Services interface. The official Magic Link plugin uses this package and nothing else, so a third-party plugin has the same capabilities.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type CreateUserInput

type CreateUserInput struct {
	Email       string
	DisplayName string
	ImageURL    string
	// EmailVerified marks the address as proven by the calling flow.
	EmailVerified bool
}

CreateUserInput describes a new user.

type CredentialResolver added in v0.3.0

type CredentialResolver interface {
	// Claims reports whether the resolver owns the bearer value. It must look
	// at the shape of the value only, and it must make no database call.
	Claims(bearer string) bool
	// Resolve returns the principal of the bearer value. It returns an error
	// when the credential does not authenticate.
	Resolve(ctx context.Context, bearer string) (*Principal, error)
}

CredentialResolver turns a bearer value into a principal. A plugin registers one with Registry.Resolver.

Auth-All asks each resolver in registration order. When no resolver claims the value, Auth-All treats it as a session token, so every v1 bearer client keeps working.

type HTTPService

type HTTPService interface {
	// CheckOrigin rejects a state-changing request from an untrusted origin.
	CheckOrigin(r *http.Request) error
	// DecodeJSON reads a JSON request body.
	DecodeJSON(r *http.Request, dst any) error
	// WriteJSON writes a JSON response.
	WriteJSON(w http.ResponseWriter, status int, body any)
	// WriteError writes the public error envelope.
	WriteError(w http.ResponseWriter, err error)
	// SafeRedirect returns candidate when it points at a trusted origin, and
	// fallback otherwise.
	SafeRedirect(candidate, fallback string) string
	// ClientIP returns the request IP for rate-limit keys.
	ClientIP(r *http.Request) string
}

HTTPService exposes the request helpers of Auth-All.

type IssueTokenInput

type IssueTokenInput struct {
	// Kind separates token namespaces, for example "magic-link".
	Kind string
	// UserID is optional. A flow for an unknown address leaves it nil.
	UserID *string
	// Identifier is the subject of the token, normally a normalized email.
	Identifier string
	// TTL is the token lifetime.
	TTL time.Duration
	// ReplaceExisting removes outstanding tokens of the same kind and
	// identifier before it issues the new token.
	ReplaceExisting bool
}

IssueTokenInput describes a one-time token.

type MFAService added in v0.2.0

type MFAService interface {
	// Challenge reports whether the user must pass a second factor, and
	// returns a single-use challenge token when so. The caller must issue no
	// session while required is true.
	Challenge(ctx context.Context, user *store.User) (token string, required bool, err error)
	// SetCookie writes the challenge into the short-lived challenge cookie. A
	// redirect flow uses it, because a token in a query parameter reaches the
	// browser history, the server log, and any leaked Referer header.
	SetCookie(w http.ResponseWriter, token string)
	// MarkRedirect adds the marker that tells the application to ask for a
	// code. The marker names no token, so it is safe in a URL.
	MarkRedirect(target string) string
}

MFAService is the second-factor gate.

A plugin that authenticates a user calls Challenge before it issues a session. A user with a live second factor must reach no session until they prove one code, so a plugin that skips this leaves a bypass of the gate.

type PasswordService added in v0.3.0

type PasswordService interface {
	// CheckPassword reports whether a password meets the configured policy.
	CheckPassword(password string) error
	// HashPassword returns the argon2id hash of a password.
	HashPassword(password string) (string, error)
}

PasswordService applies the password policy and the hash parameters of Auth-All, so a plugin writes the same credential as a core route.

type Plugin

type Plugin interface {
	// ID returns the stable plugin identifier.
	ID() string
	// Register contributes routes, schema, hooks, and OpenAPI operations.
	Register(r *Registry) error
}

Plugin is one Auth-All extension.

type Principal added in v0.3.0

type Principal struct {
	// User is the owner of the credential. It must not be nil.
	User *store.User
	// Session is nil for a credential that is no session.
	Session *store.Session
	// APIKey is nil for a session credential.
	APIKey *store.APIKey
	// Role is the effective role of the request.
	Role string
	// Method names the authentication method, for example "api_key".
	Method string
}

Principal is the authenticated caller of one request. A credential resolver returns it. Auth-All copies it into the request context.

type PrincipalService added in v0.3.0

type PrincipalService interface {
	// Current returns the principal of the request context. It returns nil
	// when no middleware authenticated the request.
	Current(ctx context.Context) *Principal
}

PrincipalService reads the principal of one request.

type PrincipalServices added in v0.3.0

type PrincipalServices interface {
	Principals() PrincipalService
}

PrincipalServices exposes the principal service.

type ProtectService added in v0.3.0

type ProtectService interface {
	// Protect refuses a request with no principal, and it refuses an unsafe
	// cross-site request that a cookie authenticated.
	Protect(next http.Handler) http.Handler
}

ProtectService wraps a handler with the Auth-All authentication middleware. The wrapped handler runs the origin check of the host routes.

type Registry

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

Registry receives the contributions of one plugin.

func NewRegistry

func NewRegistry(id string, services Services, hooks *hook.Hooks) *Registry

NewRegistry returns a registry for one plugin. Auth-All calls this during construction.

func (*Registry) ComponentSchemas

func (r *Registry) ComponentSchemas() map[string]*openapi.Schema

ComponentSchemas returns the contributed component schemas.

func (*Registry) Extend added in v0.3.0

func (r *Registry) Extend(e schema.Extension)

Extend adds columns and indexes to a table that another owner declared. The plugin also declares the migration unit that adds them to a database that exists.

func (*Registry) Extensions added in v0.3.0

func (r *Registry) Extensions() []schema.Extension

Extensions returns the contributed table extensions.

func (*Registry) Hooks

func (r *Registry) Hooks() *hook.Hooks

Hooks returns the lifecycle hook registry.

func (*Registry) OpenAPISchema

func (r *Registry) OpenAPISchema(name string, s *openapi.Schema)

OpenAPISchema contributes one reusable component schema.

func (*Registry) PluginID

func (r *Registry) PluginID() string

PluginID returns the identifier of the registering plugin.

func (*Registry) Resolver added in v0.3.0

func (r *Registry) Resolver(c CredentialResolver)

Resolver contributes one credential resolver.

func (*Registry) Resolvers added in v0.3.0

func (r *Registry) Resolvers() []CredentialResolver

Resolvers returns the contributed credential resolvers.

func (*Registry) Route

func (r *Registry) Route(rt Route)

Route contributes one HTTP route.

func (*Registry) Routes

func (r *Registry) Routes() []Route

Routes returns the contributed routes.

func (*Registry) Schema

func (r *Registry) Schema(t schema.Table)

Schema contributes one table to the effective Auth-All schema.

func (*Registry) Services

func (r *Registry) Services() Services

Services returns the Auth-All capabilities available to the plugin.

func (*Registry) Tables

func (r *Registry) Tables() []schema.Table

Tables returns the contributed schema tables.

func (*Registry) Unit added in v0.3.0

func (r *Registry) Unit(u schema.Unit)

Unit contributes one migration unit. A released unit never changes.

func (*Registry) Units added in v0.3.0

func (r *Registry) Units() []schema.Unit

Units returns the contributed migration units.

type RoleConfigurator added in v0.3.0

type RoleConfigurator interface {
	// SetRoles installs the ordered hierarchy and the default role.
	SetRoles(names []string, defaultRole string) error
}

RoleConfigurator installs a role hierarchy in the core. The roles plugin calls it during registration.

type RoleService added in v0.3.0

type RoleService interface {
	// Names returns the roles from the lowest to the highest.
	Names() []string
	// Default returns the role of a user whose role is empty.
	Default() string
	// Rank returns the position of a role. A role that the configuration does
	// not name ranks below every role, so its rank is negative.
	Rank(role string) int
	// AtLeast reports whether role ranks equal to or above min.
	AtLeast(role, min string) bool
}

RoleService reads the configured role hierarchy.

type RoleServices added in v0.3.0

type RoleServices interface {
	Roles() RoleService
}

RoleServices exposes the role service.

type Route

type Route struct {
	// Method is the HTTP method.
	Method string
	// Path is relative to the configured Auth-All base path and starts with /.
	Path string
	// Handler serves the route.
	Handler http.Handler
	// Operation documents the route. A route without an operation stays out of
	// the OpenAPI document and out of the generated client.
	Operation *openapi.Operation
}

Route is one HTTP route contributed by a plugin.

type SchemaService added in v0.3.0

type SchemaService interface {
	// SchemaOptions returns the physical options of the effective schema.
	SchemaOptions() schema.Options
}

SchemaService reports the physical schema options of the instance. A plugin that owns a table uses it, so the table takes the host table prefix.

type Services

type Services interface {
	// Store returns the configured storage adapter.
	Store() store.Store
	// Email returns the configured email sender.
	Email() email.Sender
	// Events returns the observability emitter.
	Events() *events.Emitter
	// Now returns the configured clock.
	Now() time.Time
	// BasePath returns the mounted base path, for example /api/auth.
	BasePath() string
	// BaseURL returns the absolute public base URL of the application.
	BaseURL() string
	// RateLimiter returns the configured limiter. It is never nil.
	RateLimiter() ratelimit.Limiter
	// Logger returns the configured logger.
	Logger() *slog.Logger

	// Users exposes user operations that run the configured hooks.
	Users() UserService
	// Sessions exposes session operations.
	Sessions() SessionService
	// Tokens exposes one-time token operations.
	Tokens() TokenService
	// HTTP exposes the request helpers Auth-All uses for its own routes.
	HTTP() HTTPService
	// MFA exposes the second-factor gate. A plugin that authenticates a user
	// must consult it before it issues a session.
	MFA() MFAService
}

Services is everything Auth-All exposes to a plugin. A plugin gets no other access to Auth-All internals.

type SessionService

type SessionService interface {
	// Issue creates a session for the user and writes the session cookie.
	// Method names the authentication method for hooks and events.
	Issue(ctx context.Context, w http.ResponseWriter, r *http.Request, user *store.User, method string) (*store.Session, error)
	// Current resolves the session of a request. It returns nil values when no
	// valid session exists.
	Current(ctx context.Context, r *http.Request) (*store.Session, *store.User, error)
	// Revoke deletes one session.
	Revoke(ctx context.Context, sessionID string) error
	// RevokeAll deletes every session of one user and returns the count.
	RevokeAll(ctx context.Context, userID string) (int, error)
	// Clear removes the session cookie.
	Clear(w http.ResponseWriter)
}

SessionService exposes session operations.

type TokenService

type TokenService interface {
	Issue(ctx context.Context, in IssueTokenInput) (plaintext string, token *store.Token, err error)
	// Consume atomically consumes a token. Two concurrent calls for the same
	// token produce at most one success.
	Consume(ctx context.Context, kind, plaintext string) (*store.Token, error)
	// Peek returns a token and consumes nothing. It reports an invalid token
	// for a value that is missing, expired, or already consumed.
	//
	// A confirmation page calls Peek, so a repeated page load and a mail
	// scanner that pre-fetches a link do not destroy the token.
	Peek(ctx context.Context, kind, plaintext string) (*store.Token, error)
}

TokenService exposes one-time token operations. The plaintext token exists only in the return value of Issue. Auth-All stores only its hash.

type UserService

type UserService interface {
	ByID(ctx context.Context, id string) (*store.User, error)
	// ByEmail looks a user up by the normalized form of the address.
	ByEmail(ctx context.Context, address string) (*store.User, error)
	// Create inserts a user and runs the user creation hooks.
	Create(ctx context.Context, in CreateUserInput) (*store.User, error)
	// MarkEmailVerified records proven ownership of the user email address. It
	// changes no other row. A passwordless flow calls ProveEmailOwnership
	// instead.
	MarkEmailVerified(ctx context.Context, userID string) error
	// DeleteCredential removes the password credential of a user. It succeeds
	// for a user that has no password credential.
	DeleteCredential(ctx context.Context, userID string) error
	// ProveEmailOwnership records proven control of the address of a user.
	//
	// A passwordless flow calls it after the flow proves that the person
	// controls the address. When the address was not verified yet, somebody can
	// have set a password and started a session before the proof. The method
	// therefore deletes the password credential of the user, revokes every
	// session of the user, and marks the address verified. It performs the
	// three steps in one transaction.
	//
	// The method does nothing for a user whose address is already verified, so
	// a normal repeat sign-in keeps its password and its sessions.
	//
	// A plugin that proves control of an address must call this method before
	// it issues a session.
	ProveEmailOwnership(ctx context.Context, userID string) error
}

UserService exposes user operations.

Jump to

Keyboard shortcuts

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