auth

package
v0.0.39 Latest Latest
Warning

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

Go to latest
Published: Nov 10, 2025 License: Apache-2.0 Imports: 12 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// BcryptCost is the cost factor for bcrypt hashing
	BcryptCost = 10

	// MinPasswordLength is the minimum password length
	MinPasswordLength = 8
)
View Source
const (
	RoleAdmin  = "admin"
	RoleUser   = "user"
	RoleViewer = "viewer"
	RoleAgent  = "agent"
)

Standard roles

Variables

View Source
var (
	ErrInvalidCredentials = errors.New("invalid username or password")
	ErrAccountLocked      = errors.New("account is locked")
	ErrAccountDisabled    = errors.New("account is disabled")
	ErrExpiredToken       = errors.New("token has expired")
	ErrInvalidToken       = errors.New("invalid token")
	ErrUserNotFound       = errors.New("user not found")
	ErrUserExists         = errors.New("user already exists")
	ErrWeakPassword       = errors.New("password does not meet requirements")
	ErrUnauthorized       = errors.New("unauthorized")
	ErrForbidden          = errors.New("forbidden")
	ErrInvalidUsername    = errors.New("invalid username format")
	ErrInvalidEmail       = errors.New("invalid email format")
	ErrEmptyPassword      = errors.New("password cannot be empty")
	ErrPasswordTooShort   = errors.New("password is too short")
	ErrSelfDelete         = errors.New("cannot delete your own account")
)

Authentication errors

Functions

func CheckPasswordStrength

func CheckPasswordStrength(password string, requireStrong bool) error

CheckPasswordStrength validates password strength

func HashPassword

func HashPassword(password string) (string, error)

HashPassword hashes a password using bcrypt

func HashRefreshToken

func HashRefreshToken(token string) (string, error)

HashRefreshToken hashes a refresh token for storage

func ValidateEmail

func ValidateEmail(email string) error

ValidateEmail validates email format (basic validation)

func ValidatePassword

func ValidatePassword(password, hash string) error

ValidatePassword checks if a password matches the hash

func ValidateRefreshToken

func ValidateRefreshToken(token, hash string) error

ValidateRefreshToken validates a refresh token against its hash

func ValidateUsername

func ValidateUsername(username string) error

ValidateUsername validates username format

Types

type AuditLog

type AuditLog struct {
	// JSON-LD semantic fields
	Context string `json:"@context,omitempty"` // https://schema.org
	Type    string `json:"@type,omitempty"`    // AssessAction or ControlAction

	// Identity fields
	ID  string `json:"@id,omitempty"`  // Semantic identifier (UUID or timestamp-based)
	Rev string `json:"_rev,omitempty"` // CouchDB revision

	// Schema.org Action properties
	Name         string     `json:"name"`              // Action name (login, logout, create_user, etc.)
	ActionStatus string     `json:"actionStatus"`      // CompletedActionStatus or FailedActionStatus
	StartTime    time.Time  `json:"startTime"`         // When action occurred
	EndTime      *time.Time `json:"endTime,omitempty"` // When action completed (optional)

	// CANONICAL SEMANTIC TYPES (workflow-compatible)
	Agent      *semantic.SemanticAgent      `json:"agent,omitempty"`      // Person who performed action
	Object     *semantic.SemanticObject     `json:"object,omitempty"`     // Resource targeted
	Target     *semantic.EntryPoint         `json:"target,omitempty"`     // HTTP endpoint details (for workflow compat)
	Instrument *semantic.SemanticInstrument `json:"instrument,omitempty"` // Tool/client used
	Result     *semantic.SemanticResult     `json:"result,omitempty"`     // Success result
	Error      *semantic.SemanticError      `json:"error,omitempty"`      // Error details if failed

	// Additional properties
	Properties map[string]interface{} `json:"additionalProperty,omitempty"` // Extra metadata

	// Legacy fields (for backward compatibility)
	Timestamp    time.Time              `json:"timestamp,omitempty"`     // Deprecated: use startTime
	UserID       string                 `json:"user_id,omitempty"`       // Deprecated: use agent (no identifier field in SemanticAgent)
	Username     string                 `json:"username,omitempty"`      // Deprecated: use agent.name
	Action       string                 `json:"action,omitempty"`        // Deprecated: use name
	Resource     string                 `json:"resource,omitempty"`      // Deprecated: use object
	ResourceID   string                 `json:"resource_id,omitempty"`   // Deprecated: use object.identifier
	Method       string                 `json:"method,omitempty"`        // Deprecated: use target.httpMethod
	Path         string                 `json:"path,omitempty"`          // Deprecated: use target.url
	IPAddress    string                 `json:"ip_address,omitempty"`    // Deprecated: use properties.ipAddress
	UserAgent    string                 `json:"user_agent,omitempty"`    // Deprecated: use instrument.name
	Success      bool                   `json:"success,omitempty"`       // Deprecated: use actionStatus
	ErrorMessage string                 `json:"error_message,omitempty"` // Deprecated: use error.message
	Metadata     map[string]interface{} `json:"metadata,omitempty"`      // Deprecated: use additionalProperty
}

