auth

package
v0.10.0 Latest Latest
Warning

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

Go to latest
Published: Oct 4, 2026 License: Apache-2.0 Imports: 37 Imported by: 0

Documentation

Overview

Package auth provides authentication and JWT token handling.

Package auth provides authentication utilities for GoatFlow.

Package auth provides authentication utilities for GoatFlow.

Index

Constants

View Source
const (
	TokenTypeAccess  = "access"
	TokenTypeRefresh = "refresh"
)

Token types carried in the "typ" claim. Access and refresh tokens are signed with the same key, so the claim is what keeps one from being used as the other.

View Source
const (
	AccountKindAgent    = "agent"
	AccountKindCustomer = "customer"
)

Account kinds carried by refresh tokens: agents live in users, customers in customer_user, and their ids overlap.

View Source
const (
	// EnvPasswordHashType selects the algorithm for new hashes (bcrypt|sha256).
	EnvPasswordHashType = "PASSWORD_HASH_TYPE"
	// EnvMigratePasswordHashes, when true, rehashes a password with the
	// configured algorithm on successful login if the stored hash uses another.
	EnvMigratePasswordHashes = "MIGRATE_PASSWORD_HASHES"
)

Environment variables that configure password hashing.

View Source
const (
	AuditTOTPSetupStarted   = "2FA_SETUP_STARTED"
	AuditTOTPSetupCompleted = "2FA_SETUP_COMPLETED"
	AuditTOTPSetupFailed    = "2FA_SETUP_FAILED"
	AuditTOTPDisabled       = "2FA_DISABLED"
	AuditTOTPVerifySuccess  = "2FA_VERIFY_SUCCESS"
	AuditTOTPVerifyFailed   = "2FA_VERIFY_FAILED"
	AuditTOTPSessionCreated = "2FA_SESSION_CREATED"
	AuditTOTPSessionExpired = "2FA_SESSION_EXPIRED"
	AuditTOTPSessionLocked  = "2FA_SESSION_LOCKED"
	AuditTOTPRecoveryUsed   = "2FA_RECOVERY_CODE_USED"
)

TOTP audit event types

View Source
const (
	// MaxTOTPAttempts before session is invalidated
	MaxTOTPAttempts = 5
	// TOTPSessionTTL is how long a pending session lasts
	TOTPSessionTTL = 5 * time.Minute
	// CleanupInterval for expired sessions
	CleanupInterval = 1 * time.Minute
)

Variables

View Source
var (
	ErrInvalidCredentials = errors.New("invalid credentials")
	ErrUserNotFound       = errors.New("user not found")
	ErrUserDisabled       = errors.New("user account is disabled")
	ErrAuthBackendFailed  = errors.New("authentication backend failed")
)

Common errors.

View Source
var (
	ErrInvalidToken = errors.New("invalid token")
	ErrExpiredToken = errors.New("token has expired")
)
View Source
var DefaultLoginRateLimiter = NewLoginRateLimiter(5, 300, 2*time.Second, 60*time.Second)

DefaultLoginRateLimiter is the global instance for login rate limiting.

View Source
var ErrPasswordTooLong = errors.New("password must be at most 72 bytes")

ErrPasswordTooLong is returned by HashPassword when bcrypt is configured and the password exceeds bcrypt's 72-byte input limit.

Functions

func GenerateSPMetadata

func GenerateSPMetadata(cfg *SAMLConfig) ([]byte, error)

GenerateSPMetadata builds the SP metadata XML from the given configuration. The metadata advertises this service provider's entity ID, ACS URL, and optional signing certificate so an IdP can be configured to trust it.

func GetOIDCClient

func GetOIDCClient() *http.Client

GetOIDCClient returns the globally-configured OIDC HTTP client.

func LDAPStartupCheck added in v0.10.0

func LDAPStartupCheck() error

LDAPStartupCheck validates the LDAP settings when LDAP_ENABLED is true and logs transport-security warnings. It does not contact the server, so a directory outage never blocks startup.

func ListProviders

func ListProviders() []string

ListProviders returns registered provider names.

func LogTOTPAuditEvent

func LogTOTPAuditEvent(event TOTPAuditEvent)

LogTOTPAuditEvent logs a 2FA security event. V8 FIX: Provides audit trail for 2FA events.

func LogTOTPDisabled

func LogTOTPDisabled(userID int, userLogin string, isCustomer bool, clientIP string)

