auth

package module
v0.0.14 Latest Latest
Warning

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

Go to latest
Published: Aug 27, 2026 License: MIT Imports: 8 Imported by: 0

README

tinywasm/auth

Authentication mechanisms, sessions, identities, and OAuth providers for the TinyWasm ecosystem. Authorization belongs to tinywasm/rbac. Both are siblings that depend only on tinywasm/user and never on each other.

flowchart TD
    U[user] --> A[auth]
    U --> R[rbac]
    A --> C[app]
    R --> C

Documentation

  • Architecture — Dependency rules, packages, local simulator

Packages

  • auth — Core ports: SubjectStore, SessionIssuer, IdentityStore, StateStore, SecurityNotifier, SessionRepo, Config, ProfileDTO, ShellProfile, OAuth types.
  • authority — Concrete module (Module) implementing the ports, caches, migrations, and middleware.
  • oauth2 + oauth2/provider/google, oauth2/provider/microsoft — OAuth flow and providers.
  • session/cookie, session/jwt — Session transports.
  • email_password, trusted_ip — Credential authenticators.
  • local — Development selector authenticator; no network, no env vars.

Local Development

scenarios := []local.Scenario{
    {ID: "user_admin", Name: "Alice", Email: "alice@example.com", Avatar: "", Roles: []string{"Administrator"}},
    {ID: "user_viewer", Name: "Bob", Email: "bob@example.com", Avatar: "", Roles: []string{"Viewer"}},
}
_ = authority.Migrate(db.RawConn(), db.RawConn().(ddl.Compiler))
authMod, _ := authority.New(db, auth.Config{IDs: ids})
rbacSvc, _ := rbac.New(db)
// seed subjects and assignments via rbac before mounting
for _, s := range scenarios { /* ensure user and AssignRole via rbacSvc */ }
localAuth := local.New(scenarios, authMod, authMod, local.WithAfterLogin("/"))
authMod.Enable(localAuth)

Production builds use oauth2.New with a real google.GoogleProvider and never register local.

Documentation

Index

Constants

View Source
const (
	PathLogin      = "/login"
	PathLogout     = "/logout"
	PathAfterLogin = "/"

	// PathOAuthPrefix es la raiz bajo la que oauth2.Authenticator monta sus
	// rutas. Es la unica definicion de esa cadena en el repositorio.
	PathOAuthPrefix = "/oauth/"
)
View Source
const (
	OpMe         = "me"          // authenticated caller's profile
	OpListUsers  = "list_users"  // admin: list users
	OpUpsertUser = "upsert_user" // admin: create (Id=="") or update
	OpDeleteUser = "delete_user" // admin: delete by record
)

Op names — shared vocabulary between the wasm view and the server module.

View Source
const TopicSecurity = "auth.security"

TopicSecurity is the events topic every SecurityEvent is published on.

Variables