AuditLog represents an audit log entry as a Schema.org Action Uses canonical semantic types from eve.evalgo.org/semantic for workflow compatibility FULLY WORKFLOW-COMPATIBLE: Can be executed as part of when workflows

type AuditLogger

type AuditLogger interface {
	Log(entry *AuditLog) error
	Query(criteria AuditSearchCriteria) ([]*AuditLog, error)
}

AuditLogger defines audit logging interface

type AuditSearchCriteria

type AuditSearchCriteria struct {
	UserID    string
	Username  string
	Action    string
	Resource  string
	Success   *bool
	StartTime *time.Time
	EndTime   *time.Time
	Limit     int
	Offset    int
}

AuditSearchCriteria represents search criteria for audit logs

type AuthResult

type AuthResult struct {
	User         *User     `json:"user"`
	AccessToken  string    `json:"access_token"`
	RefreshToken string    `json:"refresh_token,omitempty"`
	ExpiresAt    time.Time `json:"expires_at"`
}

AuthResult represents the result of a successful authentication

type AuthService

type AuthService interface {
	// Authentication
	Login(username, password string) (*AuthResult, error)
	Logout(userID string) error

	// Token management
	GenerateToken(user *User) (string, error)
	ValidateToken(token string) (*Claims, error)
	GenerateTokenPair(user *User) (*TokenPair, error)
	RefreshToken(refreshToken string) (*TokenPair, error)

	// Password management
	ChangePassword(userID, currentPassword, newPassword string) error
	HashPassword(password string) (string, error)
	ValidatePasswordHash(password, hash string) error

	// User management
	CreateUser(req CreateUserRequest) (*User, error)
	UpdateUser(userID string, req UpdateUserRequest) (*User, error)
	DeleteUser(userID string, requestingUserID string) error
	GetUser(userID string) (*User, error)
	GetUserByUsername(username string) (*User, error)
	ListUsers() ([]*User, error)

	// Authorization
	HasRole(userID string, role string) (bool, error)
	HasAnyRole(userID string, roles []string) (bool, error)
}

AuthService provides authentication and authorization

func NewAuthService

func NewAuthService(config *Config, store UserStore) AuthService

NewAuthService creates a new auth service

type Claims

type Claims struct {
	UserID   string   `json:"user_id"`
	Username string   `json:"username"`
	Roles    []string `json:"roles"`
	jwt.RegisteredClaims
}

Claims represents JWT claims

type Config

type Config struct {
	// JWT settings
	JWTSecret              string
	JWTExpiration          time.Duration
	RefreshTokenEnabled    bool
	RefreshTokenExpiration time.Duration

	// Password policy
	PasswordMinLength     int
	PasswordRequireStrong bool // uppercase, lowercase, number, special char

	// Account locking
	MaxFailedAttempts int
	LockoutDuration   time.Duration

	// Session management
	SessionTimeout time.Duration
	CookieSecure   bool
	CookieHTTPOnly bool
	CookieSameSite string

	// Roles
	DefaultRole    string
	AvailableRoles []string

	// Audit logging
	AuditEnabled       bool
	AuditRetentionDays int
}

Config represents authentication service configuration

func DefaultConfig

func DefaultConfig() *Config

DefaultConfig returns default configuration

type CouchDBUserStore

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

CouchDBUserStore implements UserStore for CouchDB with JSON-LD support

func (*CouchDBUserStore) CreateUser

func (s *CouchDBUserStore) CreateUser(user *User) error

CreateUser creates a new user in CouchDB

func (*CouchDBUserStore) DeleteExpiredRefreshTokens

func (s *CouchDBUserStore) DeleteExpiredRefreshTokens() error

DeleteExpiredRefreshTokens deletes all expired refresh tokens

func (*CouchDBUserStore) DeleteUser

func (s *CouchDBUserStore) DeleteUser(id string) error

DeleteUser deletes a user from CouchDB

func (*CouchDBUserStore) GetAuditLogs

func (s *CouchDBUserStore) GetAuditLogs(criteria AuditSearchCriteria) ([]*AuditLog, error)

GetAuditLogs retrieves audit logs based on search criteria using semantic queries

func (*CouchDBUserStore) GetRefreshToken

func (s *CouchDBUserStore) GetRefreshToken(id string) (*RefreshToken, error)