LogTOTPDisabled logs when 2FA is disabled.

func LogTOTPRecoveryCodeUsed

func LogTOTPRecoveryCodeUsed(userID int, userLogin string, isCustomer bool, clientIP string, codesRemaining int)

LogTOTPRecoveryCodeUsed logs when a recovery code is used instead of TOTP.

func LogTOTPSessionLocked

func LogTOTPSessionLocked(userID int, userLogin string, isCustomer bool, clientIP string)

LogTOTPSessionLocked logs when a 2FA session is locked due to too many failures.

func LogTOTPSetupCompleted

func LogTOTPSetupCompleted(userID int, userLogin string, isCustomer bool, clientIP string)

LogTOTPSetupCompleted logs when 2FA setup is successfully completed.

func LogTOTPSetupStarted

func LogTOTPSetupStarted(userID int, userLogin string, isCustomer bool, clientIP string)

LogTOTPSetupStarted logs when a user starts 2FA setup.

func LogTOTPVerifyFailed

func LogTOTPVerifyFailed(userID int, userLogin string, isCustomer bool, clientIP string, attemptsRemaining int)

LogTOTPVerifyFailed logs a failed 2FA verification attempt.

func LogTOTPVerifySuccess

func LogTOTPVerifySuccess(userID int, userLogin string, isCustomer bool, clientIP string)

LogTOTPVerifySuccess logs a successful 2FA verification.

func NewGithubProvider

func NewGithubProvider(cfg *GithubConfig, deps ProviderDependencies) *githubProvider

NewGithubProvider creates a new GitHub OAuth2 provider.

func NewGoogleProvider

func NewGoogleProvider(cfg *GoogleConfig, deps ProviderDependencies) *googleProvider

NewGoogleProvider creates a new Google auth provider.

func NewOidcProvider

func NewOidcProvider(cfg *OidcConfig, deps ProviderDependencies) *oidcProvider

NewOidcProvider creates a new OIDC provider.

func NewSAML2Provider

func NewSAML2Provider(cfg *SAMLConfig, deps ProviderDependencies) (*samlProvider, error)

NewSAML2Provider creates a new SAML2 provider from the given configuration.

func RegisterProvider

func RegisterProvider(name string, factory ProviderFactory) error

RegisterProvider registers a provider factory by name (lowercase unique key).

func SetOIDCClient

func SetOIDCClient(client *http.Client)

SetOIDCClient sets the global OIDC HTTP client.

func SetStateStore

func SetStateStore(store StateStore)

SetStateStore sets the global state store.

func SetUserRepoFactory

func SetUserRepoFactory(f func(*sql.DB) UserLookup)

SetUserRepoFactory injects a factory that creates a UserLookup from a *sql.DB. Product code calls this at boot to wire repository.UserRepository without a platform import.

Types

type AuthProvider

type AuthProvider interface {
	// Authenticate attempts to authenticate a user with the given credentials
	// Returns the authenticated user and nil error on success
	Authenticate(ctx context.Context, username, password string) (*platformmodels.User, error)

	// GetUser retrieves user details by username/email
	GetUser(ctx context.Context, identifier string) (*platformmodels.User, error)

	// ValidateToken validates an existing session/token
	ValidateToken(ctx context.Context, token string) (*platformmodels.User, error)

	// Name returns the name of this auth provider
	Name() string

	// Priority returns the priority of this provider (lower = higher priority)
	Priority() int
}

AuthProvider defines the interface for authentication providers.

func CreateProvider

func CreateProvider(name string, deps ProviderDependencies) (AuthProvider, error)

CreateProvider instantiates a provider by name.

type Authenticator

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

Authenticator manages multiple authentication providers.

func NewAuthenticator

func NewAuthenticator(providers ...AuthProvider) *Authenticator

NewAuthenticator creates a new authenticator with the given providers.

func (*Authenticator) AddProvider

func (a *Authenticator) AddProvider(provider AuthProvider)

AddProvider adds a new authentication provider.

func (*Authenticator) Authenticate

func (a *Authenticator) Authenticate(ctx context.Context, username, password string) (*platformmodels.User, error)

Authenticate attempts to authenticate using all configured providers.

func (*Authenticator) GetProviders

func (a *Authenticator) GetProviders() []string

GetProviders returns the list of configured providers.

func (*Authenticator) GetUser

func (a *Authenticator) GetUser(ctx context.Context, identifier string) (*platformmodels.User, error)