View Source
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
)
View Source
var IdentityModel = model.Definition{
	Name: "identity",
	Fields: model.Fields{
		{Name: "id", Type: model.Text(), DB: &model.FieldDB{PK: true}},
		{Name: "user_id", Type: model.Text(), DB: &model.FieldDB{RefColumn: "id"}, Ref: &UserModel},
		{Name: "provider", Type: model.Text()},
		{Name: "provider_id", Type: model.Text()},
		{Name: "email", Type: model.Text()},
		{Name: "created_at", Type: model.Int()},
	},
}
View Source
var Identity_ = struct {
	Id         string
	UserId     string
	Provider   string
	ProviderId string
	Email      string
	CreatedAt  string
}{
	Id:         "id",
	UserId:     "user_id",
	Provider:   "provider",
	ProviderId: "provider_id",
	Email:      "email",
	CreatedAt:  "created_at",
}
View Source
var LANIPModel = model.Definition{
	Name: "lanip",
	Fields: model.Fields{
		{Name: "id", Type: model.Text(), DB: &model.FieldDB{PK: true}},
		{Name: "user_id", Type: model.Text(), DB: &model.FieldDB{RefColumn: "id"}, Ref: &UserModel},
		{Name: "ip", Type: model.Text()},
		{Name: "label", Type: model.Text()},
		{Name: "created_at", Type: model.Int()},
	},
}
View Source
var LANIP_ = struct {
	Id        string
	UserId    string
	Ip        string
	Label     string
	CreatedAt string
}{
	Id:        "id",
	UserId:    "user_id",
	Ip:        "ip",
	Label:     "label",
	CreatedAt: "created_at",
}
View Source
var LoginDataModel = model.Definition{
	Name: "login_data",
	Fields: model.Fields{
		{Name: "email", Type: input.Email(), NotNull: true},
		{Name: "password", Type: input.Password(), NotNull: true},
	},
}
View Source
var OAuthStateModel = model.Definition{
	Name: "oauth_state",
	Fields: model.Fields{
		{Name: "state", Type: model.Text(), DB: &model.FieldDB{PK: true}},
		{Name: "provider", Type: model.Text()},
		{Name: "expires_at", Type: model.Int()},
		{Name: "created_at", Type: model.Int()},
	},
}
View Source
var OAuthState_ = struct {
	State     string
	Provider  string
	ExpiresAt string
	CreatedAt string
}{
	State:     "state",
	Provider:  "provider",
	ExpiresAt: "expires_at",
	CreatedAt: "created_at",
}
View Source
var PasswordDataModel = model.Definition{
	Name: "password_data",
	Fields: model.Fields{
		{Name: "current", Type: input.Password(), NotNull: true},
		{Name: "new", Type: input.Password(), NotNull: true},
		{Name: "confirm", Type: input.Password(), NotNull: true},
	},
}
View Source
var ProfileDataModel = model.Definition{
	Name: "profile_data",
	Fields: model.Fields{
		{Name: "name", Type: input.Text(), NotNull: true},
		{Name: "phone", Type: input.Phone()},
	},
}
View Source
var RegisterDataModel = model.Definition{
	Name: "register_data",
	Fields: model.Fields{
		{Name: "name", Type: input.Text(), NotNull: true},
		{Name: "email", Type: input.Email(), NotNull: true},
		{Name: "password", Type: input.Password(), NotNull: true},
		{Name: "phone", Type: input.Phone()},
	},
}
View Source
var SessionModel = model.Definition{
	Name: "session",
	Fields: model.Fields{
		{Name: "id", Type: model.Text(), DB: &model.FieldDB{PK: true}},
		{Name: "user_id", Type: model.Text(), DB: &model.FieldDB{RefColumn: "id"}, Ref: &UserModel},
		{Name: "expires_at", Type: model.Int()},
		{Name: "ip", Type: model.Text()},
		{Name: "user_agent", Type: model.Text()},
		{Name: "created_at", Type: model.Int()},
	},
}
View Source
var Session_ = struct {
	Id        string
	UserId    string
	ExpiresAt string
	Ip        string
	UserAgent string
	CreatedAt string
}{
	Id:        "id",
	UserId:    "user_id",
	ExpiresAt: "expires_at",
	Ip:        "ip",
	UserAgent: "user_agent",
	CreatedAt: "created_at",
}
View Source
var UserModel = model.Definition{
	Name: "user",
	Fields: model.Fields{
		{Name: "id", Type: model.Text(), DB: &model.FieldDB{PK: true}},
		{Name: "email", Type: input.Email(), DB: &model.FieldDB{Unique: true}},
		{Name: "name", Type: input.Text()},
		{Name: "phone", Type: input.Phone()},
		{Name: "status", Type: model.Text()},
		{Name: "avatar", Type: model.Text()},
		{Name: "created_at", Type: model.Int()},
	},
}
View Source
var User_ = struct {
	Id        string
	Email     string
	Name      string
	Phone     string
	Status    string
	Avatar    string
	CreatedAt string
}{
	Id:        "id",
	Email:     "email",
	Name:      "name",
	Phone:     "phone",
	Status:    "status",
	Avatar:    "avatar",
	CreatedAt: "created_at",
}

Functions

func ClientIP added in v0.0.2

func ClientIP(ctx router.Context, trustProxy bool) string

ClientIP extracts the caller's IP from ctx. When trustProxy is true it reads X-Forwarded-For / X-Real-IP first (only safe behind a reverse proxy you control — otherwise a client can spoof its own IP). Shared by every mode/strategy that needs an IP for a SecurityEvent or an audit column: it is mechanism-agnostic, so it lives at the root, not inside any one mode.

func NewView added in v0.0.2

func NewView(caller router.Caller) view.Presenter

NewView builds the user-administration Presenter — the tech-agnostic engine a renderer (crudview, or any other) wraps. The app decides which renderer draws it.

func PathOAuthCallback added in v0.0.2

func PathOAuthCallback(provider string) string

PathOAuthCallback devuelve la ruta a la que el proveedor redirige de vuelta. Es el valor que se registra como URI de redireccion en la consola del proveedor, precedido del dominio publico de la aplicacion.

func PathOAuthStart added in v0.0.2

func PathOAuthStart(provider string) string