GetRefreshToken retrieves a refresh token by ID

func (*CouchDBUserStore) GetRefreshTokensByUserID

func (s *CouchDBUserStore) GetRefreshTokensByUserID(userID string) ([]*RefreshToken, error)

GetRefreshTokensByUserID retrieves all refresh tokens for a user using semantic query

func (*CouchDBUserStore) GetUser

func (s *CouchDBUserStore) GetUser(id string) (*User, error)

GetUser retrieves a user by ID

func (*CouchDBUserStore) GetUserByEmail

func (s *CouchDBUserStore) GetUserByEmail(email string) (*User, error)

GetUserByEmail retrieves a user by email using semantic query

func (*CouchDBUserStore) GetUserByUsername

func (s *CouchDBUserStore) GetUserByUsername(username string) (*User, error)

GetUserByUsername retrieves a user by username using semantic query

func (*CouchDBUserStore) ListUsers

func (s *CouchDBUserStore) ListUsers() ([]*User, error)

ListUsers retrieves all users using semantic query

func (*CouchDBUserStore) RecordLoginAttempt

func (s *CouchDBUserStore) RecordLoginAttempt(username string, success bool) error

RecordLoginAttempt records a login attempt (updates user's failed login count)

func (*CouchDBUserStore) RevokeRefreshToken

func (s *CouchDBUserStore) RevokeRefreshToken(id string) error

RevokeRefreshToken revokes a refresh token

func (*CouchDBUserStore) SaveAuditLog

func (s *CouchDBUserStore) SaveAuditLog(log *AuditLog) error

SaveAuditLog saves an audit log entry to CouchDB

func (*CouchDBUserStore) SaveRefreshToken

func (s *CouchDBUserStore) SaveRefreshToken(token *RefreshToken) error

SaveRefreshToken saves a refresh token to CouchDB

func (*CouchDBUserStore) UpdateUser

func (s *CouchDBUserStore) UpdateUser(user *User) error

UpdateUser updates an existing user in CouchDB

type CreateUserRequest

type CreateUserRequest struct {
	Username           string   `json:"username"`
	Email              string   `json:"email,omitempty"`
	Password           string   `json:"password"`
	Name               string   `json:"name,omitempty"`
	Roles              []string `json:"roles,omitempty"`
	MustChangePassword bool     `json:"must_change_password,omitempty"`
}

CreateUserRequest represents a request to create a new user

type RefreshToken

type RefreshToken struct {
	// JSON-LD semantic fields
	Context string `json:"@context,omitempty"` // JSON-LD context
	Type    string `json:"@type,omitempty"`    // JSON-LD type (RefreshToken)

	// Identity fields
	ID     string `json:"_id,omitempty"`  // UUID (CouchDB _id)
	Rev    string `json:"_rev,omitempty"` // CouchDB revision
	UserID string `json:"user_id"`        // Foreign key to User

	// Token fields
	Token      string     `json:"token"` // Hashed refresh token
	ExpiresAt  time.Time  `json:"expires_at"`
	CreatedAt  time.Time  `json:"created_at"`
	LastUsedAt *time.Time `json:"last_used_at,omitempty"`
	Revoked    bool       `json:"revoked"`
}

RefreshToken represents a refresh token for token rotation Fully semantic with JSON-LD support

func (*RefreshToken) IsValid

func (rt *RefreshToken) IsValid() bool

IsValid checks if the refresh token is still valid (not expired and not revoked)

type TokenPair

type TokenPair struct {
	AccessToken  string    `json:"access_token"`
	RefreshToken string    `json:"refresh_token"`
	ExpiresAt    time.Time `json:"expires_at"`
}

TokenPair represents an access token and refresh token pair

type TokenService

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

TokenService handles JWT token operations

func NewTokenService

func NewTokenService(secret string, expiration, refreshExpiration time.Duration) *TokenService

NewTokenService creates a new token service

func (*TokenService) GenerateToken

func (s *TokenService) GenerateToken(user *User) (string, error)

GenerateToken generates a JWT access token for a user

func (*TokenService) GenerateTokenPair

func (s *TokenService) GenerateTokenPair(user *User) (*TokenPair, error)

GenerateTokenPair generates both access and refresh tokens

func (*TokenService) ValidateToken

func (s *TokenService) ValidateToken(tokenString string) (*Claims, error)

ValidateToken validates a JWT token and returns the claims

type UpdateUserRequest

type UpdateUserRequest struct {
	Email              *string   `json:"email,omitempty"`
	Password           *string   `json:"password,omitempty"`
	Name               *string   `json:"name,omitempty"`
	Roles              *[]string `json:"roles,omitempty"`
	Enabled            *bool     `json:"enabled,omitempty"`
	Locked             *bool     `json:"locked,omitempty"`
	MustChangePassword *bool     `json:"must_change_password,omitempty"`
	FailedLogins       *int      `json:"failed_logins,omitempty"`
}

UpdateUserRequest represents a request to update an existing user

type User

type User struct {
	// JSON-LD semantic fields
	Context string `json:"@context,omitempty"` // JSON-LD context (https://schema.org)
	Type    string `json:"@type,omitempty"`    // JSON-LD type (Person)

	// Identity fields
	ID       string `json:"_id,omitempty"`   // UUID (CouchDB _id)
	Rev      string `json:"_rev,omitempty"`  // CouchDB revision
	Username string `json:"username"`        // Unique, 3-50 chars
	Email    string `json:"email,omitempty"` // Optional, unique if provided
	Name     string `json:"name,omitempty"`  // Display name

	// Authentication fields
	PasswordHash string   `json:"password_hash,omitempty"` // bcrypt hash (never sent to client)
	Roles        []string `json:"roles"`                   // Array of role names
	APIKeys      []string `json:"api_keys,omitempty"`      // Hashed API keys (optional)

	// Account status
	Enabled            bool `json:"enabled"`              // Account active/inactive
	Locked             bool `json:"locked"`               // Account locked due to failed attempts
	MustChangePassword bool `json:"must_change_password"` // Force password change
	FailedLogins       int  `json:"failed_logins"`        // Failed login counter

	// Timestamps
	CreatedAt   time.Time  `json:"created_at"`
	UpdatedAt   time.Time  `json:"updated_at"`
	LastLoginAt *time.Time `json:"last_login_at,omitempty"`

	// Extensible metadata
	Metadata map[string]interface{} `json:"metadata,omitempty"`
}

User represents a user account in the system Fully semantic with JSON-LD support (@context, @type) CouchDB-compatible with _id and _rev fields

func (*User) CanRead

func (u *User) CanRead() bool

CanRead checks if the user can read (any role except disabled)

func (*User) CanWrite

func (u *User) CanWrite() bool

CanWrite checks if the user can write (admin or user role)

func (*User) HasAnyRole

func (u *User) HasAnyRole(roles ...string) bool

HasAnyRole checks if the user has any of the specified roles

func (*User) HasRole

func (u *User) HasRole(role string) bool

HasRole checks if the user has a specific role

func (*User) IsAdmin

func (u *User) IsAdmin() bool

IsAdmin checks if the user has admin role

func (*User) IsAgent

func (u *User) IsAgent() bool

IsAgent checks if the user has agent role

func (*User) ToResponse

func (u *User) ToResponse() *UserResponse

ToResponse converts User to UserResponse, removing sensitive fields

type UserResponse

type UserResponse struct {
	ID          string                 `json:"id"`
	Username    string                 `json:"username"`
	Email       string                 `json:"email,omitempty"`
	Roles       []string               `json:"roles"`
	Enabled     bool                   `json:"enabled"`
	Locked      bool                   `json:"locked"`
	Name        string                 `json:"name,omitempty"`
	CreatedAt   time.Time              `json:"created_at"`
	UpdatedAt   time.Time              `json:"updated_at"`
	LastLoginAt *time.Time             `json:"last_login_at,omitempty"`
	Context     string                 `json:"@context,omitempty"`
	Type        string                 `json:"@type,omitempty"`
	Metadata    map[string]interface{} `json:"metadata,omitempty"`
}

UserResponse represents a user with sensitive fields removed

type UserStore

type UserStore interface {
	// User CRUD operations
	CreateUser(user *User) error
	GetUser(id string) (*User, error)
	GetUserByUsername(username string) (*User, error)
	GetUserByEmail(email string) (*User, error)
	UpdateUser(user *User) error
	DeleteUser(id string) error
	ListUsers() ([]*User, error)

	// Authentication helpers
	RecordLoginAttempt(username string, success bool) error

	// Refresh token operations
	SaveRefreshToken(token *RefreshToken) error
	GetRefreshToken(id string) (*RefreshToken, error)
	GetRefreshTokensByUserID(userID string) ([]*RefreshToken, error)
	RevokeRefreshToken(id string) error
	DeleteExpiredRefreshTokens() error

	// Audit logging
	SaveAuditLog(log *AuditLog) error
	GetAuditLogs(criteria AuditSearchCriteria) ([]*AuditLog, error)
}

UserStore defines the interface for user persistence

func NewCouchDBUserStore

func NewCouchDBUserStore(service *db.CouchDBService) UserStore

NewCouchDBUserStore creates a new CouchDB-backed user store

Jump to

Keyboard shortcuts

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