GetUser retrieves user information from the primary provider.

func (*Authenticator) ValidateToken

func (a *Authenticator) ValidateToken(ctx context.Context, token string) (*platformmodels.User, error)

ValidateToken validates a token using the primary provider.

type Claims

type Claims struct {
	UserID    uint   `json:"user_id"`
	Email     string `json:"email"`
	Login     string `json:"login,omitempty"`
	Role      string `json:"role"`
	IsAdmin   bool   `json:"is_admin,omitempty"` // User is in admin group (for nav display)
	TenantID  uint   `json:"tenant_id,omitempty"`
	SessionID string `json:"sid"`
	TokenType string `json:"typ"`
	jwt.RegisteredClaims
}

Claims are the claims of an access token. SessionID names the sessions row the login created; an access token is only as alive as that row, so killing the session (admin, logout) revokes every token that carries its id.

type DatabaseAuthProvider

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

DatabaseAuthProvider provides authentication against the database.

func NewDatabaseAuthProvider

func NewDatabaseAuthProvider(db *sql.DB, userRepo UserLookup) *DatabaseAuthProvider

func (*DatabaseAuthProvider) Authenticate

func (p *DatabaseAuthProvider) Authenticate(ctx context.Context, username, password string) (*platformmodels.User, error)

Authenticate authenticates a user against the database.

func (*DatabaseAuthProvider) GetUser

func (p *DatabaseAuthProvider) GetUser(ctx context.Context, identifier string) (*platformmodels.User, error)

GetUser retrieves user details by username or email.

func (*DatabaseAuthProvider) Name

func (p *DatabaseAuthProvider) Name() string

Name returns the name of this auth provider.

func (*DatabaseAuthProvider) Priority

func (p *DatabaseAuthProvider) Priority() int

Priority returns the priority of this provider.

func (*DatabaseAuthProvider) ValidateToken

func (p *DatabaseAuthProvider) ValidateToken(ctx context.Context, token string) (*platformmodels.User, error)

ValidateToken validates a session token (for future implementation).

type GithubConfig

type GithubConfig struct {
	ClientID     string
	ClientSecret string
	Scopes       string // optional, defaults to "read:user user:email"
}

GithubConfig holds the GitHub OAuth2 configuration.

type GoogleConfig

type GoogleConfig struct {
	ClientID     string
	ClientSecret string
	RedirectURL  string // optional, set by handler from request
	Scopes       string // optional, defaults to "openid email profile"
}

GoogleConfig holds the configuration for a Google auth provider.

type JWTManager

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

func NewJWTManager

func NewJWTManager(secretKey string, tokenDuration time.Duration) *JWTManager

func (*JWTManager) GenerateRefreshToken

func (m *JWTManager) GenerateRefreshToken(kind string, userID uint, login, sessionID string) (string, error)

GenerateRefreshToken creates a refresh token for the account (kind, userID, login) and session, valid for the refresh token TTL. Each token gets a random id (jti), so two tokens issued in the same second differ.

func (*JWTManager) GenerateTokenWithDuration

func (m *JWTManager) GenerateTokenWithDuration(sessionID string, userID uint, login, email, role string, isAdmin bool, tenantID uint, duration time.Duration) (string, error)

GenerateTokenWithDuration creates an access token bound to sessionID with a specific duration. If duration is 0, the system default is used. A token without a session cannot be revoked, so an empty sessionID is an error.

func (*JWTManager) GenerateTokenWithLogin

func (m *JWTManager) GenerateTokenWithLogin(sessionID string, userID uint, login, email, role string, isAdmin bool, tenantID uint) (string, error)

GenerateTokenWithLogin creates an access token bound to sessionID with the default duration.

func (*JWTManager) RefreshTokenDuration added in v0.10.0

func (m *JWTManager) RefreshTokenDuration() time.Duration

RefreshTokenDuration returns the refresh token TTL.

func (*JWTManager) SetRefreshTokenDuration

func (m *JWTManager) SetRefreshTokenDuration(d time.Duration)

SetRefreshTokenDuration sets the refresh token TTL.

func (*JWTManager) TokenDuration

func (m *JWTManager) TokenDuration() time.Duration

func (*JWTManager) ValidateRefreshToken

func (m *JWTManager) ValidateRefreshToken(tokenString string) (*RefreshClaims, error)

ValidateRefreshToken validates a refresh token. Access tokens are rejected.