PathOAuthStart devuelve la ruta que inicia el intercambio OAuth2 con el proveedor indicado. Un consumidor enlaza aqui su boton de "iniciar sesion".

Types

type Authenticator added in v0.0.2

type Authenticator interface {
	Name() string
	Mount(r router.Router)
}

Authenticator is one login mode. It owns its HTTP routes completely — authority never inspects, duplicates, or knows the shape of what it mounts.

type Config added in v0.0.2

type Config struct {
	// CookieName/TokenTTL configure authority's OWN default session strategy
	// (session/cookie) and the lifetime of every session row it creates,
	// regardless of which strategy ends up carrying the credential.
	CookieName string // default: "session"
	TokenTTL   int    // default: 86400 (seconds)

	// TrustProxy tells every IP-extracting collaborator (the default cookie
	// strategy, Module.LoginLAN) whether to trust X-Forwarded-For/X-Real-IP.
	// The composition root passes this SAME value to any mode it constructs
	// that also needs it (trusted_ip.New's trustProxy param, WithTrustProxy on
	// the others) — one environmental fact, told explicitly to every consumer,
	// same idiom as IDs/Events.
	TrustProxy bool

	// IDs mints primary keys for every record this module creates. REQUIRED:
	// New fails if nil — an auth module must never silently pick its own
	// generator.
	IDs model.IDGenerator

	// Events receives security events (TopicSecurity). Optional: nil = events
	// are dropped (fire-and-forget contract), never an error.
	Events events.Publisher

	// OnPasswordValidate is consulted by Module.SetPassword before hashing.
	// Return a non-nil error to reject the password. nil = only the built-in
	// len>=8 check applies.
	OnPasswordValidate func(password string) error
}

type Identity added in v0.0.2

type Identity struct {
	Id         string
	UserId     string
	Provider   string
	ProviderId string
	Email      string
	CreatedAt  int64
}

func ReadOneIdentity added in v0.0.2

func ReadOneIdentity(qb *orm.QB, model *Identity) (*Identity, error)

func (*Identity) DecodeFields added in v0.0.2

func (m *Identity) DecodeFields(r model.FieldReader)

func (*Identity) EncodeFields added in v0.0.2

func (m *Identity) EncodeFields(w model.FieldWriter)

func (*Identity) IsNil added in v0.0.2

func (m *Identity) IsNil() bool

func (*Identity) ModelName added in v0.0.2

func (m *Identity) ModelName() string

func (*Identity) Pointers added in v0.0.2

func (m *Identity) Pointers() []any

func (*Identity) Schema added in v0.0.2

func (m *Identity) Schema() []model.Field

func (*Identity) SchemaExt added in v0.0.2

func (m *Identity) SchemaExt() []model.FieldExt

func (*Identity) Validate added in v0.0.2

func (m *Identity) Validate(action byte) error

type IdentityList added in v0.0.2

type IdentityList []*Identity

func ReadAllIdentity added in v0.0.2

func ReadAllIdentity(qb *orm.QB) (IdentityList, error)

func (*IdentityList) Append added in v0.0.2

func (s *IdentityList) Append() model.Fielder

func (*IdentityList) At added in v0.0.2

func (s *IdentityList) At(i int) model.Fielder

func (*IdentityList) DecodeFields added in v0.0.2

func (s *IdentityList) DecodeFields(_ model.FieldReader)

func (*IdentityList) EncodeFields added in v0.0.2

func (s *IdentityList) EncodeFields(_ model.FieldWriter)

func (*IdentityList) IsNil added in v0.0.2

func (s *IdentityList) IsNil() bool

func (*IdentityList) Len added in v0.0.2

func (s *IdentityList) Len() int

func (*IdentityList) Pointers added in v0.0.2

func (s *IdentityList) Pointers() []any

func (*IdentityList) Schema added in v0.0.2

func (s *IdentityList) Schema() []model.Field

type IdentityStore added in v0.0.2

type IdentityStore interface {
	UserByID(id string) (User, error)
	UserByEmail(email string) (User, error)
	CreateUser(email, name, phone string) (User, error)
	// IdentityByProvider finds who owns a (provider, providerID) pair — an OAuth
	// (provider name, external subject) or a trusted_ip (provider="trusted_ip",
	// the normalized RUT).
	IdentityByProvider(provider, providerID string) (Identity, error)
	// IdentityFor returns userID's identity row for provider — e.g. email_password
	// reads its bcrypt hash from Identity.ProviderId here.
	IdentityFor(userID, provider string) (Identity, error)
	UpsertIdentity(userID, provider, providerID, email string) error
	UpdateUserAvatar(userID, avatar string) error
}

