Help us shape the future of Go! Take the 2026 Go Developer Survey

plugin

package
v1.9.0 Latest Latest
Warning

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

Go to latest
Published: Nov 2, 2026 License: MIT Imports: 30 Imported by: 0

Documentation

Overview

Package plugin: authz.go — shared route-group guards for plugins.

Plugins register their own routes (see RouteProvider), which means each plugin is responsible for gating its own admin and account surfaces. The helpers here package the same chain the core API uses for /v1/admin so a plugin group can't accidentally ship unauthenticated.

Package plugin: contract.go — optional interface a plugin implements when it ships a forge-dashboard contract surface (manifest + handlers).

Plugins that adopt this interface participate in authsome's RegisterContractContributor lifecycle: the extension iterates every plugin after the auth contributor itself registers, invoking RegisterContract on each implementer in the order they were registered with the plugin registry. Order matters when a plugin extends another plugin's pages — register host-owning plugins first.

This is the only way a plugin contributes to the dashboard; its UI ships as a React plugin that calls these intents. Non-implementers are skipped.

Package plugin defines the plugin system for AuthSome v0.5.0. Plugins implement the base Plugin interface and optionally implement any combination of lifecycle and event hook interfaces.

The registry type-caches plugins at registration time so emit calls iterate only over plugins implementing the relevant hook.

Package plugin: tenant_scope.go — the app tenancy boundary, shared between the core API and plugin route groups.

AdminGuard answers "may this caller manage clients?". It cannot answer "is this client one of theirs?", because that is a property of the caller AND a row the handler has not loaded yet. No middleware can see that row, so the second check necessarily lives in handlers. These helpers are what keeps every handler answering it the same way.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AdminGuard

func AdminGuard(engine Engine, action, resource string) []forge.Middleware

AdminGuard returns SessionGuard plus an RBAC permission check, mirroring the core API's /v1/admin chain (middleware.RequireAuth + RequirePermission). Use it for plugin admin groups that manage tenant-wide configuration — OAuth2 clients, SSO connections, provider credentials, billing plans.

The permission check is appended only when the engine implements PermissionChecker. An engine without RBAC still gets session enforcement, which is the property that matters most: the group is never anonymous.

func AssertAppScope

func AssertAppScope(ctx forge.Context, resourceAppID id.AppID) error

AssertAppScope verifies that a loaded resource belongs to the caller's tenant app. It returns a 404 (not 403) on mismatch so the endpoint never discloses the existence of another app's resource. A missing caller app yields 401.

func CallerAppID

func CallerAppID(ctx forge.Context) (id.AppID, bool)

CallerAppID returns the app the authenticated caller is bound to. This is the tenant boundary used to scope app-owned admin resources (webhooks, environments, OAuth2 clients, per-app config) to the caller.

The credential decides: the session's app first, then a machine principal's app. The context app id set by the publishable-key middleware is consulted only when no credential is present (public routes), because a publishable key is public by design and must never move an authenticated caller into another tenant.

func PermissionGuard

func PermissionGuard(engine Engine, action, resource string) []forge.Middleware

PermissionGuard returns just the RBAC permission check, without the session middleware. Use it on individual routes inside a group that already carries SessionGuard — typically to hold mutating routes to a higher bar than the reads they sit beside.

Returns nil when the engine doesn't implement PermissionChecker, so an engine without RBAC falls back to the group's session requirement rather than failing closed on every request.

func PermissionRouteOptions

func PermissionRouteOptions(engine Engine, action, resource string) []forge.RouteOption

PermissionRouteOptions is PermissionGuard adapted to per-route options, for use alongside forge.WithSummary and friends in a route registration.

func ScopedAppID

func ScopedAppID(ctx forge.Context, requested string) (id.AppID, error)

ScopedAppID resolves the caller's tenant app for create/list operations, rejecting any request that explicitly targets a different app than the caller is bound to. A caller may therefore only ever create or enumerate resources within their own app, never one supplied in the request body/query.