func (*JWTManager) ValidateToken

func (m *JWTManager) ValidateToken(tokenString string) (*Claims, error)

ValidateToken validates an access token. Refresh tokens and tokens that name no session (issued before sessions were bound to tokens) are rejected; the caller still has to check that the session row exists.

type LDAPAuthProvider

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

LDAPAuthProvider authenticates agents against an LDAP / Active Directory server and maps them to GoatFlow agent accounts (OTRS Auth::Module LDAP with optional AuthSyncModule-style account creation and attribute sync).

func NewLDAPAuthProvider

func NewLDAPAuthProvider(cfg *ldap.Config, db *sql.DB, userRepo UserLookup) (*LDAPAuthProvider, error)

NewLDAPAuthProvider creates an LDAP provider for a validated configuration.

func (*LDAPAuthProvider) Authenticate

func (p *LDAPAuthProvider) Authenticate(ctx context.Context, username, password string) (*platformmodels.User, error)

Authenticate verifies the password with the directory and returns the matching GoatFlow agent. A login with no directory entry returns ErrUserNotFound so the next provider in Auth::Providers is tried.

func (*LDAPAuthProvider) GetUser

func (p *LDAPAuthProvider) GetUser(ctx context.Context, identifier string) (*platformmodels.User, error)

GetUser returns the GoatFlow agent with the given login.

func (*LDAPAuthProvider) Name

func (p *LDAPAuthProvider) Name() string

Name returns the name of this auth provider.

func (*LDAPAuthProvider) Priority

func (p *LDAPAuthProvider) Priority() int

Priority returns the priority of this provider.

func (*LDAPAuthProvider) ValidateToken

func (p *LDAPAuthProvider) ValidateToken(ctx context.Context, token string) (*platformmodels.User, error)

ValidateToken is not supported: sessions are JWTs issued after login.

type LoginRateLimiter

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

LoginRateLimiter implements fail2ban-style rate limiting for login attempts. It tracks failed attempts by IP and username, applying exponential backoff.

func NewLoginRateLimiter

func NewLoginRateLimiter(maxAttempts, windowSeconds int, baseBackoff, maxBackoff time.Duration) *LoginRateLimiter

maxBackoff: maximum backoff duration.

func (*LoginRateLimiter) IsBlocked

func (rl *LoginRateLimiter) IsBlocked(ip, username string) (bool, time.Duration)

IsBlocked checks if an IP+username combination is currently blocked.

func (*LoginRateLimiter) RecordFailure

func (rl *LoginRateLimiter) RecordFailure(ip, username string)

RecordFailure records a failed login attempt.

func (*LoginRateLimiter) RecordSuccess

func (rl *LoginRateLimiter) RecordSuccess(ip, username string)

RecordSuccess clears the failure record for successful login.

func (*LoginRateLimiter) Stats

func (rl *LoginRateLimiter) Stats() map[string]interface{}

Stats returns current rate limiter statistics (for monitoring).

type MemoryStateStore

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

MemoryStateStore is an in-memory, thread-safe store for SSO state tokens. State entries expire after 5 minutes and are lazily evicted on access.

func NewMemoryStateStore

func NewMemoryStateStore() *MemoryStateStore

NewMemoryStateStore creates a ready-to-use state store.

func (*MemoryStateStore) ConsumeState

func (s *MemoryStateStore) ConsumeState(token string) (StateData, bool)

ConsumeState atomically reads and removes the state token.

func (*MemoryStateStore) GetState

func (s *MemoryStateStore) GetState(token string) (StateData, bool)

GetState returns the data for a token without consuming it.

func (*MemoryStateStore) StoreState

func (s *MemoryStateStore) StoreState(token string, data StateData) error

StoreState saves a state token. It fails when the token already exists.

type OIDCProvider

type OIDCProvider interface {
	// StartAuthFlow generates a state token and returns the IdP authorize URL.
	StartAuthFlow(ctx context.Context, state, codeVerifier string) (authURL string, err error)

	// CompleteAuthFlow exchanges an authorization code for a user.
	// Validates state, exchanges code, validates ID token (JWKS), and resolves user.
	CompleteAuthFlow(ctx context.Context, code, state string) (*platformmodels.User, error)
}

OIDCProvider defines the interface for redirect-based authentication providers (OIDC, Google, etc). Used via type assertion in login handlers, NOT part of AuthProvider since password-based providers (database, LDAP) don't have auth redirects.