IdentityStore is the persistence port a mode uses to resolve or register the domain User/Identity behind a credential. A mode never queries *orm.DB itself.

type LANIP added in v0.0.2

type LANIP struct {
	Id        string
	UserId    string
	Ip        string
	Label     string
	CreatedAt int64
}

func ReadOneLANIP added in v0.0.2

func ReadOneLANIP(qb *orm.QB, model *LANIP) (*LANIP, error)

func (*LANIP) DecodeFields added in v0.0.2

func (m *LANIP) DecodeFields(r model.FieldReader)

func (*LANIP) EncodeFields added in v0.0.2

func (m *LANIP) EncodeFields(w model.FieldWriter)

func (*LANIP) IsNil added in v0.0.2

func (m *LANIP) IsNil() bool

func (*LANIP) ModelName added in v0.0.2

func (m *LANIP) ModelName() string

func (*LANIP) Pointers added in v0.0.2

func (m *LANIP) Pointers() []any

func (*LANIP) Schema added in v0.0.2

func (m *LANIP) Schema() []model.Field

func (*LANIP) SchemaExt added in v0.0.2

func (m *LANIP) SchemaExt() []model.FieldExt

func (*LANIP) Validate added in v0.0.2

func (m *LANIP) Validate(action byte) error

type LANIPList added in v0.0.2

type LANIPList []*LANIP

func ReadAllLANIP added in v0.0.2

func ReadAllLANIP(qb *orm.QB) (LANIPList, error)

func (*LANIPList) Append added in v0.0.2

func (s *LANIPList) Append() model.Fielder

func (*LANIPList) At added in v0.0.2

func (s *LANIPList) At(i int) model.Fielder

func (*LANIPList) DecodeFields added in v0.0.2

func (s *LANIPList) DecodeFields(_ model.FieldReader)

func (*LANIPList) EncodeFields added in v0.0.2

func (s *LANIPList) EncodeFields(_ model.FieldWriter)

func (*LANIPList) IsNil added in v0.0.2

func (s *LANIPList) IsNil() bool

func (*LANIPList) Len added in v0.0.2

func (s *LANIPList) Len() int

func (*LANIPList) Pointers added in v0.0.2

func (s *LANIPList) Pointers() []any

func (*LANIPList) Schema added in v0.0.2

func (s *LANIPList) Schema() []model.Field

type LoginData added in v0.0.2

type LoginData struct {
	Email    string
	Password string
}

func (*LoginData) DecodeFields added in v0.0.2

func (m *LoginData) DecodeFields(r model.FieldReader)

func (*LoginData) EncodeFields added in v0.0.2

func (m *LoginData) EncodeFields(w model.FieldWriter)

func (*LoginData) IsNil added in v0.0.2

func (m *LoginData) IsNil() bool

func (*LoginData) ModelName added in v0.0.2

func (m *LoginData) ModelName() string

func (*LoginData) Pointers added in v0.0.2

func (m *LoginData) Pointers() []any

func (*LoginData) Schema added in v0.0.2

func (m *LoginData) Schema() []model.Field

func (*LoginData) Validate added in v0.0.2

func (m *LoginData) Validate(action byte) error

type LoginDataList added in v0.0.2

type LoginDataList []*LoginData

func (*LoginDataList) Append added in v0.0.2

func (s *LoginDataList) Append() model.Fielder

func (*LoginDataList) At added in v0.0.2

func (s *LoginDataList) At(i int) model.Fielder

func (*LoginDataList) DecodeFields added in v0.0.2

func (s *LoginDataList) DecodeFields(_ model.FieldReader)

func (*LoginDataList) EncodeFields added in v0.0.2

func (s *LoginDataList) EncodeFields(_ model.FieldWriter)

func (*LoginDataList) IsNil added in v0.0.2

func (s *LoginDataList) IsNil() bool

func (*LoginDataList) Len added in v0.0.2

func (s *LoginDataList) Len() int

func (*LoginDataList) Pointers added in v0.0.2

func (s *LoginDataList) Pointers() []any

func (*LoginDataList) Schema added in v0.0.2

func (s *LoginDataList) Schema() []model.Field

type OAuthConfig added in v0.0.2

type OAuthConfig struct {
	ClientID     string
	ClientSecret string
	RedirectURL  string
	Scopes       []string
	AuthURL      string // provider's authorization endpoint
	TokenURL     string // provider's token endpoint
}

OAuthConfig is the provider's registration: what the app declares in the provider console.

type OAuthProvider added in v0.0.2

