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
- Variables
- func GenerateSPMetadata(cfg *SAMLConfig) ([]byte, error)
- func GetOIDCClient() *http.Client
- func LDAPStartupCheck() error
- func ListProviders() []string
- func LogTOTPAuditEvent(event TOTPAuditEvent)
- func LogTOTPDisabled(userID int, userLogin string, isCustomer bool, clientIP string)
- func LogTOTPRecoveryCodeUsed(userID int, userLogin string, isCustomer bool, clientIP string, ...)
- func LogTOTPSessionLocked(userID int, userLogin string, isCustomer bool, clientIP string)
- func LogTOTPSetupCompleted(userID int, userLogin string, isCustomer bool, clientIP string)
- func LogTOTPSetupStarted(userID int, userLogin string, isCustomer bool, clientIP string)
- func LogTOTPVerifyFailed(userID int, userLogin string, isCustomer bool, clientIP string, ...)
- func LogTOTPVerifySuccess(userID int, userLogin string, isCustomer bool, clientIP string)
- func NewGithubProvider(cfg *GithubConfig, deps ProviderDependencies) *githubProvider
- func NewGoogleProvider(cfg *GoogleConfig, deps ProviderDependencies) *googleProvider
- func NewOidcProvider(cfg *OidcConfig, deps ProviderDependencies) *oidcProvider
- func NewSAML2Provider(cfg *SAMLConfig, deps ProviderDependencies) (*samlProvider, error)
- func RegisterProvider(name string, factory ProviderFactory) error
- func SetOIDCClient(client *http.Client)
- func SetStateStore(store StateStore)
- func SetUserRepoFactory(f func(*sql.DB) UserLookup)
- type AuthProvider
- type Authenticator
- func (a *Authenticator) AddProvider(provider AuthProvider)
- func (a *Authenticator) Authenticate(ctx context.Context, username, password string) (*platformmodels.User, error)
- func (a *Authenticator) GetProviders() []string
- func (a *Authenticator) GetUser(ctx context.Context, identifier string) (*platformmodels.User, error)
- func (a *Authenticator) ValidateToken(ctx context.Context, token string) (*platformmodels.User, error)
- type Claims
- type DatabaseAuthProvider
- func (p *DatabaseAuthProvider) Authenticate(ctx context.Context, username, password string) (*platformmodels.User, error)
- func (p *DatabaseAuthProvider) GetUser(ctx context.Context, identifier string) (*platformmodels.User, error)
- func (p *DatabaseAuthProvider) Name() string
- func (p *DatabaseAuthProvider) Priority() int
- func (p *DatabaseAuthProvider) ValidateToken(ctx context.Context, token string) (*platformmodels.User, error)
- type GithubConfig
- type GoogleConfig
- type JWTManager
- func (m *JWTManager) GenerateRefreshToken(kind string, userID uint, login, sessionID string) (string, error)
- func (m *JWTManager) GenerateTokenWithDuration(sessionID string, userID uint, login, email, role string, isAdmin bool, ...) (string, error)
- func (m *JWTManager) GenerateTokenWithLogin(sessionID string, userID uint, login, email, role string, isAdmin bool, ...) (string, error)
- func (m *JWTManager) RefreshTokenDuration() time.Duration
- func (m *JWTManager) SetRefreshTokenDuration(d time.Duration)
- func (m *JWTManager) TokenDuration() time.Duration
- func (m *JWTManager) ValidateRefreshToken(tokenString string) (*RefreshClaims, error)
- func (m *JWTManager) ValidateToken(tokenString string) (*Claims, error)
- type LDAPAuthProvider
- func (p *LDAPAuthProvider) Authenticate(ctx context.Context, username, password string) (*platformmodels.User, error)
- func (p *LDAPAuthProvider) GetUser(ctx context.Context, identifier string) (*platformmodels.User, error)
- func (p *LDAPAuthProvider) Name() string
- func (p *LDAPAuthProvider) Priority() int
- func (p *LDAPAuthProvider) ValidateToken(ctx context.Context, token string) (*platformmodels.User, error)
- type LoginRateLimiter
- type MemoryStateStore
- type OIDCProvider
- type OidcConfig
- type PasswordHashType
- type PasswordHasher
- type PendingTOTPSession
- type Permission
- type ProviderDependencies
- type ProviderFactory
- type RBAC
- func (r *RBAC) CanAccessAdminPanel(role string) bool
- func (r *RBAC) CanAccessTicket(role string, ticketOwnerID, userID uint) bool
- func (r *RBAC) CanAssignTicket(role string) bool
- func (r *RBAC) CanCloseTicket(role string) bool
- func (r *RBAC) CanModifyUser(actorRole string, targetUserRole string) bool
- func (r *RBAC) CanViewReports(role string) bool
- func (r *RBAC) GetRolePermissions(role string) []Permission
- func (r *RBAC) HasPermission(role string, permission Permission) bool
- type RefreshClaims
- type SAMLConfig
- type StateData
- type StateStore
- type StaticAuthProvider
- func (p *StaticAuthProvider) Authenticate(ctx context.Context, username, password string) (*platformmodels.User, error)
- func (p *StaticAuthProvider) GetUser(ctx context.Context, identifier string) (*platformmodels.User, error)
- func (p *StaticAuthProvider) Name() string
- func (p *StaticAuthProvider) Priority() int
- func (p *StaticAuthProvider) ValidateToken(ctx context.Context, token string) (*platformmodels.User, error)
- type TOTPAuditEvent
- type TOTPSessionManager
- func (m *TOTPSessionManager) CreateAgentSession(userID int, username, clientIP, userAgent string) (string, error)
- func (m *TOTPSessionManager) CreateCustomerSession(userLogin, clientIP, userAgent string) (string, error)
- func (m *TOTPSessionManager) GenerateHMAC(data string) string
- func (m *TOTPSessionManager) GetRemainingAttempts(token string) int
- func (m *TOTPSessionManager) InvalidateSession(token string)
- func (m *TOTPSessionManager) RecordFailedAttempt(token string) int
- func (m *TOTPSessionManager) Stats() map[string]int
- func (m *TOTPSessionManager) ValidateAndGetSession(token, clientIP, userAgent string) *PendingTOTPSession
- func (m *TOTPSessionManager) VerifyHMAC(data, signature string) bool
- type UserLookup
Constants ¶
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.
const ( AccountKindAgent = "agent" AccountKindCustomer = "customer" )
Account kinds carried by refresh tokens: agents live in users, customers in customer_user, and their ids overlap.
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.
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
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 ¶
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.
var ( ErrInvalidToken = errors.New("invalid token") ErrExpiredToken = errors.New("token has expired") )
var DefaultLoginRateLimiter = NewLoginRateLimiter(5, 300, 2*time.Second, 60*time.Second)
DefaultLoginRateLimiter is the global instance for login rate limiting.
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 ¶
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 LogTOTPAuditEvent ¶
func LogTOTPAuditEvent(event TOTPAuditEvent)
LogTOTPAuditEvent logs a 2FA security event. V8 FIX: Provides audit trail for 2FA events.
func LogTOTPDisabled ¶
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 ¶
LogTOTPSessionLocked logs when a 2FA session is locked due to too many failures.
func LogTOTPSetupCompleted ¶
LogTOTPSetupCompleted logs when 2FA setup is successfully completed.
func LogTOTPSetupStarted ¶
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 ¶
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 ¶
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 (*RBAC) CanAccessAdminPanel ¶
func (*RBAC) CanAccessTicket ¶
func (*RBAC) CanAssignTicket ¶
func (*RBAC) CanCloseTicket ¶
func (*RBAC) CanModifyUser ¶
func (*RBAC) CanViewReports ¶
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.