func SessionGuard

func SessionGuard(engine Engine) []forge.Middleware

SessionGuard returns the middleware chain that requires a resolved session on every route in a group. Use it for plugin surfaces that act on behalf of the calling user (creating a key for yourself, reading your own billing).

Pair it with forge.WithGroupAuth("session") so the OpenAPI document advertises the requirement alongside the enforcement:

g := router.Group("/v1/things",
    forge.WithGroupAuth("session"),
    forge.WithGroupMiddleware(plugin.SessionGuard(engine)...),
)

Returns nil when engine is nil or exposes no auth registry (minimal test wiring), so tests that construct a bare plugin still register routes.

Types

type AfterMemberAdd

type AfterMemberAdd interface {
	OnAfterMemberAdd(ctx context.Context, m *organization.Member) error
}

AfterMemberAdd is called after a member is added to an organization.

type AfterMemberRemove

type AfterMemberRemove interface {
	OnAfterMemberRemove(ctx context.Context, memberID id.MemberID) error
}

AfterMemberRemove is called after a member is removed from an organization.

type AfterMemberRoleChange

type AfterMemberRoleChange interface {
	OnAfterMemberRoleChange(ctx context.Context, m *organization.Member) error
}

AfterMemberRoleChange is called after a member's role is changed.

type AfterOrgCreate

type AfterOrgCreate interface {
	OnAfterOrgCreate(ctx context.Context, o *organization.Organization) error
}

AfterOrgCreate is called after an organization is created.

type AfterOrgDelete

type AfterOrgDelete interface {
	OnAfterOrgDelete(ctx context.Context, orgID id.OrgID) error
}

AfterOrgDelete is called after an organization is deleted.

type AfterOrgUpdate

type AfterOrgUpdate interface {
	OnAfterOrgUpdate(ctx context.Context, o *organization.Organization) error
}

AfterOrgUpdate is called after an organization is updated.

type AfterPrincipalAuth

type AfterPrincipalAuth interface {
	OnAfterPrincipalAuth(ctx context.Context, a *principal.AuthAttempt, s *session.Session) error
}

AfterPrincipalAuth is called once a non-human caller has a session. Errors are logged and do not fail the request, matching the other After hooks.

type AfterSessionCreate

type AfterSessionCreate interface {
	OnAfterSessionCreate(ctx context.Context, s *session.Session) error
}

AfterSessionCreate is called after a session is created.

type AfterSessionRefresh

type AfterSessionRefresh interface {
	OnAfterSessionRefresh(ctx context.Context, s *session.Session) error
}

AfterSessionRefresh is called after a session token is refreshed.

type AfterSessionRevoke

type AfterSessionRevoke interface {
	OnAfterSessionRevoke(ctx context.Context, sessionID id.SessionID) error
}

AfterSessionRevoke is called after a session is revoked.

type AfterSignIn

type AfterSignIn interface {
	OnAfterSignIn(ctx context.Context, u *user.User, s *session.Session) error
}

AfterSignIn is called after successful authentication.

type AfterSignOut

type AfterSignOut interface {
	OnAfterSignOut(ctx context.Context, sessionID id.SessionID) error
}

AfterSignOut is called after session termination.

type AfterSignUp

type AfterSignUp interface {
	OnAfterSignUp(ctx context.Context, u *user.User, s *session.Session) error
}

AfterSignUp is called after a new account is created.

type AfterUserCreate

type AfterUserCreate interface {
	OnAfterUserCreate(ctx context.Context, u *user.User) error
}

AfterUserCreate is called after a user is created.

type AfterUserDelete

type AfterUserDelete interface {
	OnAfterUserDelete(ctx context.Context, userID id.UserID) error
}

AfterUserDelete is called after a user is deleted.

type AfterUserUpdate

type AfterUserUpdate interface {
	OnAfterUserUpdate(ctx context.Context, u *user.User) error
}

AfterUserUpdate is called after a user is updated.