type OAuthProvider interface {
	Name() string
	AuthCodeURL(state string) string
	ExchangeCode(code string) (OAuthToken, error)
	GetUserInfo(token OAuthToken) (OAuthUserInfo, error)
}

type OAuthState added in v0.0.2

type OAuthState struct {
	State     string
	Provider  string
	ExpiresAt int64
	CreatedAt int64
}

func ReadOneOAuthState added in v0.0.2

func ReadOneOAuthState(qb *orm.QB, model *OAuthState) (*OAuthState, error)

func (*OAuthState) DecodeFields added in v0.0.2

func (m *OAuthState) DecodeFields(r model.FieldReader)

func (*OAuthState) EncodeFields added in v0.0.2

func (m *OAuthState) EncodeFields(w model.FieldWriter)

func (*OAuthState) IsNil added in v0.0.2

func (m *OAuthState) IsNil() bool

func (*OAuthState) ModelName added in v0.0.2

func (m *OAuthState) ModelName() string

func (*OAuthState) Pointers added in v0.0.2

func (m *OAuthState) Pointers() []any

func (*OAuthState) Schema added in v0.0.2

func (m *OAuthState) Schema() []model.Field

func (*OAuthState) Validate added in v0.0.2

func (m *OAuthState) Validate(action byte) error

type OAuthStateList added in v0.0.2

type OAuthStateList []*OAuthState

func ReadAllOAuthState added in v0.0.2

func ReadAllOAuthState(qb *orm.QB) (OAuthStateList, error)

func (*OAuthStateList) Append added in v0.0.2

func (s *OAuthStateList) Append() model.Fielder

func (*OAuthStateList) At added in v0.0.2

func (s *OAuthStateList) At(i int) model.Fielder

func (*OAuthStateList) DecodeFields added in v0.0.2

func (s *OAuthStateList) DecodeFields(_ model.FieldReader)

func (*OAuthStateList) EncodeFields added in v0.0.2

func (s *OAuthStateList) EncodeFields(_ model.FieldWriter)

func (*OAuthStateList) IsNil added in v0.0.2

func (s *OAuthStateList) IsNil() bool

func (*OAuthStateList) Len added in v0.0.2

func (s *OAuthStateList) Len() int

func (*OAuthStateList) Pointers added in v0.0.2

func (s *OAuthStateList) Pointers() []any

func (*OAuthStateList) Schema added in v0.0.2

func (s *OAuthStateList) Schema() []model.Field

type OAuthToken added in v0.0.2

type OAuthToken struct {
	AccessToken string
	TokenType   string
	ExpiresIn   int
}

OAuthToken is what a provider returns when it exchanges the code. It replaces oauth2.Token: that type dragged net/http in, and net/http does not exist under TinyGo — which put this whole module out of the edge for one function call.

func (*OAuthToken) DecodeFields added in v0.0.2

func (t *OAuthToken) DecodeFields(r model.FieldReader)

func (OAuthToken) IsNil added in v0.0.2

func (t OAuthToken) IsNil() bool

type OAuthUserInfo added in v0.0.2

type OAuthUserInfo struct {
	ID     string
	Email  string
	Name   string
	Avatar string
}

type PasswordData added in v0.0.2

type PasswordData struct {
	Current string
	New     string
	Confirm string
}

func (*PasswordData) DecodeFields added in v0.0.2

func (m *PasswordData) DecodeFields(r model.FieldReader)

func (*PasswordData) EncodeFields added in v0.0.2

func (m *PasswordData) EncodeFields(w model.FieldWriter)

func (*PasswordData) IsNil added in v0.0.2

func (m *PasswordData) IsNil() bool

func (*PasswordData) ModelName added in v0.0.2

func (m *PasswordData) ModelName() string

func (*PasswordData) Pointers added in v0.0.2

func (m *PasswordData) Pointers() []any

func (*PasswordData) Schema added in v0.0.2

func (m *PasswordData) Schema() []model.Field

func (*PasswordData) Validate added in v0.0.2

func (m *PasswordData) Validate(action byte) error

type PasswordDataList added in v0.0.2

type PasswordDataList []*PasswordData

func (*PasswordDataList) Append added in v0.0.2

func (s *PasswordDataList) Append() model.Fielder

func (*PasswordDataList) At added in v0.0.2

func (s *PasswordDataList) At(i int) model.Fielder

func (*PasswordDataList) DecodeFields added in v0.0.2

func (s *PasswordDataList) DecodeFields(_ model.FieldReader)

func (*PasswordDataList) EncodeFields added in v0.0.2

