identity

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Jul 27, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Index

Constants

View Source
const DefaultPasswordResetTTL = time.Hour

Variables

View Source
var (
	ErrInvalidCredentials = errors.New("invalid credentials")
	ErrSSODisabled        = errors.New("sso disabled")
	ErrSignupDisabled     = errors.New("signup disabled")
	ErrUnknownProvider    = errors.New("unknown sso provider")
	ErrInvalidSSOState    = errors.New("invalid or expired sso state")
	ErrInvalidResetToken  = errors.New("invalid or expired reset token")
)

Domain sentinel errors for AuthN.

View Source
var ErrEmailNotVerified = errors.New("email not verified")

ErrEmailNotVerified is returned when JIT provisioning requires a verified email.

View Source
var ErrMissingFederatedEmail = errors.New("federated email required")

ErrMissingFederatedEmail is returned when claims lack an email address.

View Source
var ErrMissingFederatedSubject = errors.New("federated subject required")

ErrMissingFederatedSubject is returned when claims lack a subject.

Functions

func HashOpaqueToken

func HashOpaqueToken(raw string) string

HashOpaqueToken returns the hex-encoded SHA-256 of the raw token.

func NewOpaqueToken

func NewOpaqueToken() (raw, hash string, err error)

NewOpaqueToken generates an opaque token and its hash (same shape as invite tokens).

Types

type AssertionExchanger

type AssertionExchanger interface {
	ExchangeAssertion(ctx context.Context, response, redirectURI string, possibleRequestIDs []string) (FederatedClaims, error)
}

AssertionExchanger is an optional FederationProvider extension for SAML ACS. possibleRequestIDs should include the AuthnRequest ID from BeginSSO (and "" when IdP-initiated is allowed).

type AuthStarter

type AuthStarter interface {
	AuthURLWithID(state, redirectURI string) (authURL, requestID string, err error)
}

AuthStarter is an optional FederationProvider extension used by SAML to return the AuthnRequest ID for InResponseTo validation on ACS.

type ExternalIdentity

type ExternalIdentity struct {
	ID        string    `json:"id"`
	UserID    string    `json:"user_id"`
	Provider  string    `json:"provider"`
	Issuer    string    `json:"issuer"`
	Subject   string    `json:"subject"`
	Email     string    `json:"email"`
	CreatedAt time.Time `json:"created_at"`
}

ExternalIdentity links a platform user to a federated IdP subject. Uniqueness is (Provider, Subject).

type ExternalIdentityRepository

type ExternalIdentityRepository interface {
	GetByProviderSubject(ctx context.Context, provider, subject string) (*ExternalIdentity, error)
	Create(ctx context.Context, identity ExternalIdentity) error
}

ExternalIdentityRepository persists federated IdP linkages.

type FederatedClaims

type FederatedClaims struct {
	Provider      string
	Issuer        string
	Subject       string
	Email         string
	EmailVerified bool
	Name          string
}

FederatedClaims are protocol-agnostic identity assertions from an IdP. OAuth2, OIDC, and (later) SAML adapters all map into this shape.

type FederationProvider

type FederationProvider interface {
	// Name returns the configured provider id (e.g. "google").
	Name() string
	// DisplayName is a human-readable label for the login UI.
	DisplayName() string
	// Type is the protocol kind: "oidc", "oauth2", or "saml".
	Type() string
	// AuthURL builds the IdP authorization redirect URL for the given CSRF state.
	AuthURL(state, redirectURI string) (string, error)
	// Exchange trades an authorization code (or mapped SAMLResponse) for FederatedClaims.
	Exchange(ctx context.Context, code, redirectURI string) (FederatedClaims, error)
}

FederationProvider is a protocol-agnostic SSO IdP adapter. OAuth2/OIDC and SAML 2.0 implement this port. SAML ACS maps the assertion payload at the HTTP edge into Exchange / AssertionExchanger.

type PasswordHasher

type PasswordHasher interface {
	Hash(password string) (string, error)
	Check(hash, password string) bool
}

PasswordHasher hashes and verifies local passwords.

type PasswordResetRepository

type PasswordResetRepository interface {
	Create(ctx context.Context, token PasswordResetToken) error
	DeleteUnusedForUser(ctx context.Context, userID string) error
	GetByTokenHash(ctx context.Context, hash string) (*PasswordResetToken, error)
	Consume(ctx context.Context, id string, usedAt time.Time) error
}

PasswordResetRepository stores opaque password-reset tokens (hash only).

type PasswordResetToken

type PasswordResetToken struct {
	ID        string
	UserID    string
	TokenHash string
	ExpiresAt time.Time
	CreatedAt time.Time
	UsedAt    *time.Time
}

PasswordResetToken is a stored reset challenge (hash only; raw token is emailed).

type ResolveDeps

type ResolveDeps struct {
	Users      UserRepository
	Identities ExternalIdentityRepository
	NewUserID  func() string
	NewLinkID  func() string
	Now        func() time.Time
}

ResolveDeps are persistence ports for ResolveOrProvisionUser.

type SSOState

type SSOState struct {
	Provider  string
	ReturnTo  string
	RequestID string // SAML AuthnRequest ID (empty for OAuth/OIDC)
	ExpiresAt time.Time
}

SSOState holds short-lived CSRF state for an SSO login attempt.

type SSOStateStore

type SSOStateStore interface {
	Put(ctx context.Context, state string, value SSOState) error
	// Take atomically loads and deletes state. Returns kernel.ErrNotFound when missing/expired.
	Take(ctx context.Context, state string) (SSOState, error)
}

SSOStateStore stores CSRF state between begin and complete SSO. Implementations must be safe for multi-instance control planes (shared backend).

type ServiceProviderMeta

type ServiceProviderMeta interface {
	MetadataXML() ([]byte, error)
}

ServiceProviderMeta is implemented by SAML adapters that expose SP metadata XML.

type TokenIssuer

type TokenIssuer interface {
	Issue(userID, email, role string) (string, error)
}

TokenIssuer creates platform session JWTs.

type User

type User struct {
	ID           string    `json:"id"`
	Email        string    `json:"email"`
	Name         string    `json:"name"`
	Role         string    `json:"role"`
	PasswordHash string    `json:"-"`
	CreatedAt    time.Time `json:"created_at"`
}

User is a platform identity record.

func ResolveOrProvisionUser

func ResolveOrProvisionUser(ctx context.Context, deps ResolveDeps, claims FederatedClaims) (*User, error)

ResolveOrProvisionUser finds or creates a platform user from federated claims (JIT).

Resolution order:

  1. Existing ExternalIdentity by (provider, subject)
  2. Verified email matches existing user → link identity
  3. JIT-create user (role member, no password) + link identity

Unverified email is rejected when no prior link exists.

type UserRepository

type UserRepository interface {
	GetByEmail(ctx context.Context, email string) (*User, error)
	GetByID(ctx context.Context, id string) (*User, error)
	Create(ctx context.Context, user User) error
	UpdatePassword(ctx context.Context, userID, passwordHash string) error
}

UserRepository loads and creates platform users.

Jump to

Keyboard shortcuts

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