type AuthMethod

type AuthMethod struct {
	Type     string `json:"type"`     // e.g. "password", "social:google", "passkey", "phone"
	Provider string `json:"provider"` // e.g. "google", "github", "password", "phone"
	Label    string `json:"label"`    // Human-readable label, e.g. "Google (user@gmail.com)"
	LinkedAt string `json:"linked_at,omitempty"`
}

AuthMethod describes a single authentication method linked to a user account.

type AuthMethodContributor

type AuthMethodContributor interface {
	Plugin
	ListUserAuthMethods(ctx context.Context, userID id.UserID) ([]*AuthMethod, error)
}

AuthMethodContributor is implemented by plugins that can report which authentication methods are linked to a user. The engine aggregates these to provide a unified "list auth methods" API.

type AuthMethodUnlinker

type AuthMethodUnlinker interface {
	Plugin
	UnlinkAuthMethod(ctx context.Context, userID id.UserID, provider string) error
	CanUnlink(ctx context.Context, userID id.UserID, provider string) bool
}

AuthMethodUnlinker is optionally implemented by plugins that support unlinking an auth method from a user account.

type BeforeMemberRemove

type BeforeMemberRemove interface {
	OnBeforeMemberRemove(ctx context.Context, m *organization.Member) error
}

BeforeMemberRemove is called before a member is removed from an organization, while the member record can still be read. AfterMemberRemove carries only the id and fires after deletion, so a plugin that needs to know which user left which org has to use this hook.

type BeforePrincipalAuth

type BeforePrincipalAuth interface {
	OnBeforePrincipalAuth(ctx context.Context, a *principal.AuthAttempt) error
}

BeforePrincipalAuth is called before a credential becomes a session for a caller that did not go through sign-in: an API key, a token exchange, a workload JWT.

Returning an error denies the authentication. This is the machine-side counterpart to BeforeSignIn, and it exists because static API key traffic reaches strategy.Authenticate and never fires the sign-in hooks, so every risk plugin was blind to it.

type BeforeSessionCreate

type BeforeSessionCreate interface {
	OnBeforeSessionCreate(ctx context.Context, s *session.Session) error
}

BeforeSessionCreate is called before a session is created.

type BeforeSignIn

type BeforeSignIn interface {
	OnBeforeSignIn(ctx context.Context, req *account.SignInRequest) error
}

BeforeSignIn is called before authentication.

type BeforeSignOut

type BeforeSignOut interface {
	OnBeforeSignOut(ctx context.Context, sessionID id.SessionID) error
}

BeforeSignOut is called before session termination.

type BeforeSignUp

type BeforeSignUp interface {
	OnBeforeSignUp(ctx context.Context, req *account.SignUpRequest) error
}

BeforeSignUp is called before a new account is created.

type BeforeUserCreate

type BeforeUserCreate interface {
	OnBeforeUserCreate(ctx context.Context, u *user.User) error
}

BeforeUserCreate is called before a user is created.

type BeforeUserDelete

type BeforeUserDelete interface {
	OnBeforeUserDelete(ctx context.Context, userID id.UserID) error
}

BeforeUserDelete is called before a user is deleted.

type BeforeUserUpdate

type BeforeUserUpdate interface {
	OnBeforeUserUpdate(ctx context.Context, u *user.User) error
}

BeforeUserUpdate is called before a user is updated.

type ContractContributor

type ContractContributor interface {
	// RegisterContract is called once during engine bootstrap, after the
	// auth contributor's own Register has succeeded. Implementations
	// should:
	//   1. Load and validate their embedded manifest YAML.
	//   2. Register the manifest with reg (which applies any `extends`
	//      blocks against previously-registered contributors).
	//   3. Register every intent handler with d under the manifest's
	//      contributor name.
	//
	// Returning a non-nil error aborts the plugin loop — keep error
	// messages prefixed with the plugin name so the failing plugin is
	// identifiable in startup logs.
	RegisterContract(d *dispatcher.Dispatcher, reg contract.Registry, wreg contract.WardenRegistry, engine Engine) error
}