func (s *PasswordDataList) EncodeFields(_ model.FieldWriter)

func (*PasswordDataList) IsNil added in v0.0.2

func (s *PasswordDataList) IsNil() bool

func (*PasswordDataList) Len added in v0.0.2

func (s *PasswordDataList) Len() int

func (*PasswordDataList) Pointers added in v0.0.2

func (s *PasswordDataList) Pointers() []any

func (*PasswordDataList) Schema added in v0.0.2

func (s *PasswordDataList) Schema() []model.Field

type ProfileDTO added in v0.0.2

type ProfileDTO struct {
	Id          string
	Name        string
	Email       string
	Avatar      string
	Roles       []string
	RoleNames   []string
	Permissions []string // "resource:actions" pairs, e.g. "service_catalog:rc"
	Locale      string
}

ProfileDTO is a safe subset of User data for public/API consumption.

func (*ProfileDTO) DecodeFields added in v0.0.2

func (p *ProfileDTO) DecodeFields(r model.FieldReader)

func (ProfileDTO) EncodeFields added in v0.0.2

func (p ProfileDTO) EncodeFields(w model.FieldWriter)

func (ProfileDTO) IsNil added in v0.0.2

func (p ProfileDTO) IsNil() bool

func (ProfileDTO) Shell added in v0.0.2

func (p ProfileDTO) Shell() ShellProfile

Shell converts a profile into the shape an application shell renders.

type ProfileData added in v0.0.2

type ProfileData struct {
	Name  string
	Phone string
}

func (*ProfileData) DecodeFields added in v0.0.2

func (m *ProfileData) DecodeFields(r model.FieldReader)

func (*ProfileData) EncodeFields added in v0.0.2

func (m *ProfileData) EncodeFields(w model.FieldWriter)

func (*ProfileData) IsNil added in v0.0.2

func (m *ProfileData) IsNil() bool

func (*ProfileData) ModelName added in v0.0.2

func (m *ProfileData) ModelName() string

func (*ProfileData) Pointers added in v0.0.2

func (m *ProfileData) Pointers() []any

func (*ProfileData) Schema added in v0.0.2

func (m *ProfileData) Schema() []model.Field

func (*ProfileData) Validate added in v0.0.2

func (m *ProfileData) Validate(action byte) error

type ProfileDataList added in v0.0.2

type ProfileDataList []*ProfileData

func (*ProfileDataList) Append added in v0.0.2

func (s *ProfileDataList) Append() model.Fielder

func (*ProfileDataList) At added in v0.0.2

func (s *ProfileDataList) At(i int) model.Fielder

func (*ProfileDataList) DecodeFields added in v0.0.2

func (s *ProfileDataList) DecodeFields(_ model.FieldReader)

func (*ProfileDataList) EncodeFields added in v0.0.2

func (s *ProfileDataList) EncodeFields(_ model.FieldWriter)

func (*ProfileDataList) IsNil added in v0.0.2

func (s *ProfileDataList) IsNil() bool

func (*ProfileDataList) Len added in v0.0.2

func (s *ProfileDataList) Len() int

func (*ProfileDataList) Pointers added in v0.0.2

func (s *ProfileDataList) Pointers() []any

func (*ProfileDataList) Schema added in v0.0.2

func (s *ProfileDataList) Schema() []model.Field

type RegisterData added in v0.0.2

type RegisterData struct {
	Name     string
	Email    string
	Password string
	Phone    string
}

func (*RegisterData) DecodeFields added in v0.0.2

func (m *RegisterData) DecodeFields(r model.FieldReader)

func (*RegisterData) EncodeFields added in v0.0.2

func (m *RegisterData) EncodeFields(w model.FieldWriter)

func (*RegisterData) IsNil added in v0.0.2

func (m *RegisterData) IsNil() bool

func (*RegisterData) ModelName added in v0.0.2

func (m *RegisterData) ModelName() string

func (*RegisterData) Pointers added in v0.0.2

func (m *RegisterData) Pointers() []any

func (*RegisterData) Schema added in v0.0.2

func (m *RegisterData) Schema() []model.Field

func (*RegisterData) Validate added in v0.0.2

func (m *RegisterData) Validate(action byte) error

type RegisterDataList added in v0.0.2

type RegisterDataList []*RegisterData

func (*RegisterDataList) Append added in v0.0.2

func (s *RegisterDataList) Append() model.Fielder

func (*RegisterDataList) At added in v0.0.2

func (s *RegisterDataList) At(i int) model.Fielder

func (*RegisterDataList) DecodeFields added in v0.0.2

