Documentation
¶
Overview ¶
Package auth provides OIDC authentication and session management.
Package auth provides authentication and authorization for Keldris.
Package auth provides authentication and authorization for Keldris.
Package auth provides email verification for non-OIDC users.
Index ¶
- Constants
- Variables
- func BuildVerificationURL(baseURL, token string) string
- func CompareAPIKeyHash(apiKey, storedHash string) bool
- func DefaultPasswordPolicy() *models.PasswordPolicy
- func ExtractBearerToken(authHeader string) string
- func GenerateState() (string, error)
- func HasRolePermission(role models.OrgRole, perm Permission) bool
- func HashAPIKey(key string) string
- func HashPassword(password string) (string, error)
- func HashToken(token string) string
- func IsValidAPIKeyFormat(apiKey string) bool
- func VerifyPassword(password, hash string) error
- type APIKeyValidator
- type AgentMFA
- func (m *AgentMFA) CleanupExpiredCodes(ctx context.Context) error
- func (m *AgentMFA) GenerateCode(ctx context.Context, orgID, userID uuid.UUID, hostname *string) (*models.RegistrationCode, error)
- func (m *AgentMFA) GetPendingCodes(ctx context.Context, orgID uuid.UUID) ([]*models.RegistrationCode, error)
- func (m *AgentMFA) MarkCodeUsed(ctx context.Context, codeID, agentID uuid.UUID) error
- func (m *AgentMFA) VerifyCode(ctx context.Context, orgID uuid.UUID, code string) (*models.RegistrationCode, error)
- type AgentStore
- type EmailVerificationToken
- type GroupSync
- type GroupSyncStore
- type IDTokenClaims
- type MembershipStore
- type OIDC
- func (o *OIDC) AuthorizationURL(state string) string
- func (o *OIDC) Exchange(ctx context.Context, code string) (*oauth2.Token, error)
- func (o *OIDC) HealthCheck(ctx context.Context) error
- func (o *OIDC) UserInfo(ctx context.Context, token *oauth2.Token) (*oidc.UserInfo, error)
- func (o *OIDC) VerifyIDToken(ctx context.Context, token *oauth2.Token) (*IDTokenClaims, error)
- type OIDCConfig
- type OIDCProvider
- type PasswordPolicyStore
- type PasswordResetService
- func (s *PasswordResetService) CleanupExpiredTokens(ctx context.Context) error
- func (s *PasswordResetService) RequestReset(ctx context.Context, email, ipAddress, userAgent string) (*ResetRequest, error)
- func (s *PasswordResetService) ResetPassword(ctx context.Context, token, newPassword, ipAddress, userAgent string) error
- func (s *PasswordResetService) ValidateToken(ctx context.Context, token string) (*models.User, error)
- type PasswordResetStore
- type PasswordValidator
- func (v *PasswordValidator) RecordPasswordChange(ctx context.Context, orgID, userID uuid.UUID, passwordHash string) error
- func (v *PasswordValidator) ValidateAgainstPolicy(password string, policy *models.PasswordPolicy) *ValidationResult
- func (v *PasswordValidator) ValidatePassword(ctx context.Context, orgID uuid.UUID, password string) (*ValidationResult, error)
- func (v *PasswordValidator) ValidatePasswordWithHistory(ctx context.Context, orgID, userID uuid.UUID, password string) (*ValidationResult, error)
- type Permission
- type RBAC
- func (r *RBAC) CanAssignRole(ctx context.Context, actorID, orgID uuid.UUID, targetRole models.OrgRole) (bool, error)
- func (r *RBAC) CanManageMember(ctx context.Context, actorID, targetID, orgID uuid.UUID) (bool, error)
- func (r *RBAC) GetUserRole(ctx context.Context, userID, orgID uuid.UUID) (models.OrgRole, error)
- func (r *RBAC) HasPermission(ctx context.Context, userID, orgID uuid.UUID, perm Permission) (bool, error)
- func (r *RBAC) RequirePermission(ctx context.Context, userID, orgID uuid.UUID, perm Permission) error
- type RegistrationCodeStore
- type ResetRequest
- type SessionConfig
- type SessionStore
- func (s *SessionStore) ClearUser(r *http.Request, w http.ResponseWriter) error
- func (s *SessionStore) EndImpersonation(r *http.Request, w http.ResponseWriter, originalUser *SessionUser) error
- func (s *SessionStore) Get(r *http.Request) (*sessions.Session, error)
- func (s *SessionStore) GetImpersonationLogID(r *http.Request) (uuid.UUID, error)
- func (s *SessionStore) GetOIDCState(r *http.Request, w http.ResponseWriter) (string, error)
- func (s *SessionStore) GetOriginalUserID(r *http.Request) uuid.UUID
- func (s *SessionStore) GetUser(r *http.Request) (*SessionUser, error)
- func (s *SessionStore) IsAuthenticated(r *http.Request) bool
- func (s *SessionStore) IsImpersonating(r *http.Request) bool
- func (s *SessionStore) Save(r *http.Request, w http.ResponseWriter, session *sessions.Session) error
- func (s *SessionStore) SetCurrentOrg(r *http.Request, w http.ResponseWriter, orgID uuid.UUID, role string) error
- func (s *SessionStore) SetOIDCState(r *http.Request, w http.ResponseWriter, state string) error
- func (s *SessionStore) SetSuperuserStatus(r *http.Request, w http.ResponseWriter, isSuperuser bool) error
- func (s *SessionStore) SetUser(r *http.Request, w http.ResponseWriter, user *SessionUser) error
- func (s *SessionStore) StartImpersonation(r *http.Request, w http.ResponseWriter, originalUser *SessionUser, ...) error
- func (s *SessionStore) TouchSession(r *http.Request, w http.ResponseWriter) error
- type SessionUser
- type Superuser
- func (s *Superuser) GetAllOrganizations(ctx context.Context, userID uuid.UUID) ([]*models.Organization, error)
- func (s *Superuser) GetAllUsers(ctx context.Context, userID uuid.UUID) ([]*models.User, error)
- func (s *Superuser) GetSystemSetting(ctx context.Context, userID uuid.UUID, key string) (*models.SystemSetting, error)
- func (s *Superuser) GetSystemSettings(ctx context.Context, userID uuid.UUID) ([]*models.SystemSetting, error)
- func (s *Superuser) GrantSuperuser(ctx context.Context, grantedBy, targetUserID uuid.UUID) error
- func (s *Superuser) IsSuperuser(ctx context.Context, userID uuid.UUID) (bool, error)
- func (s *Superuser) RequireSuperuser(ctx context.Context, userID uuid.UUID) error
- func (s *Superuser) RevokeSuperuser(ctx context.Context, revokedBy, targetUserID uuid.UUID) error
- func (s *Superuser) UpdateSystemSetting(ctx context.Context, userID uuid.UUID, key string, value interface{}) error
- type SuperuserStore
- type UserVerificationStatus
- type ValidationResult
- type VerifiableUser
- type VerificationConfig
- type VerificationService
- func (s *VerificationService) GenerateToken(ctx context.Context, userID uuid.UUID) (string, error)
- func (s *VerificationService) GetUserVerificationStatus(ctx context.Context, userID uuid.UUID) (*UserVerificationStatus, error)
- func (s *VerificationService) ResendVerification(ctx context.Context, userID uuid.UUID) (string, error)
- func (s *VerificationService) VerifyToken(ctx context.Context, rawToken string) error
- type VerificationStore
Constants ¶
const ( // RegistrationCodeLength is the length of generated registration codes. RegistrationCodeLength = 8 // RegistrationCodeExpiration is how long registration codes are valid. RegistrationCodeExpiration = 10 * time.Minute // RegistrationCodeChars is the character set for registration codes. // Using uppercase letters and digits, excluding ambiguous characters (0, O, I, L, 1). RegistrationCodeChars = "ABCDEFGHJKMNPQRSTUVWXYZ23456789" )
const ( // APIKeyPrefix is the prefix for all Keldris API keys. APIKeyPrefix = "kld_" // APIKeyLength is the expected length of the hex portion of the API key. APIKeyLength = 64 // 32 bytes = 64 hex chars )
const ( // TokenExpiryDuration is the duration before a reset token expires. TokenExpiryDuration = 1 * time.Hour // TokenLength is the length of the reset token in bytes (before hex encoding). TokenLength = 32 // MaxResetAttemptsPerEmail is the maximum number of reset requests per email per window. MaxResetAttemptsPerEmail = 3 // MaxResetAttemptsPerIP is the maximum number of reset requests per IP per window. MaxResetAttemptsPerIP = 5 // RateLimitWindow is the duration of the rate limit window. RateLimitWindow = 15 * time.Minute )
const ( // SessionName is the name of the session cookie. SessionName = "keldris_session" // StateKey is the session key for OIDC state. StateKey = "oidc_state" // UserIDKey is the session key for the authenticated user ID. UserIDKey = "user_id" // OIDCSubjectKey is the session key for the OIDC subject. OIDCSubjectKey = "oidc_subject" // EmailKey is the session key for the user's email. EmailKey = "email" // NameKey is the session key for the user's name. NameKey = "name" // AuthenticatedAtKey is the session key for when the user authenticated. AuthenticatedAtKey = "authenticated_at" // CurrentOrgIDKey is the session key for the currently selected organization. CurrentOrgIDKey = "current_org_id" // CurrentOrgRoleKey is the session key for the user's role in the current org. CurrentOrgRoleKey = "current_org_role" // LastActivityKey is the session key for the last activity timestamp. LastActivityKey = "last_activity" // SessionRecordIDKey is the session key for the database session record ID. SessionRecordIDKey = "session_record_id" // IsSuperuserKey is the session key for superuser status. IsSuperuserKey = "is_superuser" // ImpersonatingKey is the session key for impersonation state. ImpersonatingKey = "impersonating" // ImpersonatingUserIDKey is the session key for the user being impersonated. ImpersonatingUserIDKey = "impersonating_user_id" // OriginalUserIDKey is the session key for the original superuser ID during impersonation. OriginalUserIDKey = "original_user_id" // OriginalUserEmailKey is the session key for the original user email during impersonation. OriginalUserEmailKey = "original_user_email" // ImpersonationLogIDKey is the session key for the impersonation log ID. ImpersonationLogIDKey = "impersonation_log_id" )
Variables ¶
var ( ErrPasswordTooShort = errors.New("password is too short") ErrPasswordNoUppercase = errors.New("password must contain at least one uppercase letter") ErrPasswordNoLowercase = errors.New("password must contain at least one lowercase letter") ErrPasswordNoNumber = errors.New("password must contain at least one number") ErrPasswordNoSpecial = errors.New("password must contain at least one special character") ErrPasswordInHistory = errors.New("password has been used recently") ErrPasswordMismatch = errors.New("current password is incorrect") ErrPasswordExpired = errors.New("password has expired") ErrPasswordChangeRequired = errors.New("password change is required") )
Common password validation errors.
var ( ErrResetTokenExpired = errors.New("reset token has expired") ErrResetTokenUsed = errors.New("reset token has already been used") ErrResetTokenInvalid = errors.New("invalid reset token") ErrResetRateLimited = errors.New("too many password reset requests") ErrUserNoPasswordAuth = errors.New("user does not have password authentication") ErrUserOIDCOnly = errors.New("user uses OIDC authentication only") )
Common password reset errors.
var ( ErrTokenExpired = errors.New("verification token has expired") ErrTokenAlreadyUsed = errors.New("verification token has already been used") ErrTokenNotFound = errors.New("verification token not found") ErrUserAlreadyVerified = errors.New("user email is already verified") ErrUserNotFound = errors.New("user not found") )
Common errors for email verification.
var ErrCannotRevokeSelf = fmt.Errorf("cannot revoke own superuser privileges")
ErrCannotRevokeSelf is returned when a superuser tries to revoke their own privileges.
var ErrLastSuperuser = fmt.Errorf("cannot remove the last superuser")
ErrLastSuperuser is returned when attempting to remove the last superuser.
var ErrNotMember = fmt.Errorf("not a member of this organization")
ErrNotMember is returned when a user is not a member of the organization.
var ErrNotSuperuser = fmt.Errorf("superuser privileges required")
ErrNotSuperuser is returned when a user is not a superuser.
var ErrPermissionDenied = fmt.Errorf("permission denied")
ErrPermissionDenied is returned when a user lacks required permissions.
Functions ¶
func BuildVerificationURL ¶
BuildVerificationURL builds the verification URL for an email.
func CompareAPIKeyHash ¶
CompareAPIKeyHash compares an API key with a stored hash using constant-time comparison.
func DefaultPasswordPolicy ¶
func DefaultPasswordPolicy() *models.PasswordPolicy
DefaultPasswordPolicy returns a default password policy for organizations without one.
func ExtractBearerToken ¶
ExtractBearerToken extracts the token from an Authorization header value. Returns empty string if the header is not a valid Bearer token.
func GenerateState ¶
GenerateState generates a cryptographically secure random state parameter.
func HasRolePermission ¶
func HasRolePermission(role models.OrgRole, perm Permission) bool
HasRolePermission checks if a role has the given permission.
func HashAPIKey ¶
HashAPIKey creates a SHA-256 hash of an API key for storage/comparison.
func HashPassword ¶
HashPassword creates a bcrypt hash of the password.
func IsValidAPIKeyFormat ¶
IsValidAPIKeyFormat checks if the API key has the correct format.
func VerifyPassword ¶
VerifyPassword compares a password with its hash.
Types ¶
type APIKeyValidator ¶
type APIKeyValidator struct {
// contains filtered or unexported fields
}
APIKeyValidator validates API keys and retrieves associated agents.
func NewAPIKeyValidator ¶
func NewAPIKeyValidator(store AgentStore, logger zerolog.Logger) *APIKeyValidator
NewAPIKeyValidator creates a new API key validator.
func (*APIKeyValidator) ValidateAPIKey ¶
ValidateAPIKey validates an API key and returns the associated agent. Returns nil if the key is invalid or not found.
type AgentMFA ¶
type AgentMFA struct {
// contains filtered or unexported fields
}
AgentMFA handles agent registration code generation and verification.
func NewAgentMFA ¶
func NewAgentMFA(store RegistrationCodeStore, logger zerolog.Logger) *AgentMFA
NewAgentMFA creates a new AgentMFA instance.
func (*AgentMFA) CleanupExpiredCodes ¶
CleanupExpiredCodes removes expired registration codes from the database.
func (*AgentMFA) GenerateCode ¶
func (m *AgentMFA) GenerateCode(ctx context.Context, orgID, userID uuid.UUID, hostname *string) (*models.RegistrationCode, error)
GenerateCode generates a new registration code for an organization.
func (*AgentMFA) GetPendingCodes ¶
func (m *AgentMFA) GetPendingCodes(ctx context.Context, orgID uuid.UUID) ([]*models.RegistrationCode, error)
GetPendingCodes returns all pending (unused, unexpired) registration codes for an organization.
func (*AgentMFA) MarkCodeUsed ¶
MarkCodeUsed marks a registration code as used by an agent.
type AgentStore ¶
type AgentStore interface {
GetAgentByAPIKeyHash(ctx context.Context, hash string) (*models.Agent, error)
}
AgentStore defines the interface for agent lookup operations.
type EmailVerificationToken ¶
type EmailVerificationToken struct {
ID uuid.UUID `json:"id"`
UserID uuid.UUID `json:"user_id"`
TokenHash string `json:"-"` // Never expose token hash
ExpiresAt time.Time `json:"expires_at"`
UsedAt *time.Time `json:"used_at,omitempty"`
CreatedAt time.Time `json:"created_at"`
}
EmailVerificationToken represents a verification token for email verification.
func NewEmailVerificationToken ¶
func NewEmailVerificationToken(userID uuid.UUID, expiresIn time.Duration) (*EmailVerificationToken, string, error)
NewEmailVerificationToken creates a new verification token for a user.
func (*EmailVerificationToken) IsExpired ¶
func (t *EmailVerificationToken) IsExpired() bool
IsExpired returns true if the token has expired.
func (*EmailVerificationToken) IsUsed ¶
func (t *EmailVerificationToken) IsUsed() bool
IsUsed returns true if the token has been used.
type GroupSync ¶
type GroupSync struct {
// contains filtered or unexported fields
}
GroupSync handles OIDC group synchronization to Keldris roles.
func NewGroupSync ¶
func NewGroupSync(store GroupSyncStore, logger zerolog.Logger) *GroupSync
NewGroupSync creates a new GroupSync instance.
func (*GroupSync) ExtractGroupsFromToken ¶
func (gs *GroupSync) ExtractGroupsFromToken(ctx context.Context, oidc *OIDC, token *oauth2.Token) ([]string, error)
ExtractGroupsFromToken extracts groups from an OIDC token. Different OIDC providers use different claim names for groups.
func (*GroupSync) SyncUserGroups ¶
func (gs *GroupSync) SyncUserGroups(ctx context.Context, userID uuid.UUID, groups []string) (*models.GroupSyncResult, error)
SyncUserGroups syncs a user's OIDC groups to Keldris memberships. This should be called during login after extracting groups from the token.
type GroupSyncStore ¶
type GroupSyncStore interface {
// Group mapping operations
GetSSOGroupMappingsByGroupNames(ctx context.Context, groupNames []string) ([]*models.SSOGroupMapping, error)
GetSSOGroupMappingsByOrgID(ctx context.Context, orgID uuid.UUID) ([]*models.SSOGroupMapping, error)
// User SSO groups operations
GetUserSSOGroups(ctx context.Context, userID uuid.UUID) (*models.UserSSOGroups, error)
UpsertUserSSOGroups(ctx context.Context, userID uuid.UUID, groups []string) error
// Membership operations
GetMembershipsByUserID(ctx context.Context, userID uuid.UUID) ([]*models.OrgMembership, error)
GetMembershipByUserAndOrg(ctx context.Context, userID, orgID uuid.UUID) (*models.OrgMembership, error)
CreateMembership(ctx context.Context, m *models.OrgMembership) error
UpdateMembershipRole(ctx context.Context, membershipID uuid.UUID, role models.OrgRole) error
// Organization operations
GetOrganizationByID(ctx context.Context, id uuid.UUID) (*models.Organization, error)
GetOrganizationSSOSettings(ctx context.Context, orgID uuid.UUID) (defaultRole *string, autoCreateOrgs bool, err error)
}
GroupSyncStore defines the interface for group sync persistence operations.
type IDTokenClaims ¶
type IDTokenClaims struct {
Subject string `json:"sub"`
Email string `json:"email"`
Name string `json:"name"`
}
IDTokenClaims holds the standard claims from an ID token.
type MembershipStore ¶
type MembershipStore interface {
GetMembershipByUserAndOrg(ctx context.Context, userID, orgID uuid.UUID) (*models.OrgMembership, error)
GetMembershipsByUserID(ctx context.Context, userID uuid.UUID) ([]*models.OrgMembership, error)
}
MembershipStore defines the interface for fetching membership data.
type OIDC ¶
type OIDC struct {
// contains filtered or unexported fields
}
OIDC wraps the OIDC provider and OAuth2 configuration.
func (*OIDC) AuthorizationURL ¶
AuthorizationURL returns the URL to redirect users for authentication.
func (*OIDC) HealthCheck ¶
HealthCheck verifies that the OIDC provider is reachable by fetching its discovery document.
func (*OIDC) VerifyIDToken ¶
VerifyIDToken verifies the ID token and extracts claims.
type OIDCConfig ¶
type OIDCConfig struct {
Issuer string
ClientID string
ClientSecret string
RedirectURL string
Scopes []string
}
OIDCConfig holds OIDC provider configuration.
func DefaultOIDCConfig ¶
func DefaultOIDCConfig(issuer, clientID, clientSecret, redirectURL string) OIDCConfig
DefaultOIDCConfig returns an OIDCConfig with standard scopes.
type OIDCProvider ¶
type OIDCProvider struct {
// contains filtered or unexported fields
}
OIDCProvider is a thread-safe wrapper around an OIDC provider that supports hot-reloading when OIDC settings change at runtime.
func NewOIDCProvider ¶
func NewOIDCProvider(provider *OIDC, logger zerolog.Logger) *OIDCProvider
NewOIDCProvider creates a new OIDCProvider wrapper. The initial provider can be nil (password-only mode).
func (*OIDCProvider) Get ¶
func (p *OIDCProvider) Get() *OIDC
Get returns the current OIDC provider instance (may be nil).
func (*OIDCProvider) HealthCheck ¶
func (p *OIDCProvider) HealthCheck(ctx context.Context) error
HealthCheck delegates to the underlying provider's health check. Returns nil if no provider is configured (OIDC is optional).
func (*OIDCProvider) IsConfigured ¶
func (p *OIDCProvider) IsConfigured() bool
IsConfigured returns true if an OIDC provider is currently loaded.
func (*OIDCProvider) Update ¶
func (p *OIDCProvider) Update(ctx context.Context, cfg OIDCConfig) error
Update creates a new OIDC provider from the given config and swaps it in. If initialization fails, the old provider is kept.
type PasswordPolicyStore ¶
type PasswordPolicyStore interface {
GetPasswordPolicyByOrgID(ctx context.Context, orgID uuid.UUID) (*models.PasswordPolicy, error)
GetPasswordHistory(ctx context.Context, userID uuid.UUID, limit int) ([]*models.PasswordHistory, error)
CreatePasswordHistory(ctx context.Context, history *models.PasswordHistory) error
CleanupPasswordHistory(ctx context.Context, userID uuid.UUID, keepCount int) error
}
PasswordPolicyStore defines the interface for password policy data access.
type PasswordResetService ¶
type PasswordResetService struct {
// contains filtered or unexported fields
}
PasswordResetService handles password reset operations.
func NewPasswordResetService ¶
func NewPasswordResetService(store PasswordResetStore, logger zerolog.Logger) *PasswordResetService
NewPasswordResetService creates a new PasswordResetService.
func (*PasswordResetService) CleanupExpiredTokens ¶
func (s *PasswordResetService) CleanupExpiredTokens(ctx context.Context) error
CleanupExpiredTokens removes expired reset tokens and rate limit entries.
func (*PasswordResetService) RequestReset ¶
func (s *PasswordResetService) RequestReset(ctx context.Context, email, ipAddress, userAgent string) (*ResetRequest, error)
RequestReset initiates a password reset for the given email. Returns the reset token and user info for sending the reset email. Always returns success to prevent email enumeration, but only generates a token if the user exists and has password auth.
func (*PasswordResetService) ResetPassword ¶
func (s *PasswordResetService) ResetPassword(ctx context.Context, token, newPassword, ipAddress, userAgent string) error
ResetPassword resets the user's password using a valid token.
func (*PasswordResetService) ValidateToken ¶
func (s *PasswordResetService) ValidateToken(ctx context.Context, token string) (*models.User, error)
ValidateToken validates a password reset token and returns the associated user.
type PasswordResetStore ¶
type PasswordResetStore interface {
// User methods
GetUserByEmail(ctx context.Context, email string) (*models.User, error)
GetUserByID(ctx context.Context, id uuid.UUID) (*models.User, error)
HasPasswordAuth(ctx context.Context, userID uuid.UUID) (bool, error)
// Token methods
CreatePasswordResetToken(ctx context.Context, token *models.PasswordResetToken) error
GetPasswordResetTokenByHash(ctx context.Context, tokenHash string) (*models.PasswordResetToken, error)
MarkPasswordResetTokenUsed(ctx context.Context, tokenID uuid.UUID) error
InvalidateUserResetTokens(ctx context.Context, userID uuid.UUID) error
// Rate limiting methods
GetResetRateLimit(ctx context.Context, identifier, identifierType string) (*models.PasswordResetRateLimit, error)
IncrementResetRateLimit(ctx context.Context, identifier, identifierType string, windowDuration time.Duration) error
CleanupExpiredRateLimits(ctx context.Context, windowDuration time.Duration) error
// Password update
UpdateUserPassword(ctx context.Context, userID uuid.UUID, passwordHash string, expiresAt *time.Time) error
GetPasswordPolicyByOrgID(ctx context.Context, orgID uuid.UUID) (*models.PasswordPolicy, error)
// Audit logging
CreateAuditLog(ctx context.Context, log *models.AuditLog) error
}
PasswordResetStore defines the interface for password reset data access.
type PasswordValidator ¶
type PasswordValidator struct {
// contains filtered or unexported fields
}
PasswordValidator handles password validation against policies.
func NewPasswordValidator ¶
func NewPasswordValidator(store PasswordPolicyStore) *PasswordValidator
NewPasswordValidator creates a new PasswordValidator.
func (*PasswordValidator) RecordPasswordChange ¶
func (v *PasswordValidator) RecordPasswordChange(ctx context.Context, orgID, userID uuid.UUID, passwordHash string) error
RecordPasswordChange records a password change in history.
func (*PasswordValidator) ValidateAgainstPolicy ¶
func (v *PasswordValidator) ValidateAgainstPolicy(password string, policy *models.PasswordPolicy) *ValidationResult
ValidateAgainstPolicy validates a password against a specific policy.
func (*PasswordValidator) ValidatePassword ¶
func (v *PasswordValidator) ValidatePassword(ctx context.Context, orgID uuid.UUID, password string) (*ValidationResult, error)
ValidatePassword validates a password against the organization's policy.
func (*PasswordValidator) ValidatePasswordWithHistory ¶
func (v *PasswordValidator) ValidatePasswordWithHistory(ctx context.Context, orgID, userID uuid.UUID, password string) (*ValidationResult, error)
ValidatePasswordWithHistory validates a password against policy and history.
type Permission ¶
type Permission string
Permission defines an action that can be performed.
const ( // Organization permissions PermOrgRead Permission = "org:read" PermOrgUpdate Permission = "org:update" PermOrgDelete Permission = "org:delete" // Member management permissions PermMemberRead Permission = "member:read" PermMemberInvite Permission = "member:invite" PermMemberUpdate Permission = "member:update" PermMemberRemove Permission = "member:remove" // User management permissions (admin-level control) PermUserRead Permission = "user:read" PermUserInvite Permission = "user:invite" PermUserUpdate Permission = "user:update" PermUserDisable Permission = "user:disable" PermUserDelete Permission = "user:delete" PermUserResetPassword Permission = "user:reset_password" PermUserImpersonate Permission = "user:impersonate" PermUserActivityView Permission = "user:activity_view" // Agent permissions PermAgentRead Permission = "agent:read" PermAgentCreate Permission = "agent:create" PermAgentUpdate Permission = "agent:update" PermAgentDelete Permission = "agent:delete" // Repository permissions PermRepoRead Permission = "repo:read" PermRepoCreate Permission = "repo:create" PermRepoUpdate Permission = "repo:update" PermRepoDelete Permission = "repo:delete" // Schedule permissions PermScheduleRead Permission = "schedule:read" PermScheduleCreate Permission = "schedule:create" PermScheduleUpdate Permission = "schedule:update" PermScheduleDelete Permission = "schedule:delete" PermScheduleRun Permission = "schedule:run" // Backup permissions PermBackupRead Permission = "backup:read" PermBackupCreate Permission = "backup:create" )
type RBAC ¶
type RBAC struct {
// contains filtered or unexported fields
}
RBAC provides role-based access control functionality.
func (*RBAC) CanAssignRole ¶
func (r *RBAC) CanAssignRole(ctx context.Context, actorID, orgID uuid.UUID, targetRole models.OrgRole) (bool, error)
CanAssignRole checks if a user can assign a specific role to another user.
func (*RBAC) CanManageMember ¶
func (r *RBAC) CanManageMember(ctx context.Context, actorID, targetID, orgID uuid.UUID) (bool, error)
CanManageMember checks if a user can manage (update/remove) another member. Owners can manage anyone. Admins can manage members and readonly, but not other admins or owners.
func (*RBAC) GetUserRole ¶
GetUserRole returns the user's role in the organization.
func (*RBAC) HasPermission ¶
func (r *RBAC) HasPermission(ctx context.Context, userID, orgID uuid.UUID, perm Permission) (bool, error)
HasPermission checks if the user has the given permission in the organization.
func (*RBAC) RequirePermission ¶
func (r *RBAC) RequirePermission(ctx context.Context, userID, orgID uuid.UUID, perm Permission) error
RequirePermission checks if the user has permission and returns an error if not.
type RegistrationCodeStore ¶
type RegistrationCodeStore interface {
CreateRegistrationCode(ctx context.Context, code *models.RegistrationCode) error
GetRegistrationCodeByCode(ctx context.Context, orgID uuid.UUID, code string) (*models.RegistrationCode, error)
GetPendingRegistrationCodes(ctx context.Context, orgID uuid.UUID) ([]*models.RegistrationCode, error)
MarkRegistrationCodeUsed(ctx context.Context, codeID, agentID uuid.UUID) error
DeleteExpiredRegistrationCodes(ctx context.Context) error
}
RegistrationCodeStore defines the interface for registration code persistence.
type ResetRequest ¶
type ResetRequest struct {
Token string // The plain-text token to send to the user
ExpiresAt time.Time // When the token expires
UserID uuid.UUID // The user's ID
UserEmail string // The user's email
UserName string // The user's name
}
ResetRequest contains the result of a password reset request.
type SessionConfig ¶
type SessionConfig struct {
Secret []byte
MaxAge int // seconds
IdleTimeout int // seconds, 0 to disable
Secure bool // require HTTPS
HTTPOnly bool // prevent JavaScript access
SameSite http.SameSite
CookiePath string
}
SessionConfig holds session store configuration.
func DefaultSessionConfig ¶
func DefaultSessionConfig(secret []byte, secure bool, maxAge, idleTimeout int) SessionConfig
DefaultSessionConfig returns a SessionConfig with secure defaults. maxAge in seconds (0 or negative uses default 86400). idleTimeout in seconds (0 disables idle timeout, negative uses default 1800).
type SessionStore ¶
type SessionStore struct {
// contains filtered or unexported fields
}
SessionStore wraps a gorilla/sessions store with helper methods.
func NewSessionStore ¶
func NewSessionStore(cfg SessionConfig, logger zerolog.Logger) (*SessionStore, error)
NewSessionStore creates a new session store.
func (*SessionStore) ClearUser ¶
func (s *SessionStore) ClearUser(r *http.Request, w http.ResponseWriter) error
ClearUser removes user data from the session (logout).
func (*SessionStore) EndImpersonation ¶
func (s *SessionStore) EndImpersonation(r *http.Request, w http.ResponseWriter, originalUser *SessionUser) error
EndImpersonation restores the original superuser session.
func (*SessionStore) GetImpersonationLogID ¶
GetImpersonationLogID returns the current impersonation log ID if impersonating.
func (*SessionStore) GetOIDCState ¶
func (s *SessionStore) GetOIDCState(r *http.Request, w http.ResponseWriter) (string, error)
GetOIDCState retrieves and clears the OIDC state from the session.
func (*SessionStore) GetOriginalUserID ¶
func (s *SessionStore) GetOriginalUserID(r *http.Request) uuid.UUID
GetOriginalUserID returns the original superuser ID during impersonation.
func (*SessionStore) GetUser ¶
func (s *SessionStore) GetUser(r *http.Request) (*SessionUser, error)
GetUser retrieves the authenticated user from the session.
func (*SessionStore) IsAuthenticated ¶
func (s *SessionStore) IsAuthenticated(r *http.Request) bool
IsAuthenticated checks if the session has a valid authenticated user.
func (*SessionStore) IsImpersonating ¶
func (s *SessionStore) IsImpersonating(r *http.Request) bool
IsImpersonating checks if the current session is in impersonation mode.
func (*SessionStore) Save ¶
func (s *SessionStore) Save(r *http.Request, w http.ResponseWriter, session *sessions.Session) error
Save saves the session to the response.
func (*SessionStore) SetCurrentOrg ¶
func (s *SessionStore) SetCurrentOrg(r *http.Request, w http.ResponseWriter, orgID uuid.UUID, role string) error
SetCurrentOrg updates the current organization in the session.
func (*SessionStore) SetOIDCState ¶
func (s *SessionStore) SetOIDCState(r *http.Request, w http.ResponseWriter, state string) error
SetOIDCState stores the OIDC state in the session.
func (*SessionStore) SetSuperuserStatus ¶
func (s *SessionStore) SetSuperuserStatus(r *http.Request, w http.ResponseWriter, isSuperuser bool) error
SetSuperuserStatus updates the superuser status in the session.
func (*SessionStore) SetUser ¶
func (s *SessionStore) SetUser(r *http.Request, w http.ResponseWriter, user *SessionUser) error
SetUser stores user data in the session after successful authentication.
func (*SessionStore) StartImpersonation ¶
func (s *SessionStore) StartImpersonation(r *http.Request, w http.ResponseWriter, originalUser *SessionUser, targetUser *SessionUser, logID uuid.UUID) error
StartImpersonation sets up impersonation mode where a superuser acts as another user.
func (*SessionStore) TouchSession ¶
func (s *SessionStore) TouchSession(r *http.Request, w http.ResponseWriter) error
TouchSession updates the last activity timestamp to keep the session alive. Call this on each authenticated request to track idle timeout.
type SessionUser ¶
type SessionUser struct {
ID uuid.UUID
OIDCSubject string
Email string
Name string
AuthenticatedAt time.Time
CurrentOrgID uuid.UUID
CurrentOrgRole string
SessionRecordID uuid.UUID
IsSuperuser bool
// Impersonation fields
Impersonating bool
ImpersonatingID uuid.UUID // The user being impersonated (if any)
OriginalUserID uuid.UUID // The original superuser ID (during impersonation)
OriginalUserEmail string
ImpersonationLogID uuid.UUID
}
SessionUser represents the authenticated user data stored in session.
func (*SessionUser) IsImpersonating ¶
func (u *SessionUser) IsImpersonating() bool
IsImpersonating returns true if the user is being impersonated.
type Superuser ¶
type Superuser struct {
// contains filtered or unexported fields
}
Superuser provides superuser authorization checks.
func NewSuperuser ¶
func NewSuperuser(store SuperuserStore) *Superuser
NewSuperuser creates a new Superuser instance.
func (*Superuser) GetAllOrganizations ¶
func (s *Superuser) GetAllOrganizations(ctx context.Context, userID uuid.UUID) ([]*models.Organization, error)
GetAllOrganizations returns all organizations (superuser only).
func (*Superuser) GetAllUsers ¶
GetAllUsers returns all users across all organizations (superuser only).
func (*Superuser) GetSystemSetting ¶
func (s *Superuser) GetSystemSetting(ctx context.Context, userID uuid.UUID, key string) (*models.SystemSetting, error)
GetSystemSetting returns a system setting by key (superuser only).
func (*Superuser) GetSystemSettings ¶
func (s *Superuser) GetSystemSettings(ctx context.Context, userID uuid.UUID) ([]*models.SystemSetting, error)
GetSystemSettings returns all system settings (superuser only).
func (*Superuser) GrantSuperuser ¶
GrantSuperuser grants superuser privileges to a user.
func (*Superuser) IsSuperuser ¶
IsSuperuser checks if the user with the given ID is a superuser.
func (*Superuser) RequireSuperuser ¶
RequireSuperuser checks if the user is a superuser and returns an error if not.
func (*Superuser) RevokeSuperuser ¶
RevokeSuperuser revokes superuser privileges from a user.
type SuperuserStore ¶
type SuperuserStore interface {
GetUserByID(ctx context.Context, id uuid.UUID) (*models.User, error)
GetAllOrganizations(ctx context.Context) ([]*models.Organization, error)
GetAllUsers(ctx context.Context) ([]*models.User, error)
SetUserSuperuser(ctx context.Context, userID uuid.UUID, isSuperuser bool) error
GetSuperusers(ctx context.Context) ([]*models.User, error)
GetUserByEmail(ctx context.Context, email string) (*models.User, error)
CreateSuperuserAuditLog(ctx context.Context, log *models.SuperuserAuditLog) error
GetSuperuserAuditLogs(ctx context.Context, limit, offset int) ([]*models.SuperuserAuditLogWithUser, int, error)
GetSystemSetting(ctx context.Context, key string) (*models.SystemSetting, error)
GetSystemSettings(ctx context.Context) ([]*models.SystemSetting, error)
UpdateSystemSetting(ctx context.Context, key string, value interface{}, updatedBy uuid.UUID) error
}
SuperuserStore defines the interface for superuser-related data operations.
type UserVerificationStatus ¶
type UserVerificationStatus struct {
UserID uuid.UUID `json:"user_id"`
Email string `json:"email"`
IsVerified bool `json:"is_verified"`
IsOIDCUser bool `json:"is_oidc_user"`
RequiresEmail bool `json:"requires_email"` // True if user needs to verify email
}
GetUserVerificationStatus returns the verification status for a user.
type ValidationResult ¶
type ValidationResult struct {
Valid bool `json:"valid"`
Errors []string `json:"errors,omitempty"`
Warnings []string `json:"warnings,omitempty"`
}
ValidationResult contains the result of password validation.
type VerifiableUser ¶
type VerifiableUser interface {
GetID() uuid.UUID
GetEmail() string
IsEmailVerified() bool
IsOIDCUser() bool
}
VerifiableUser represents a user that can be verified.
type VerificationConfig ¶
type VerificationConfig struct {
TokenExpiration time.Duration // How long verification tokens are valid
ResendCooldown time.Duration // Minimum time between resend requests
MaxTokensPerUser int // Maximum active tokens per user
}
VerificationConfig holds configuration for the verification service.
func DefaultVerificationConfig ¶
func DefaultVerificationConfig() VerificationConfig
DefaultVerificationConfig returns a VerificationConfig with sensible defaults.
type VerificationService ¶
type VerificationService struct {
// contains filtered or unexported fields
}
VerificationService handles email verification operations.
func NewVerificationService ¶
func NewVerificationService(store VerificationStore, config VerificationConfig, logger zerolog.Logger) *VerificationService
NewVerificationService creates a new verification service.
func (*VerificationService) GenerateToken ¶
GenerateToken creates a new verification token for a user. Returns the raw token that should be sent to the user via email.
func (*VerificationService) GetUserVerificationStatus ¶
func (s *VerificationService) GetUserVerificationStatus(ctx context.Context, userID uuid.UUID) (*UserVerificationStatus, error)
GetUserVerificationStatus returns verification status for a user.
func (*VerificationService) ResendVerification ¶
func (s *VerificationService) ResendVerification(ctx context.Context, userID uuid.UUID) (string, error)
ResendVerification generates a new verification token for a user. This can be used when the original token expires or is lost.
func (*VerificationService) VerifyToken ¶
func (s *VerificationService) VerifyToken(ctx context.Context, rawToken string) error
VerifyToken validates a verification token and marks the user's email as verified.
type VerificationStore ¶
type VerificationStore interface {
CreateEmailVerificationToken(ctx context.Context, token *EmailVerificationToken) error
GetEmailVerificationTokenByHash(ctx context.Context, tokenHash string) (*EmailVerificationToken, error)
MarkEmailVerificationTokenUsed(ctx context.Context, tokenID uuid.UUID) error
GetUserByID(ctx context.Context, userID uuid.UUID) (VerifiableUser, error)
SetUserEmailVerified(ctx context.Context, userID uuid.UUID) error
InvalidateUserVerificationTokens(ctx context.Context, userID uuid.UUID) error
}
VerificationStore defines the interface for verification token persistence.