ContractContributor is implemented by plugins that ship a contract manifest + handler bundle. The signature mirrors authsome's own contract.Register, with the addition of the typed Engine handle so plugins don't have to capture it during OnInit just to wire a contract. The Engine parameter is a plugin.Engine interface; plugins that need the concrete *authsome.Engine for app-resolution helpers can type-assert internally.

type DataExportContributor

type DataExportContributor interface {
	ExportUserData(ctx context.Context, userID id.UserID) (key string, data any, err error)
}

DataExportContributor allows a plugin to contribute data to the GDPR user export. The returned key names the data section (e.g. "organizations") and data is the payload that will be included in the export.

type DispatcherProvider

type DispatcherProvider interface {
	Dispatcher() bridge.Dispatcher
}

DispatcherProvider is optionally implemented by engines that expose a background job queue. A plugin that needs deferred work should fall back to its own goroutine when the host returns nil. *authsome.Engine already satisfies it.

type Engine

type Engine interface {

	// Store returns the aggregate persistence store.
	Store() store.Store
	// DB returns the raw database handle. Returns nil if not set.
	DB() *grove.DB

	// Plugins returns the plugin registry.
	Plugins() *Registry
	// Plugin returns a registered plugin by name, or nil if not found.
	Plugin(name string) Plugin
	// Hooks returns the hook event bus.
	Hooks() *hook.Bus

	// Logger returns the engine's logger.
	Logger() log.Logger

	// Settings returns the dynamic settings manager.
	Settings() *settings.Manager

	// The audit trail is not exposed here on purpose: plugins record through
	// bridge.NewBusChronicle(engine.Hooks()) so every event takes the one
	// enriched path into Chronicle.
	Relay() bridge.EventRelay
	Herald() bridge.Herald
	Mailer() bridge.Mailer
	SMSSender() bridge.SMSSender
	Ledger() bridge.Ledger
	// TokenEncryptor returns the at-rest Encryptor used for sensitive
	// opaque payloads such as third-party OAuth access/refresh tokens.
	// Always non-nil — falls back to bridge.NoopEncryptor when no key
	// is configured (with a startup warning).
	TokenEncryptor() bridge.Encryptor

	// SessionConfigForApp resolves per-app (and optional per-environment)
	// session configuration.
	SessionConfigForApp(ctx context.Context, appID id.AppID, envIDs ...id.EnvironmentID) account.SessionConfig
	// TokenFormatForApp returns the token format configured for an app.
	TokenFormatForApp(appID string) tokenformat.Format
	// CeremonyStore returns the store for short-lived ceremony state.
	CeremonyStore() ceremony.Store
	// APIKeyStore returns the API key store.
	APIKeyStore() apikey.Store
	// DPoPValidator returns the RFC 9449 proof validator. Never nil.
	DPoPValidator() *dpop.Validator
	// DPoPNonceSigner returns the DPoP nonce signer, or nil when no signing
	// secret could be derived.
	DPoPNonceSigner() *dpop.NonceSigner
	// DPoPModeForApp resolves an app's DPoP mode. Fold a per-client value in
	// with dpop.MaxMode; a client value must never lower the app's.
	DPoPModeForApp(ctx context.Context, appID id.AppID) dpop.Mode
	// DPoPNonceRequiredForApp reports whether an app demands a nonce.
	DPoPNonceRequiredForApp(ctx context.Context, appID id.AppID) bool

	// ResolveSessionByToken resolves a session from its opaque token.
	ResolveSessionByToken(ctx context.Context, token string) (*session.Session, error)
	// ResolveUser resolves a user by ID string.
	ResolveUser(ctx context.Context, userID string) (*user.User, error)
	// GetUser fetches a user by typed ID.
	GetUser(ctx context.Context, userID id.UserID) (*user.User, error)
	// RevokeOtherUserSessions ends every session of the user except keep.
	// Plugins call it after a credential change (second factor, passkey) so
	// a session an attacker already holds does not survive the change.
	RevokeOtherUserSessions(ctx context.Context, userID id.UserID, keep id.SessionID) error

	// EnsureDefaultRole assigns the default role to a user if none is set.
	EnsureDefaultRole(ctx context.Context, appID id.AppID, userID id.UserID)

	// ResolvePrincipal resolves any caller, human or otherwise, by ref.
	// Use this rather than ResolveUser when a plugin must work for agents and
	// workloads as well as people.
	ResolvePrincipal(ctx context.Context, ref principal.Ref) (*principal.Principal, error)

	// PrincipalStore returns the principal and delegation store.
	PrincipalStore() principal.Store

	// Can is the chain-aware authorization check. Pass an empty chain for an
	// ordinary single-subject check.
	Can(ctx context.Context, subject principal.Ref, actors principal.Chain,
		action, resource string) (bool, error)

	// AuthMiddleware returns the engine's non-blocking authentication
	// middleware (cookie bridge + session resolver + JWT + strategies).
	// Populates user context when a valid token is present but passes
	// through unauthenticated requests. Applied globally by the extension.
	AuthMiddleware() forge.Middleware

	// AuthRegistry returns the forge auth provider registry. Plugins can:
	// - Register custom auth providers (API keys, SSO, etc.) via Register()
	// - Create blocking middleware via Middleware("session", "api-key")
	// - Use forge.WithGroupAuth("session") for OpenAPI + enforcement
	AuthRegistry() auth.Registry

	// RateLimiter returns the engine's rate limiter. May be nil.
	RateLimiter() ratelimit.Limiter

	// PlatformAppID returns the platform/bootstrap app ID.
	PlatformAppID() id.AppID
	// DefaultAppID returns the configured app ID string.
	DefaultAppID() string
	// BasePath returns the URL prefix for auth routes.
	BasePath() string
}