func (s *RegisterDataList) DecodeFields(_ model.FieldReader)

func (*RegisterDataList) EncodeFields added in v0.0.2

func (s *RegisterDataList) EncodeFields(_ model.FieldWriter)

func (*RegisterDataList) IsNil added in v0.0.2

func (s *RegisterDataList) IsNil() bool

func (*RegisterDataList) Len added in v0.0.2

func (s *RegisterDataList) Len() int

func (*RegisterDataList) Pointers added in v0.0.2

func (s *RegisterDataList) Pointers() []any

func (*RegisterDataList) Schema added in v0.0.2

func (s *RegisterDataList) Schema() []model.Field

type SecurityEvent added in v0.0.2

type SecurityEvent struct {
	Type      SecurityEventType
	IP        string // client IP, empty if not available
	UserID    string // empty if user not yet identified
	Provider  string // OAuth provider name, for OAuth events
	Resource  string // RBAC resource, for EventAccessDenied
	Timestamp int64  // time.Now().Unix()
}

func (*SecurityEvent) EncodeFields added in v0.0.2

func (e *SecurityEvent) EncodeFields(w model.FieldWriter)

func (*SecurityEvent) IsNil added in v0.0.2

func (e *SecurityEvent) IsNil() bool

type SecurityEventType added in v0.0.2

type SecurityEventType uint8
const (
	EventJWTTampered        SecurityEventType = iota // validateJWT: jwt.Forged (never jwt.Expired)
	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"
	EventUnauthorizedAccess                          // validateSession: cookie present but session invalid
	EventAccessDenied                                // AccessCheck: RBAC denied with valid session
	EventPermissionCorrupt                           // HasPermission: permissions.action is not a CRUD string
	EventRateLimited                                 // POST /login: Config.RateLimit rejected the attempt before bcrypt
)

type SecurityNotifier added in v0.0.2

type SecurityNotifier interface {
	Notify(e SecurityEvent)
}

SecurityNotifier lets a mode report a SecurityEvent without knowing whether anything is subscribed.

type Session added in v0.0.2

type Session struct {
	Id        string
	UserId    string
	ExpiresAt int64
	Ip        string
	UserAgent string
	CreatedAt int64
}

func ReadOneSession added in v0.0.2

func ReadOneSession(qb *orm.QB, model *Session) (*Session, error)

func (*Session) DecodeFields added in v0.0.2

func (m *Session) DecodeFields(r model.FieldReader)

func (*Session) EncodeFields added in v0.0.2

func (m *Session) EncodeFields(w model.FieldWriter)

func (*Session) IsNil added in v0.0.2

func (m *Session) IsNil() bool

func (*Session) ModelName added in v0.0.2

func (m *Session) ModelName() string

func (*Session) Pointers added in v0.0.2

func (m *Session) Pointers() []any

func (*Session) Schema added in v0.0.2

func (m *Session) Schema() []model.Field

func (*Session) SchemaExt added in v0.0.2

func (m *Session) SchemaExt() []model.FieldExt

func (*Session) Validate added in v0.0.2

func (m *Session) Validate(action byte) error

type SessionIssuer added in v0.0.2

type SessionIssuer interface {
	IssueSession(ctx router.Context, userID string) error
}

SessionIssuer lets a mode start a session after verifying credentials, without knowing whether the app carries it in a cookie or a signed JWT.

type SessionList added in v0.0.2

type SessionList []*Session

func ReadAllSession added in v0.0.2

func ReadAllSession(qb *orm.QB) (SessionList, error)

func (*SessionList) Append added in v0.0.2

func (s *SessionList) Append() model.Fielder

func (*SessionList) At added in v0.0.2

func (s *SessionList) At(i int) model.Fielder

func (*SessionList) DecodeFields added in v0.0.2

func (s *SessionList) DecodeFields(_ model.FieldReader)

func (*SessionList) EncodeFields added in v0.0.2

func (s *SessionList) EncodeFields(_ model.FieldWriter)

func (*SessionList) IsNil added in v0.0.2

func (s *SessionList) IsNil() bool

func (*SessionList) Len added in v0.0.2

func (s *SessionList) Len() int

func (*SessionList) Pointers added in v0.0.2

func (s *SessionList) Pointers() []any

func (*SessionList) Schema added in v0.0.2

func (s *SessionList) Schema() []model.Field

type SessionRepo added in v0.0.2

type SessionRepo interface {
	CreateSession(userID, ip, userAgent string) (Session, error)
	GetSession(id string) (Session, error)
	DeleteSession(id string) error
}