type OidcConfig

type OidcConfig struct {
	DiscoveryURL  string
	ClientID      string
	ClientSecret  string
	RedirectURL   string
	Scopes        string
	ClaimEmail    string
	ClaimName     string
	ClaimGroups   string
	AutoProvision bool
	UserTable     string
}

OidcConfig holds OIDC provider configuration.

type PasswordHashType

type PasswordHashType string

PasswordHashType is the algorithm used to create new password hashes.

const (
	// HashTypeBcrypt is the default: salted, adaptive bcrypt.
	HashTypeBcrypt PasswordHashType = "bcrypt"
	// HashTypeSHA256 is OTRS's unsalted sha2 format (64 hex chars). Only for
	// running side by side with an OTRS that must read the same user tables.
	HashTypeSHA256 PasswordHashType = "sha256"
)

func ConfiguredPasswordHashType added in v0.10.0

func ConfiguredPasswordHashType() PasswordHashType

ConfiguredPasswordHashType returns the algorithm selected by PASSWORD_HASH_TYPE. Unset means bcrypt; an unknown value logs a warning and falls back to bcrypt rather than to a weaker algorithm.

type PasswordHasher

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

PasswordHasher is the single place that creates and verifies password hashes for agents (users.pw) and customers (customer_user.pw). Its configuration is read once at construction and never mutated, so it is safe for concurrent use.

func NewPasswordHasher

func NewPasswordHasher() *PasswordHasher

NewPasswordHasher returns a hasher configured from PASSWORD_HASH_TYPE (default bcrypt) and MIGRATE_PASSWORD_HASHES (default false).

func (*PasswordHasher) HashPassword

func (h *PasswordHasher) HashPassword(password string) (string, error)

HashPassword hashes a password using the configured algorithm.

func (*PasswordHasher) HashType added in v0.10.0

func (h *PasswordHasher) HashType() PasswordHashType

HashType returns the algorithm this hasher uses for new hashes.

func (*PasswordHasher) MigratePasswordHash

func (h *PasswordHasher) MigratePasswordHash(password, storedHash string) (string, bool, error)

MigratePasswordHash returns a new hash of password in the configured format when MIGRATE_PASSWORD_HASHES is enabled and storedHash is in another format. The caller must already have verified password against storedHash. When no migration is due it returns ("", false, nil).

func (*PasswordHasher) VerifyPassword

func (h *PasswordHasher) VerifyPassword(password, storedHash string) bool

VerifyPassword checks a password against a stored hash in any supported format, regardless of the configured algorithm: bcrypt ($2a$/$2b$/$2y$), salted "sha256$salt$hash", and the OTRS/Znuny formats (see verifyOTRSHash).

type PendingTOTPSession

type PendingTOTPSession struct {
	Token       string    // Random token (cookie value)
	UserID      int       // For agents (numeric)
	UserLogin   string    // For customers (email) - stored here, not in cookie
	Username    string    // Display name
	IsCustomer  bool      // true for customer, false for agent
	CreatedAt   time.Time // Session creation time
	ExpiresAt   time.Time // Expiration (5 minutes)
	Attempts    int       // Failed attempt count
	MaxAttempts int       // Max allowed (default 5)
	ClientIP    string    // Bind to IP for security
	UserAgent   string    // Bind to User-Agent
}

PendingTOTPSession tracks a pending 2FA verification.

type Permission

type Permission string
const (
	// Ticket permissions.
	PermissionTicketCreate Permission = "ticket:create"
	PermissionTicketRead   Permission = "ticket:read"
	PermissionTicketUpdate Permission = "ticket:update"
	PermissionTicketDelete Permission = "ticket:delete"
	PermissionTicketAssign Permission = "ticket:assign"
	PermissionTicketClose  Permission = "ticket:close"

	// User permissions.
	PermissionUserCreate Permission = "user:create"
	PermissionUserRead   Permission = "user:read"
	PermissionUserUpdate Permission = "user:update"
	PermissionUserDelete Permission = "user:delete"

	// Admin permissions.
	PermissionAdminAccess  Permission = "admin:access"
	PermissionSystemConfig Permission = "system:config"

	// Report permissions.
	PermissionReportView   Permission = "report:view"
	PermissionReportCreate Permission = "report:create"

	// Entity deletion permissions.
	PermissionEntityHardDelete Permission = "entity:hard_delete"

	// Customer permissions.
	PermissionOwnTicketRead   Permission = "own:ticket:read"
	PermissionOwnTicketCreate Permission = "own:ticket:create"
)