Engine is the typed interface that plugins receive during OnInit. It exposes the engine's capabilities without importing the concrete authsome.Engine type (which would create an import cycle).

All commonly-used methods are included here so plugins can call them directly instead of ad-hoc type assertions. For specialised capabilities that would cause import cycles (e.g. warden, keysmith, ledger engines), use the optional interfaces below.

type Extensible

type Extensible interface {
	RegisterSubPlugin(sub Plugin) error
}

Extensible allows a plugin to accept sub-plugins.

type LedgerEngineProvider

type LedgerEngineProvider interface {
	LedgerEngine() any
}

LedgerEngineProvider is optionally implemented by engines with a first-class billing/ledger engine.

type LedgerStoreProvider

type LedgerStoreProvider interface {
	LedgerStore() any
}

LedgerStoreProvider is optionally implemented by engines with a ledger store for direct query access.

type MigrationProvider

type MigrationProvider interface {
	MigrationGroups(driverName string) []*migrate.Group
}

MigrationProvider allows a plugin to register its own grove migration groups. The engine collects these groups and passes them to Store.Migrate() so plugin tables are created alongside the core schema. The driverName parameter ("pg", "sqlite", "mongo") lets the plugin return driver-specific migration groups.

type NotificationMapping

type NotificationMapping struct {
	// Template is the Herald template slug (e.g. "billing.payment-failed").
	Template string
	// Channels lists the channels to send on (e.g. ["email", "inapp"]).
	Channels []string
	// Enabled controls whether this mapping is active.
	Enabled bool
}

NotificationMapping describes a hook-to-notification template mapping contributed by an external plugin.

type NotificationMappingContributor

type NotificationMappingContributor interface {
	Plugin
	NotificationMappings() map[string]*NotificationMapping
}

NotificationMappingContributor is implemented by plugins that want to contribute notification template mappings. The notification plugin collects these during initialization to extend its default mappings. Plugin-contributed mappings do not override user-provided config mappings.