SessionRepo is the storage port a SessionStrategy uses to persist stateful sessions. authority.Module implements it with its own table + cache.

type SessionStrategy added in v0.0.2

type SessionStrategy interface {
	Issue(ctx router.Context, userID string) error          // starts a session, writes the credential onto ctx's response
	Identify(ctx router.Context) (userID string, err error) // reads the incoming credential; "" only alongside a non-nil err
	Revoke(ctx router.Context) error                        // ends the session named by ctx's incoming credential
}

SessionStrategy is how identity survives across requests after a successful login. authority holds exactly one (default: session/cookie); the consumer may swap it via Module.SetStrategy before mounting. Implementations: session/cookie, session/jwt.

type ShellProfile added in v0.0.2

type ShellProfile struct {
	Name   string
	Avatar string
	Roles  []string // display names, never codes
}

ShellProfile is the read-only view of a session that an application shell renders.

NOT to be confused with Identity in this package, which is the ORM row tying a user to an auth provider.

func (ShellProfile) UserAvatar added in v0.0.2

func (p ShellProfile) UserAvatar() string

func (ShellProfile) UserName added in v0.0.2

func (p ShellProfile) UserName() string

func (ShellProfile) UserRoles added in v0.0.2

func (p ShellProfile) UserRoles() []string

type StateStore added in v0.0.2

type StateStore interface {
	CreateState(provider string) (state string, err error)
	ConsumeState(state, provider string) error // single-use: deletes on read, validates provider+expiry
}

StateStore is the anti-CSRF port the oauth2 mode uses for its one-time state token. authority owns the oauth_state table; a mode never touches it directly.

type SubjectStore added in v0.0.2

type SubjectStore interface {
	GetOrCreateSubject(id user.SubjectID, email, name, avatar string) (user.Subject, error)
}

SubjectStore resolves or creates a stable identity for a local development scenario. The local authenticator uses it to materialize the selected Scenario without ever contacting an external provider.

type TrustedIPStore added in v0.0.2

type TrustedIPStore interface {
	IsTrustedIP(userID, ip string) bool
}

TrustedIPStore is the read-only port the trusted_ip mode uses to check whether a request's IP is on userID's allowlist. Kept separate from IdentityStore because an allowed IP is not a login credential — it's an authorization check applied AFTER the RUT already identified the auth.

type User added in v0.0.2

type User struct {
	Id        string
	Email     string
	Name      string
	Phone     string
	Status    string
	Avatar    string
	CreatedAt int64
}

func ReadOneUser added in v0.0.2

func ReadOneUser(qb *orm.QB, model *User) (*User, error)

func (*User) DecodeFields added in v0.0.2

func (m *User) DecodeFields(r model.FieldReader)

func (*User) EncodeFields added in v0.0.2

func (m *User) EncodeFields(w model.FieldWriter)

func (*User) IsNil added in v0.0.2

func (m *User) IsNil() bool

func (*User) Item added in v0.0.2

func (m *User) Item() view.Item

Item projects a User as a list row (view.Itemizer) — the ONLY view-specific code this module writes on its model.

func (*User) ModelName added in v0.0.2

func (m *User) ModelName() string

func (*User) Pointers added in v0.0.2

func (m *User) Pointers() []any

func (*User) Schema added in v0.0.2

func (m *User) Schema() []model.Field

func (*User) Validate added in v0.0.2

func (m *User) Validate(action byte) error

type UserList added in v0.0.2

type UserList []*User

func ReadAllUser added in v0.0.2

func ReadAllUser(qb *orm.QB) (UserList, error)

func (*UserList) Append added in v0.0.2

func (s *UserList) Append() model.Fielder

func (*UserList) At added in v0.0.2

func (s *UserList) At(i int) model.Fielder

func (*UserList) DecodeFields added in v0.0.2

func (s *UserList) DecodeFields(_ model.FieldReader)

func (*UserList) EncodeFields added in v0.0.2

func (s *UserList) EncodeFields(_ model.FieldWriter)

func (*UserList) IsNil added in v0.0.2

func (s *UserList) IsNil() bool

func (*UserList) Len added in v0.0.2

func (s *UserList) Len() int

func (*UserList) Pointers added in v0.0.2

func (s *UserList) Pointers() []any

func (*UserList) Schema added in v0.0.2

func (s *UserList) Schema() []model.Field

Directories

Path Synopsis
Package local implements the development authenticator described in the Local Simulator Contract.
Package local implements the development authenticator described in the Local Simulator Contract.
session
jwt

Jump to

Keyboard shortcuts

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