type ProviderDependencies

type ProviderDependencies struct {
	DB         *sql.DB
	UserRepo   UserLookup
	OIDCClient *http.Client // shared HTTP client for OIDC token exchanges and JWKS fetches
	StateStore StateStore   // state token store for OIDC OAuth2 state protection
}

ProviderDependencies bundles common resources providers may need.

type ProviderFactory

type ProviderFactory func(deps ProviderDependencies) (AuthProvider, error)

ProviderFactory builds an AuthProvider given dependencies.

type RBAC

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

func NewRBAC

func NewRBAC() *RBAC

func (*RBAC) CanAccessAdminPanel

func (r *RBAC) CanAccessAdminPanel(role string) bool

func (*RBAC) CanAccessTicket

func (r *RBAC) CanAccessTicket(role string, ticketOwnerID, userID uint) bool

func (*RBAC) CanAssignTicket

func (r *RBAC) CanAssignTicket(role string) bool

func (*RBAC) CanCloseTicket

func (r *RBAC) CanCloseTicket(role string) bool

func (*RBAC) CanModifyUser

func (r *RBAC) CanModifyUser(actorRole string, targetUserRole string) bool

func (*RBAC) CanViewReports

func (r *RBAC) CanViewReports(role string) bool

func (*RBAC) GetRolePermissions

func (r *RBAC) GetRolePermissions(role string) []Permission

func (*RBAC) HasPermission

func (r *RBAC) HasPermission(role string, permission Permission) bool

type RefreshClaims added in v0.10.0

type RefreshClaims struct {
	UserID    uint   `json:"user_id"`
	Kind      string `json:"kind"` // AccountKindAgent or AccountKindCustomer
	SessionID string `json:"sid"`
	TokenType string `json:"typ"`
	jwt.RegisteredClaims
}

RefreshClaims are the claims of a refresh token. Subject is the account login; SessionID is the session the refreshed access tokens stay bound to.

type SAMLConfig

type SAMLConfig struct {
	EntityID        string // SP entity ID (required)
	AcsURL          string // Assertion Consumer Service URL on this host
	IdPMetadataURL  string // IdP metadata endpoint URL
	IdPMetadataXML  string // raw IdP metadata XML (alternative to URL)
	SigningCert     string // PEM-encoded X.509 certificate for signing
	PrivateKey      string // PEM-encoded private key
	UserClaimEmail  string // attribute name/oid mapped to email (default "email")
	UserClaimName   string // attribute name/oid mapped to display name (default "name")
	UserClaimGroups string // attribute name mapped to groups (default "groups")
	AutoProvision   bool   // create users not found in the database
	UserTable       string // "users" (agent) or "customer" (service_customer_user)
}

SAMLConfig holds SAML2 service provider configuration derived from an IdentityProvider row.

type StateData added in v0.10.0

type StateData struct {
	ProviderID   uint
	ProviderType string
	OrgID        uint
	// CodeVerifier is the PKCE verifier (OIDC only).
	CodeVerifier string
	// RequestID is the ID of the SAML AuthnRequest sent for this login (SAML
	// only). The ACS accepts only a response whose InResponseTo matches it.
	RequestID string
	// BrowserBinding is the hash of the nonce cookie set in the browser that
	// started the login. The callback must come from the same browser, so a
	// callback URL captured from another login cannot be replayed (login CSRF).
	BrowserBinding string
}

StateData is what the store keeps for one SSO state token (OIDC state or SAML RelayState) between the redirect to the IdP and the callback.

type StateStore

type StateStore interface {
	// StoreState saves a state token. It fails when the token already exists.
	StoreState(token string, data StateData) error

	// GetState returns the data for a token without consuming it.
	// ok=false when the token is missing or expired.
	GetState(token string) (data StateData, ok bool)

	// ConsumeState atomically reads and removes the state token.
	// ok=false when the token is missing, already consumed, or expired.
	ConsumeState(token string) (data StateData, ok bool)
}

StateStore manages SSO state tokens with TTL-based expiry.

func GetStateStore

func GetStateStore() StateStore

GetStateStore returns the globally-configured state store.

type StaticAuthProvider

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

StaticAuthProvider offers simple in-memory users for demos/tests.