type OnInit

type OnInit interface {
	OnInit(ctx context.Context, engine Engine) error
}

OnInit is called during engine initialization. The engine parameter provides typed access to all engine capabilities.

type OnShutdown

type OnShutdown interface {
	OnShutdown(ctx context.Context) error
}

OnShutdown is called during engine shutdown.

type PermissionChecker

type PermissionChecker interface {
	HasPermission(ctx context.Context, userID id.UserID, action, resource string) (bool, error)
}

PermissionChecker is optionally implemented by engines that support RBAC permission checking. Mirrors middleware.PermissionChecker to avoid importing the middleware package from the plugin package.

type Plugin

type Plugin interface {
	Name() string
}

Plugin is the base interface that all plugins must implement.

type PrincipalAuthGateProvider

type PrincipalAuthGateProvider interface {
	PrincipalAuthGate() any
}

PrincipalAuthGateProvider is optionally implemented by engines that score machine callers (API keys, and anything else authenticating without a human sign-in) through the principal-auth hooks before minting a session. Returns any, not a named gate type, so this package does not have to import a specific plugin's interface (which would create an import cycle with a plugin that itself needs the concrete authsome.Engine type, as the apikey plugin does). The consuming plugin type-asserts the result against its own narrow gate interface. *authsome.Engine satisfies it.

type Registry

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

Registry holds registered plugins and dispatches lifecycle events. It type-caches plugins at registration time so emit calls iterate only over plugins implementing the relevant hook.

func NewRegistry

func NewRegistry(logger log.Logger) *Registry

NewRegistry creates a plugin registry with the given logger.

func (*Registry) CollectExportData

func (r *Registry) CollectExportData(ctx context.Context, userID id.UserID) map[string]any

CollectExportData gathers data from all plugins that implement DataExportContributor. The returned map is keyed by each plugin's export key (e.g. "organizations") and contains the exported data.

func (*Registry) CollectMigrationGroups

func (r *Registry) CollectMigrationGroups(driverName string) []*migrate.Group

CollectMigrationGroups gathers migration groups from all plugins that implement MigrationProvider for the given driver name.

func (*Registry) EmitAfterMemberAdd

func (r *Registry) EmitAfterMemberAdd(ctx context.Context, m *organization.Member)

EmitAfterMemberAdd notifies all plugins that implement AfterMemberAdd.

func (*Registry) EmitAfterMemberRemove

func (r *Registry) EmitAfterMemberRemove(ctx context.Context, memberID id.MemberID)

EmitAfterMemberRemove notifies all plugins that implement AfterMemberRemove.

func (*Registry) EmitAfterMemberRoleChange

func (r *Registry) EmitAfterMemberRoleChange(ctx context.Context, m *organization.Member)

EmitAfterMemberRoleChange notifies all plugins that implement AfterMemberRoleChange.

func (*Registry) EmitAfterOrgCreate

func (r *Registry) EmitAfterOrgCreate(ctx context.Context, o *organization.Organization)

EmitAfterOrgCreate notifies all plugins that implement AfterOrgCreate.

func (*Registry) EmitAfterOrgDelete

func (r *Registry) EmitAfterOrgDelete(ctx context.Context, orgID id.OrgID)

EmitAfterOrgDelete notifies all plugins that implement AfterOrgDelete.

func (*Registry) EmitAfterOrgUpdate

func (r *Registry) EmitAfterOrgUpdate(ctx context.Context, o *organization.Organization)

EmitAfterOrgUpdate notifies all plugins that implement AfterOrgUpdate.

func (*Registry) EmitAfterPrincipalAuth

func (r *Registry) EmitAfterPrincipalAuth(ctx context.Context, a *principal.AuthAttempt, s *session.Session)

EmitAfterPrincipalAuth notifies all plugins that implement AfterPrincipalAuth. Errors are logged, never propagated.

func (*Registry) EmitAfterSessionCreate

func (r *Registry) EmitAfterSessionCreate(ctx context.Context, s *session.Session)

