Documentation
¶
Index ¶
- Variables
- func GenerateJWT(secret []byte, userID string, ttl int) (string, error)
- func UIModules() []any
- func ValidateJWT(secret []byte, token string) (string, error)
- type AuthMode
- type Config
- type Executor
- type GoogleProvider
- type Identity
- type LANIP
- type LoginData
- type MicrosoftProvider
- func (p *MicrosoftProvider) AuthCodeURL(state string) string
- func (p *MicrosoftProvider) ExchangeCode(ctx context.Context, code string) (*oauth2.Token, error)
- func (p *MicrosoftProvider) GetUserInfo(ctx context.Context, token *oauth2.Token) (OAuthUserInfo, error)
- func (p *MicrosoftProvider) Name() string
- type Module
- func (m *Module) AccessCheck(resource string, action byte, data ...any) bool
- func (m *Module) Add() []any
- func (m *Module) AssignLANIP(userID, ip, label string) error
- func (m *Module) AssignPermission(roleID, permissionID string) error
- func (m *Module) AssignRole(userID, roleID string) error
- func (m *Module) BeginOAuth(providerName string) (string, error)
- func (m *Module) CanExecute(ctx context.Context, resource string, action byte) bool
- func (m *Module) CompleteOAuth(providerName string, r *http.Request, ip, ua string) (User, bool, error)
- func (m *Module) CreatePermission(id, name, resource string, action string) error
- func (m *Module) CreateRole(id string, code string, name, description string) error
- func (m *Module) CreateSession(userID, ip, userAgent string) (Session, error)
- func (m *Module) DeletePermission(id string) error
- func (m *Module) DeleteRole(id string) error
- func (m *Module) DeleteSession(id string) error
- func (m *Module) FromContext(ctx context.Context) (*User, bool)
- func (m *Module) GenerateAPIToken(userID string, ttl int) (string, error)
- func (m *Module) GetLANIPs(userID string) ([]LANIP, error)
- func (m *Module) GetPermission(id string) (*Permission, error)
- func (m *Module) GetRole(id string) (*Role, error)
- func (m *Module) GetRoleByCode(code string) (*Role, error)
- func (m *Module) GetSession(id string) (Session, error)
- func (m *Module) GetUser(id string) (User, error)
- func (m *Module) GetUserIdentities(userID string) ([]Identity, error)
- func (m *Module) GetUserRoles(userID string) ([]Role, error)
- func (m *Module) HasPermission(userID, resource string, action byte) (bool, error)
- func (m *Module) InjectIdentity(ctx context.Context, r *http.Request) context.Context
- func (m *Module) Login(email, password string) (User, error)
- func (m *Module) LoginLAN(rut string, r *http.Request) (User, error)
- func (m *Module) Middleware(next http.Handler) http.Handler
- func (m *Module) PurgeExpiredOAuthStates() error
- func (m *Module) PurgeExpiredSessions() error
- func (m *Module) PurgeSessionsByUser(userID string) error
- func (m *Module) ReactivateUser(id string) error
- func (m *Module) Register(handlers ...RBACObject) error
- func (m *Module) RegisterLAN(userID, rut string) error
- func (m *Module) RegisterMCP(next http.Handler) http.Handler
- func (m *Module) RevokeLANIP(userID, ip string) error
- func (m *Module) RevokeRole(userID, roleID string) error
- func (m *Module) RotateSession(oldID, ip, userAgent string) (Session, error)
- func (m *Module) SetLog(fn func(...any))
- func (m *Module) SetPassword(userID, password string) error
- func (m *Module) SuspendUser(id string) error
- func (m *Module) UIModules() []any
- func (m *Module) UnlinkIdentity(userID, provider string) error
- func (m *Module) UnregisterLAN(userID string) error
- func (m *Module) VerifyPassword(userID, password string) error
- type OAuthProvider
- type OAuthState
- type OAuthUserInfo
- type PasswordData
- type Permission
- type ProfileData
- type RBACObject
- type RegisterData
- type Role
- type RolePermission
- type Rows
- type Scanner
- type SecurityEvent
- type SecurityEventType
- type Session
- type User
- type UserRole
Constants ¶
This section is empty.
Variables ¶
var ( ErrInvalidCredentials = fmt.Err("access", "denied") // EN: Access Denied / ES: Acceso Denegado ErrSuspended = fmt.Err("user", "suspended") // EN: User Suspended / ES: Usuario Suspendido ErrEmailTaken = fmt.Err("email", "registered") // EN: Email Registered / ES: Correo electrónico Registrado ErrWeakPassword = fmt.Err("password", "weak") // EN: Password Weak / ES: Contraseña Débil ErrSessionExpired = fmt.Err("token", "expired") // EN: Token Expired / ES: Token Expirado ErrNotFound = fmt.Err("user", "not", "found") // EN: User Not Found / ES: Usuario No Encontrado ErrProviderNotFound = fmt.Err("provider", "not", "found") // EN: Provider Not Found / ES: Proveedor No Encontrado ErrInvalidOAuthState = fmt.Err("state", "invalid") // EN: State Invalid / ES: Estado Inválido ErrCannotUnlink = fmt.Err("identity", "cannot", "unlink") // EN: Identity Cannot Unlink / ES: Identidad No puede Desvincular ErrInvalidRUT = fmt.Err("rut", "invalid") // EN: Rut Invalid / ES: Rut Inválido ErrRUTTaken = fmt.Err("rut", "registered") // EN: Rut Registered / ES: Rut Registrado ErrIPTaken = fmt.Err("ip", "registered") // EN: Ip Registered / ES: Ip Registrado )
var ErrInvalidToken = fmt.Err("token", "invalid")
var Identity_ = struct { TableName string ID string UserID string Provider string ProviderID string Email string CreatedAt string }{ TableName: "user_identities", ID: "id", UserID: "user_id", Provider: "provider", ProviderID: "provider_id", Email: "email", CreatedAt: "created_at", }
var LANIP_ = struct { TableName string ID string UserID string IP string Label string CreatedAt string }{ TableName: "user_lan_ips", ID: "id", UserID: "user_id", IP: "ip", Label: "label", CreatedAt: "created_at", }
var OAuthState_ = struct { TableName string State string Provider string ExpiresAt string CreatedAt string }{ TableName: "user_oauth_states", State: "state", Provider: "provider", ExpiresAt: "expires_at", CreatedAt: "created_at", }
var PasswordHashCost = bcrypt.DefaultCost
var Permission_ = struct { TableName string ID string Name string Resource string Action string }{ TableName: "rbac_permissions", ID: "id", Name: "name", Resource: "resource", Action: "action", }
var RolePermission_ = struct { TableName string RoleID string PermissionID string }{ TableName: "rbac_role_permissions", RoleID: "role_id", PermissionID: "permission_id", }
var Role_ = struct { TableName string ID string Code string Name string Description string }{ TableName: "rbac_roles", ID: "id", Code: "code", Name: "name", Description: "description", }
var Session_ = struct { TableName string ID string UserID string ExpiresAt string IP string UserAgent string CreatedAt string }{ TableName: "user_sessions", ID: "id", UserID: "user_id", ExpiresAt: "expires_at", IP: "ip", UserAgent: "user_agent", CreatedAt: "created_at", }
var UserRole_ = struct { TableName string UserID string RoleID string }{ TableName: "rbac_user_roles", UserID: "user_id", RoleID: "role_id", }
Functions ¶
func GenerateJWT ¶ added in v0.0.17
Types ¶
type AuthMode ¶ added in v0.0.17
type AuthMode uint8
AuthMode selects the session strategy.
const ( // AuthModeCookie stores a session ID in an HttpOnly cookie. // Stateful: requires user_sessions table. Supports immediate revocation. AuthModeCookie AuthMode = iota // default // AuthModeJWT stores a signed JWT in an HttpOnly cookie. // Stateless: no DB lookup per request. No immediate revocation. // Ideal for SPA/PWA and multi-server deployments. AuthModeJWT // AuthModeBearer reads a signed JWT from the "Authorization: Bearer <token>" header. // Stateless: for API clients (MCP servers, IDEs, LLMs) that cannot use cookies. // Structurally implements mcp.Authorizer via InjectIdentity + CanExecute methods. // Requires JWTSecret. AuthModeBearer )
type Config ¶ added in v0.0.2
type Config struct {
AuthMode AuthMode // default: AuthModeCookie
// Shared by all modes
CookieName string // default: "session"
TokenTTL int // default: 86400 (seconds). Session TTL in cookie mode, JWT expiry in JWT mode.
// Required when AuthMode == AuthModeJWT or AuthMode == AuthModeBearer.
// Also required to call GenerateAPIToken regardless of AuthMode.
JWTSecret []byte
TrustProxy bool
OAuthProviders []OAuthProvider
// Optional hook for receiving security events (e.g. tampering, brute force)
OnSecurityEvent func(SecurityEvent)
// OnPasswordValidate is called by SetPassword before hashing.
// Return a non-nil error to reject the password.
// If nil, only the built-in len >= 8 check applies.
OnPasswordValidate func(password string) error
}
type Executor ¶ added in v0.0.2
type Executor interface {
Exec(query string, args ...any) error
Query(query string, args ...any) (Rows, error)
QueryRow(query string, args ...any) Scanner
Prepare(query string) (*sql.Stmt, error)
Begin() (*sql.Tx, error)
}
Executor interface abstracts database operations.
type GoogleProvider ¶ added in v0.0.2
type GoogleProvider struct {
ClientID string
ClientSecret string
RedirectURL string
// contains filtered or unexported fields
}
func (*GoogleProvider) AuthCodeURL ¶ added in v0.0.2
func (p *GoogleProvider) AuthCodeURL(state string) string
func (*GoogleProvider) ExchangeCode ¶ added in v0.0.2
func (*GoogleProvider) GetUserInfo ¶ added in v0.0.2
func (p *GoogleProvider) GetUserInfo(ctx context.Context, token *oauth2.Token) (OAuthUserInfo, error)
func (*GoogleProvider) Name ¶ added in v0.0.2
func (p *GoogleProvider) Name() string
type Identity ¶ added in v0.0.2
type Identity struct {
ID string `json:"id" db:"pk"`
UserID string `json:"user_id" db:"ref=users"`
Provider string `json:"provider"`
ProviderID string `json:"provider_id"`
Email string `json:"email,omitempty"`
CreatedAt int64 `json:"created_at"`
}
Identity
func ReadOneIdentity ¶ added in v0.0.6
type LANIP ¶ added in v0.0.2
type LANIP struct {
ID string `json:"id" db:"pk"`
UserID string `json:"user_id" db:"ref=users"`
IP string `json:"ip"`
Label string `json:"label"`
CreatedAt int64 `json:"created_at"`
}
LANIP
type LoginData ¶ added in v0.0.2
LoginData is validated by LoginModule on both frontend and backend.
type MicrosoftProvider ¶ added in v0.0.2
type MicrosoftProvider struct {
ClientID string
ClientSecret string
RedirectURL string
// contains filtered or unexported fields
}
func (*MicrosoftProvider) AuthCodeURL ¶ added in v0.0.2
func (p *MicrosoftProvider) AuthCodeURL(state string) string
func (*MicrosoftProvider) ExchangeCode ¶ added in v0.0.2
func (*MicrosoftProvider) GetUserInfo ¶ added in v0.0.2
func (p *MicrosoftProvider) GetUserInfo(ctx context.Context, token *oauth2.Token) (OAuthUserInfo, error)
func (*MicrosoftProvider) Name ¶ added in v0.0.2
func (p *MicrosoftProvider) Name() string
type Module ¶ added in v0.0.15
type Module struct {
// contains filtered or unexported fields
}
Module is the user/auth/rbac handle. All backend operations are methods on this type. Created exclusively via New().
func New ¶
New initializes the user/rbac schema, warms the cache, and returns a Module handle. This is the ONLY entry point for this package on the backend.
func (*Module) AccessCheck ¶ added in v0.0.15
AccessCheck is the bridge function for tinywasm/crudp and tinywasm/site. Reads the *http.Request from data, validates the session, and checks RBAC permissions. Satisfies the site.SetAccessCheck(fn) signature directly.
Usage: site.SetAccessCheck(m.AccessCheck)
func (*Module) Add ¶ added in v0.0.15
Add returns all admin-managed CRUDP handlers for registration. The concrete types are private — pass directly to crudp.RegisterHandlers.
Usage: cp.RegisterHandlers(m.Add()...)
func (*Module) AssignLANIP ¶ added in v0.0.15
func (*Module) AssignPermission ¶ added in v0.0.15
func (*Module) AssignRole ¶ added in v0.0.15
func (*Module) BeginOAuth ¶ added in v0.0.15
func (*Module) CanExecute ¶ added in v0.0.24
CanExecute implements mcp.Authorizer. Reads identity injected by InjectIdentity and checks RBAC.
func (*Module) CompleteOAuth ¶ added in v0.0.15
func (*Module) CreatePermission ¶ added in v0.0.15
func (*Module) CreateRole ¶ added in v0.0.15
func (*Module) CreateSession ¶ added in v0.0.15
func (*Module) DeletePermission ¶ added in v0.0.15
func (*Module) DeleteRole ¶ added in v0.0.15
func (*Module) DeleteSession ¶ added in v0.0.15
func (*Module) FromContext ¶ added in v0.0.15
FromContext extracts the authenticated *User injected by Middleware or RegisterMCP. Returns (nil, false) if the context carries no authenticated user.
func (*Module) GenerateAPIToken ¶ added in v0.0.24
GenerateAPIToken creates a signed JWT for API access (MCP clients, IDEs, LLMs). Requires Config.JWTSecret — independent of the configured AuthMode. ttl=0 → 100 years (effectively no expiry). The returned token is used as a Bearer token in Authorization headers.
func (*Module) GetPermission ¶ added in v0.0.15
func (m *Module) GetPermission(id string) (*Permission, error)
func (*Module) GetRoleByCode ¶ added in v0.0.15
func (*Module) GetSession ¶ added in v0.0.15
func (*Module) GetUserIdentities ¶ added in v0.0.15
func (*Module) GetUserRoles ¶ added in v0.0.15
func (*Module) HasPermission ¶ added in v0.0.15
func (*Module) InjectIdentity ¶ added in v0.0.24
InjectIdentity implements mcp.Authorizer. Delegates to validateSession (respects configured AuthMode). On failure: returns ctx unchanged — CanExecute will deny.
func (*Module) Middleware ¶ added in v0.0.15
Middleware protects HTTP routes. Validates the session cookie and injects the authenticated *User into the request context. Returns HTTP 401 if the session is missing or expired.
Example:
mux.Handle("/admin", m.Middleware(adminHandler))
func (*Module) PurgeExpiredOAuthStates ¶ added in v0.0.15
func (*Module) PurgeExpiredSessions ¶ added in v0.0.15
func (*Module) PurgeSessionsByUser ¶ added in v0.0.22
PurgeSessionsByUser deletes all sessions belonging to userID from cache and DB.
func (*Module) ReactivateUser ¶ added in v0.0.22
ReactivateUser sets Status = "active". Evicts user from cache.
func (*Module) Register ¶ added in v0.0.15
func (m *Module) Register(handlers ...RBACObject) error
func (*Module) RegisterLAN ¶ added in v0.0.15
func (*Module) RegisterMCP ¶ added in v0.0.15
RegisterMCP envuelve el handler MCP con middleware de sesión. Alternativa limpia a registrar hooks en el MCPServer (que no existe en tinywasm/mcp).
Ejemplo:
mcpHandler := mcp.NewStreamableHTTPServer(srv)
mux.Handle("/mcp", m.RegisterMCP(mcpHandler))
func (*Module) RevokeLANIP ¶ added in v0.0.15
func (*Module) RevokeRole ¶ added in v0.0.15
func (*Module) RotateSession ¶ added in v0.0.22
RotateSession atomically deletes the old session and creates a new one with the same userID, updated IP/UserAgent, and a fresh TTL. Prevents session fixation attacks when called post-login.
func (*Module) SetLog ¶ added in v0.0.15
SetLog configures optional logging. Call immediately after New(). Default: no-op. Follows the tinywasm ecosystem SetLog convention (same as rbac).
Example:
m.SetLog(func(msg ...any) { log.Println(msg...) })
func (*Module) SetPassword ¶ added in v0.0.15
func (*Module) SuspendUser ¶ added in v0.0.22
SuspendUser sets Status = "suspended". Evicts user from cache.
func (*Module) UIModules ¶ added in v0.0.15
UIModules returns all standard authentication UI flow handlers bound to this module. Isomorphic: The signature exists in both WASM and backend. On the backend, it links to the DB.
func (*Module) UnlinkIdentity ¶ added in v0.0.15
func (*Module) UnregisterLAN ¶ added in v0.0.15
func (*Module) VerifyPassword ¶ added in v0.0.15
type OAuthProvider ¶ added in v0.0.2
type OAuthState ¶ added in v0.0.6
type OAuthState struct {
State string `json:"state" db:"pk"`
Provider string `json:"provider"`
ExpiresAt int64 `json:"expires_at"`
CreatedAt int64 `json:"created_at"`
}
OAuthState
func ReadAllOAuthState ¶ added in v0.0.6
func ReadAllOAuthState(qb *orm.QB) ([]*OAuthState, error)
func ReadOneOAuthState ¶ added in v0.0.6
func ReadOneOAuthState(qb *orm.QB, model *OAuthState) (*OAuthState, error)
func (*OAuthState) Pointers ¶ added in v0.0.6
func (m *OAuthState) Pointers() []any
func (*OAuthState) Schema ¶ added in v0.0.6
func (m *OAuthState) Schema() []orm.Field
func (OAuthState) TableName ¶ added in v0.0.6
func (OAuthState) TableName() string
func (*OAuthState) Values ¶ added in v0.0.6
func (m *OAuthState) Values() []any
type OAuthUserInfo ¶ added in v0.0.2
type PasswordData ¶ added in v0.0.2
PasswordData is validated by ProfileModule (password change sub-form).
type Permission ¶ added in v0.0.6
type Permission struct {
ID string `json:"id" db:"pk"`
Name string `json:"name"`
Resource string `json:"resource"`
Action string `json:"action"`
}
Permission
func ReadAllPermission ¶ added in v0.0.6
func ReadAllPermission(qb *orm.QB) ([]*Permission, error)
func ReadOnePermission ¶ added in v0.0.6
func ReadOnePermission(qb *orm.QB, model *Permission) (*Permission, error)
func (*Permission) Pointers ¶ added in v0.0.6
func (m *Permission) Pointers() []any
func (*Permission) Schema ¶ added in v0.0.6
func (m *Permission) Schema() []orm.Field
func (Permission) TableName ¶ added in v0.0.6
func (Permission) TableName() string
func (*Permission) Values ¶ added in v0.0.6
func (m *Permission) Values() []any
type ProfileData ¶ added in v0.0.2
ProfileData is validated by ProfileModule (name/phone update).
type RBACObject ¶ added in v0.0.6
type RegisterData ¶ added in v0.0.2
RegisterData is validated by RegisterModule.
type Role ¶ added in v0.0.6
type Role struct {
ID string `json:"id" db:"pk"`
Code string `json:"code"`
Name string `json:"name"`
Description string `json:"description"`
}
Role
type RolePermission ¶ added in v0.0.6
type RolePermission struct {
RoleID string `json:"role_id"`
PermissionID string `json:"permission_id"`
}
RolePermission
func ReadAllRolePermission ¶ added in v0.0.6
func ReadAllRolePermission(qb *orm.QB) ([]*RolePermission, error)
func ReadOneRolePermission ¶ added in v0.0.6
func ReadOneRolePermission(qb *orm.QB, model *RolePermission) (*RolePermission, error)
func (*RolePermission) Pointers ¶ added in v0.0.6
func (m *RolePermission) Pointers() []any
func (*RolePermission) Schema ¶ added in v0.0.6
func (m *RolePermission) Schema() []orm.Field
func (RolePermission) TableName ¶ added in v0.0.6
func (RolePermission) TableName() string
func (*RolePermission) Values ¶ added in v0.0.6
func (m *RolePermission) Values() []any
type SecurityEvent ¶ added in v0.0.22
type SecurityEventType ¶ added in v0.0.22
type SecurityEventType uint8
const ( EventJWTTampered SecurityEventType = iota // ValidateJWT: HMAC mismatch EventOAuthReplay // consumeState: state already consumed (2nd use) EventOAuthExpiredState // consumeState: state found but past ExpiresAt EventOAuthCrossProvider // consumeState: provider mismatch (state preserved) EventIPMismatch // LoginLAN: IP not registered EventNonActiveAccess // Login/LoginLAN: status != "active" EventAccessDenied // AccessCheck: RBAC denied with valid session )
type Session ¶ added in v0.0.2
type Session struct {
ID string `json:"id" db:"pk"`
UserID string `json:"user_id" db:"ref=users"`
ExpiresAt int64 `json:"expires_at"`
IP string `json:"ip,omitempty"`
UserAgent string `json:"user_agent,omitempty"`
CreatedAt int64 `json:"created_at"`
}
Session
func ReadOneSession ¶ added in v0.0.6
type User ¶
type User struct {
ID string `json:"id" db:"pk"`
Email string `json:"email,omitempty" db:"unique"`
Name string `json:"name"`
Phone string `json:"phone,omitempty"`
Status string `json:"status"` // "active", "suspended"
CreatedAt int64 `json:"created_at"`
Roles []Role `json:"roles,omitempty" db:"-"`
Permissions []Permission `json:"permissions,omitempty" db:"-"`
}
User
Source Files
¶
- api_token_back.go
- auth.go
- cache.go
- cache_users.go
- crud.go
- forms.go
- generate.go
- google.go
- identities.go
- jwt_back.go
- lan.go
- lan_ips.go
- microsoft.go
- middleware_back.go
- migrate.go
- models.go
- models_crud_back.go
- models_orm.go
- module_lan.go
- module_lan_back.go
- module_login.go
- module_login_back.go
- module_oauth.go
- module_oauth_back.go
- module_profile.go
- module_profile_back.go
- module_register.go
- module_register_back.go
- modules.go
- oauth.go
- sessions.go
- sql.go
- user.go
- user_back.go
- user_rbac_mutations.go