func NewStaticAuthProvider

func NewStaticAuthProvider(specs []string) *StaticAuthProvider

static user spec env format: user:password:Role(Agent|Customer|Admin) Multiple separated by commas.

func (*StaticAuthProvider) Authenticate

func (p *StaticAuthProvider) Authenticate(ctx context.Context, username, password string) (*platformmodels.User, error)

func (*StaticAuthProvider) GetUser

func (p *StaticAuthProvider) GetUser(ctx context.Context, identifier string) (*platformmodels.User, error)

func (*StaticAuthProvider) Name

func (p *StaticAuthProvider) Name() string

func (*StaticAuthProvider) Priority

func (p *StaticAuthProvider) Priority() int

func (*StaticAuthProvider) ValidateToken

func (p *StaticAuthProvider) ValidateToken(ctx context.Context, token string) (*platformmodels.User, error)

type TOTPAuditEvent

type TOTPAuditEvent struct {
	Timestamp  time.Time
	EventType  string
	UserID     int
	UserLogin  string
	IsCustomer bool
	ClientIP   string
	UserAgent  string
	Success    bool
	Details    string
}

TOTPAuditEvent represents a 2FA-related security event.

type TOTPSessionManager

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

TOTPSessionManager handles pending 2FA sessions with security controls. Addresses: V3 (rate limiting), V5 (HMAC verification), V7 (session invalidation).

var (
	// DefaultTOTPSessionManager is the global instance
	DefaultTOTPSessionManager *TOTPSessionManager
)

func GetTOTPSessionManager

func GetTOTPSessionManager() *TOTPSessionManager

GetTOTPSessionManager returns the singleton instance.

func NewTOTPSessionManager

func NewTOTPSessionManager(secret []byte) *TOTPSessionManager

NewTOTPSessionManager creates a new session manager with the given HMAC secret.

func (*TOTPSessionManager) CreateAgentSession

func (m *TOTPSessionManager) CreateAgentSession(userID int, username, clientIP, userAgent string) (string, error)

CreateAgentSession creates a pending 2FA session for an agent. Returns the token to store in cookie.

func (*TOTPSessionManager) CreateCustomerSession

func (m *TOTPSessionManager) CreateCustomerSession(userLogin, clientIP, userAgent string) (string, error)

CreateCustomerSession creates a pending 2FA session for a customer. Returns the token to store in cookie. Login is stored server-side, NOT in cookie (V4 fix).

func (*TOTPSessionManager) GenerateHMAC

func (m *TOTPSessionManager) GenerateHMAC(data string) string

GenerateHMAC creates an HMAC signature for session data (V5).

func (*TOTPSessionManager) GetRemainingAttempts

func (m *TOTPSessionManager) GetRemainingAttempts(token string) int

GetRemainingAttempts returns how many attempts are left for a session.

func (*TOTPSessionManager) InvalidateSession

func (m *TOTPSessionManager) InvalidateSession(token string)

InvalidateSession removes a session (after successful auth or too many failures).

func (*TOTPSessionManager) RecordFailedAttempt

func (m *TOTPSessionManager) RecordFailedAttempt(token string) int

RecordFailedAttempt increments the attempt counter (V3 + V7). Returns remaining attempts, or 0 if session is now invalid.

func (*TOTPSessionManager) Stats

func (m *TOTPSessionManager) Stats() map[string]int

Stats returns current session manager statistics.

func (*TOTPSessionManager) ValidateAndGetSession

func (m *TOTPSessionManager) ValidateAndGetSession(token, clientIP, userAgent string) *PendingTOTPSession

ValidateAndGetSession checks if a token is valid and returns the session. Returns nil if invalid, expired, or too many attempts. Security: Enforces strict IP binding to prevent session hijacking during 2FA.

func (*TOTPSessionManager) VerifyHMAC

func (m *TOTPSessionManager) VerifyHMAC(data, signature string) bool

VerifyHMAC checks if an HMAC signature is valid (V5).

type UserLookup

type UserLookup interface {
	GetByLogin(login string) (*platformmodels.User, error)
	GetByEmail(email string) (*platformmodels.User, error)
	Create(user *platformmodels.User) error
	SyncGroups(userID uint, groupNames []string) error
}

UserLookup is the subset of user repository methods auth providers need. Product code injects a concrete *repository.UserRepository, which satisfies this interface.

Jump to

Keyboard shortcuts

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