EmitAfterSessionCreate notifies all plugins that implement AfterSessionCreate.

func (*Registry) EmitAfterSessionRefresh

func (r *Registry) EmitAfterSessionRefresh(ctx context.Context, s *session.Session)

EmitAfterSessionRefresh notifies all plugins that implement AfterSessionRefresh.

func (*Registry) EmitAfterSessionRevoke

func (r *Registry) EmitAfterSessionRevoke(ctx context.Context, sessionID id.SessionID)

EmitAfterSessionRevoke notifies all plugins that implement AfterSessionRevoke.

func (*Registry) EmitAfterSignIn

func (r *Registry) EmitAfterSignIn(ctx context.Context, u *user.User, s *session.Session)

EmitAfterSignIn notifies all plugins that implement AfterSignIn.

func (*Registry) EmitAfterSignOut

func (r *Registry) EmitAfterSignOut(ctx context.Context, sessionID id.SessionID)

EmitAfterSignOut notifies all plugins that implement AfterSignOut.

func (*Registry) EmitAfterSignUp

func (r *Registry) EmitAfterSignUp(ctx context.Context, u *user.User, s *session.Session)

EmitAfterSignUp notifies all plugins that implement AfterSignUp.

func (*Registry) EmitAfterUserCreate

func (r *Registry) EmitAfterUserCreate(ctx context.Context, u *user.User)

EmitAfterUserCreate notifies all plugins that implement AfterUserCreate.

func (*Registry) EmitAfterUserDelete

func (r *Registry) EmitAfterUserDelete(ctx context.Context, userID id.UserID)

EmitAfterUserDelete notifies all plugins that implement AfterUserDelete.

func (*Registry) EmitAfterUserUpdate

func (r *Registry) EmitAfterUserUpdate(ctx context.Context, u *user.User)

EmitAfterUserUpdate notifies all plugins that implement AfterUserUpdate.

func (*Registry) EmitBeforeMemberRemove

func (r *Registry) EmitBeforeMemberRemove(ctx context.Context, m *organization.Member) error

EmitBeforeMemberRemove notifies all plugins that implement BeforeMemberRemove. Unlike EmitAfterMemberRemove, which fires after deletion and only logs a hook's error, this fires before deletion and returns the first error so the caller can abort the removal, matching EmitBeforeUserDelete.

func (*Registry) EmitBeforePrincipalAuth

func (r *Registry) EmitBeforePrincipalAuth(ctx context.Context, a *principal.AuthAttempt) error

EmitBeforePrincipalAuth notifies all plugins that implement BeforePrincipalAuth, stopping at the first error.

func (*Registry) EmitBeforeSessionCreate

func (r *Registry) EmitBeforeSessionCreate(ctx context.Context, s *session.Session) error

EmitBeforeSessionCreate notifies all plugins that implement BeforeSessionCreate.

func (*Registry) EmitBeforeSignIn

func (r *Registry) EmitBeforeSignIn(ctx context.Context, req *account.SignInRequest) error

EmitBeforeSignIn notifies all plugins that implement BeforeSignIn.

func (*Registry) EmitBeforeSignOut

func (r *Registry) EmitBeforeSignOut(ctx context.Context, sessionID id.SessionID) error

EmitBeforeSignOut notifies all plugins that implement BeforeSignOut.

func (*Registry) EmitBeforeSignUp

func (r *Registry) EmitBeforeSignUp(ctx context.Context, req *account.SignUpRequest) error

EmitBeforeSignUp notifies all plugins that implement BeforeSignUp.

func (*Registry) EmitBeforeUserCreate

func (r *Registry) EmitBeforeUserCreate(ctx context.Context, u *user.User) error

EmitBeforeUserCreate notifies all plugins that implement BeforeUserCreate.

func (*Registry) EmitBeforeUserDelete

func (r *Registry) EmitBeforeUserDelete(ctx context.Context, userID id.UserID) error

EmitBeforeUserDelete notifies all plugins that implement BeforeUserDelete.

func (*Registry) EmitBeforeUserUpdate

func (r *Registry) EmitBeforeUserUpdate(ctx context.Context, u *user.User) error

EmitBeforeUserUpdate notifies all plugins that implement BeforeUserUpdate.

func (*Registry) EmitOnInit

func (r *Registry) EmitOnInit(ctx context.Context, engine Engine) error

EmitOnInit notifies all plugins that implement OnInit, stopping at the first failure and returning it.

Unlike the after-hooks, an OnInit error is fatal rather than logged. OnInit is where a plugin resolves its store, keys, and bridges; a plugin that fails here is not "degraded", it is absent. Continuing would leave the engine serving traffic with a security control silently missing — an MFA plugin that never wired its store enforces nothing — and a warning in the startup log is not a reliable way to notice. Startup is the one point where failing loudly costs nothing.

func (*Registry) EmitOnShutdown

func (r *Registry) EmitOnShutdown(ctx context.Context)

EmitOnShutdown notifies all plugins that implement OnShutdown.

func (*Registry) Plugin

func (r *Registry) Plugin(name string) Plugin

Plugin returns a registered plugin by name, or nil if not found.

func (*Registry) Plugins

func (r *Registry) Plugins() []Plugin

Plugins returns all registered plugins.

func (*Registry) Register

func (r *Registry) Register(p Plugin)

Register adds a plugin and type-asserts it into all applicable hook caches. Plugins are notified in registration order. Duplicate plugins (same Name()) are silently skipped.

func (*Registry) RootRouteProviders

func (r *Registry) RootRouteProviders() []RootRouteProvider

RootRouteProviders returns all plugins that provide origin-root routes.

func (*Registry) RouteProviders

func (r *Registry) RouteProviders() []RouteProvider

RouteProviders returns all plugins that provide routes.

type RetentionSweeper

type RetentionSweeper interface {
	SweepRetention(ctx context.Context, cutoff func(kind string) time.Time, batch int) (int64, error)
}

RetentionSweeper is implemented by a plugin that keeps rows with a lifetime of their own. The engine's retention sweeper calls it on every run: cutoff returns the instant before which rows of a kind (a store.Retention* name, or the plugin's own) may go, or the zero time when that kind is kept forever; batch is how many rows one delete may remove. The plugin loops until a batch comes back short and reports the total.

type RootRouteProvider

type RootRouteProvider interface {
	RegisterRootRoutes(router forge.Router) error
}

RootRouteProvider is implemented by plugins that must serve routes at the origin root rather than under the extension's mount prefix. Well-known discovery documents are the only legitimate use: RFC 8414 and RFC 9728 define their locations relative to the origin, so a prefixed copy is invisible to a client that only knows the host.

type RouteProvider

type RouteProvider interface {
	RegisterRoutes(router forge.Router) error
}

RouteProvider allows a plugin to register additional HTTP routes.

type SessionRevoker

type SessionRevoker interface {
	RevokeSession(ctx context.Context, sessionID id.SessionID) error
}

SessionRevoker is optionally implemented by engines that can revoke a single session by ID. Revoking through this rather than deleting rows directly keeps the AfterSessionRevoke hooks, the hook bus and the outbound relay firing. *authsome.Engine already satisfies it.

type SettingsProvider

type SettingsProvider interface {
	DeclareSettings(m *settings.Manager) error
}

SettingsProvider is implemented by plugins that declare configurable settings via the dynamic settings system. The engine calls DeclareSettings during initialization so the settings are registered before use.

type StrategyProvider

type StrategyProvider interface {
	Plugin
	Strategy() strategy.Strategy
	StrategyPriority() int
}

StrategyProvider is implemented by plugins that contribute an authentication strategy to the strategy registry. The engine auto-registers these strategies during Start() so they participate in layered auth middleware evaluation.

Jump to

Keyboard shortcuts

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