Liking cljdoc? Tell your friends :D

wagoe.user.shell.auth

Shell Layer - Authentication service with side effects.

This is the SHELL layer for authentication operations:

  • Password hashing and verification (bcrypt)
  • JWT token creation and validation
  • Session token generation
  • Authentication coordination
  • MFA verification

All I/O and side effects happen here. Pure business logic is delegated to wagoe.user.core.authentication.

Shell Layer - Authentication service with side effects.

This is the SHELL layer for authentication operations:
- Password hashing and verification (bcrypt)
- JWT token creation and validation
- Session token generation
- Authentication coordination
- MFA verification

All I/O and side effects happen here. Pure business logic
is delegated to wagoe.user.core.authentication.
raw docstring

wagoe.user.shell.auth-persistence

Authentication persistence layer - manages public.auth_users table.

This namespace handles persistence for global authentication credentials in the schema-per-tenant multi-tenancy architecture (ADR-004).

Table: public.auth_users (shared across all tenants) Contains: email, password_hash, mfa_*, failed_login_count, lockout_until, active

Usage:

  • Login authentication (verify email + password)
  • MFA operations (setup, enable, disable, verify)
  • Account security (lockout, failed login tracking)
  • Password management (reset, change)

Does NOT contain:

  • User profile data (name, role, avatar) → in tenant_<slug>.users
  • Tenant-specific settings → in tenant_<slug>.users
Authentication persistence layer - manages public.auth_users table.

This namespace handles persistence for global authentication credentials
in the schema-per-tenant multi-tenancy architecture (ADR-004).

Table: public.auth_users (shared across all tenants)
Contains: email, password_hash, mfa_*, failed_login_count, lockout_until, active

Usage:
- Login authentication (verify email + password)
- MFA operations (setup, enable, disable, verify)
- Account security (lockout, failed login tracking)
- Password management (reset, change)

Does NOT contain:
- User profile data (name, role, avatar) → in tenant_<slug>.users
- Tenant-specific settings → in tenant_<slug>.users
raw docstring

wagoe.user.shell.cli

CLI commands for user management.

This is the SHELL layer in Functional Core / Imperative Shell architecture. Responsibilities:

  • Parse command-line arguments using tools.cli
  • Orchestrate service calls (no business logic here)
  • Format output (table or JSON)
  • Handle errors and exit codes

All business logic lives in wagoe.user.core.* and wagoe.user.shell.service. All observability is handled automatically by interceptors.

CLI commands for user management.

This is the SHELL layer in Functional Core / Imperative Shell architecture.
Responsibilities:
- Parse command-line arguments using tools.cli
- Orchestrate service calls (no business logic here)
- Format output (table or JSON)
- Handle errors and exit codes

All business logic lives in wagoe.user.core.* and wagoe.user.shell.service.
All observability is handled automatically by interceptors.
raw docstring

wagoe.user.shell.cli-entry

User module CLI entrypoint wrapper.

Encapsulates user-specific CLI startup so that the top-level CLI can remain as module-agnostic as possible and delegate into this module.

Configuration comes from wagoe.config, a declared dependency. It used to be resolved at runtime, which meant this CLI worked in the monorepo and asked generated projects for a db-spec their config.clj never defined (BOU-306).

User module CLI entrypoint wrapper.

Encapsulates user-specific CLI startup so that the top-level CLI can
remain as module-agnostic as possible and delegate into this module.

Configuration comes from wagoe.config, a declared dependency. It used to be
resolved at runtime, which meant this CLI worked in the monorepo and asked
generated projects for a `db-spec` their config.clj never defined (BOU-306).
raw docstring

wagoe.user.shell.cli-entry.authorization-upgrade

The JVM half of wagoe upgrade authorization: the steps that need the app's database and routes. The Babashka half edits config.edn and calls

clojure -M -m wagoe.user.shell.cli-entry.authorization-upgrade <app>.system-config <step>

  • check: what the first start of this version will move, who holds which legacy role, the routes no rule covers. Builds the routes without the rights migration or boot migrations, so it moves no rights.
  • prepare: runs the migrations and the rights migration, then prints what each user holds and where :enforce differs from :off.
  • report: those differences again. Exits 2 while any would refuse.
The JVM half of `wagoe upgrade authorization`: the steps that need the
app's database and routes. The Babashka half edits config.edn and calls

  clojure -M -m wagoe.user.shell.cli-entry.authorization-upgrade <app>.system-config <step>

- `check`: what the first start of this version will move, who holds which
  legacy role, the routes no rule covers. Builds the routes without the
  rights migration or boot migrations, so it moves no rights.
- `prepare`: runs the migrations and the rights migration, then prints what
  each user holds and where `:enforce` differs from `:off`.
- `report`: those differences again. Exits 2 while any would refuse.
raw docstring

wagoe.user.shell.data-export

The user module's contributions to data export and retention: a user's account, sessions, sign-in links, groups and audit trail, and the audit-log retention policy.

The user module's contributions to data export and retention: a user's
account, sessions, sign-in links, groups and audit trail, and the audit-log
retention policy.
raw docstring

No vars found in this namespace.

wagoe.user.shell.group-handlers

Admin pages for groups, under /web/admin/groups. Every change goes through the group service, so it is checked and audited with the signed-in admin as actor.

Admin pages for groups, under /web/admin/groups. Every change goes through
the group service, so it is checked and audited with the signed-in admin as
actor.
raw docstring

wagoe.user.shell.group-persistence

IUserGroupRepository on user_groups, user_group_members, user_roles and user_group_roles, which initialize-user-schema! creates, and the user_group_grants they replace. A scope and a role's permissions are stored as EDN text, so a uuid or keyword in them reads back as one.

IUserGroupRepository on `user_groups`, `user_group_members`, `user_roles`
and `user_group_roles`, which `initialize-user-schema!` creates, and the
`user_group_grants` they replace. A scope and a role's permissions are
stored as EDN text, so a uuid or keyword in them reads back as one.
raw docstring

wagoe.user.shell.group-service

IUserGroupService: groups, members, roles and assignments through one place, so each change is checked and audited. Reads go to the database every time.

IUserGroupService: groups, members, roles and assignments through one
place, so each change is checked and audited. Reads go to the database
every time.
raw docstring

wagoe.user.shell.hooks

The sign-in hooks, :mfa-required?, :login-redirect and :login-layout, :profile-layout, and :group-membership, which the group service reads. Each is set in :wagoe/user config or contributed by an application module's :auth part, which can be a ref to a component — config can only name a var.

The sign-in hooks, `:mfa-required?`, `:login-redirect` and `:login-layout`,
`:profile-layout`, and `:group-membership`, which the group service reads.
Each is set in `:wagoe/user` config or contributed by an application
module's `:auth` part, which can be a ref to a component — config can only
name a var.
raw docstring

wagoe.user.shell.http

HTTP routing and handlers for user module - provides structured route definitions.

This namespace implements the REST API and Web UI for user and session management.

Route Structure:

The module exports routes in a structured format {:api [...] :web [...] :static [...]} for composition by the top-level router, which applies appropriate prefixes:

API Endpoints (mounted under /api):

  • POST /api/users - Create user
  • GET /api/users/:id - Get user by ID
  • GET /api/users - List users (with filters)
  • PUT /api/users/:id - Update user
  • DELETE /api/users/:id - Soft delete user
  • POST /api/sessions - Create session (login)
  • GET /api/sessions/:token - Validate session
  • DELETE /api/sessions/:token - Invalidate session (logout)
  • POST /api/auth/login - Authenticate with email/password

Web UI Endpoints (mounted under /web):

  • GET /web/users - Users listing page
  • GET /web/users/new - Create user page
  • GET /web/users/:id - Redirect to /web/admin/users/:id
  • POST /web/users - Create user (HTMX fragment)

Static Assets (mounted at root):

  • GET /css/* - CSS assets
  • GET /js/* - JavaScript assets
  • GET /modules/* - Module-specific assets
  • GET /docs/* - Documentation

All observability is handled automatically by interceptors.

HTTP routing and handlers for user module - provides structured route definitions.

This namespace implements the REST API and Web UI for user and session management.

Route Structure:
----------------
The module exports routes in a structured format {:api [...] :web [...] :static [...]}
for composition by the top-level router, which applies appropriate prefixes:

API Endpoints (mounted under /api):
- POST   /api/users           - Create user
- GET    /api/users/:id       - Get user by ID
- GET    /api/users           - List users (with filters)
- PUT    /api/users/:id       - Update user
- DELETE /api/users/:id       - Soft delete user
- POST   /api/sessions        - Create session (login)
- GET    /api/sessions/:token - Validate session
- DELETE /api/sessions/:token - Invalidate session (logout)
- POST   /api/auth/login      - Authenticate with email/password

Web UI Endpoints (mounted under /web):
- GET    /web/users           - Users listing page
- GET    /web/users/new       - Create user page
- GET    /web/users/:id       - Redirect to /web/admin/users/:id
- POST   /web/users           - Create user (HTMX fragment)

Static Assets (mounted at root):
- GET    /css/*                - CSS assets
- GET    /js/*                 - JavaScript assets
- GET    /modules/*            - Module-specific assets
- GET    /docs/*               - Documentation

All observability is handled automatically by interceptors.
raw docstring

wagoe.user.shell.http-interceptors

HTTP-level interceptors for user module authentication, authorization, and audit.

These interceptors work with the HTTP interceptor architecture (ADR-010) and operate on HTTP contexts with enter/leave/error semantics.

Key Differences from Domain Interceptors:

  • Domain interceptors (user.shell.interceptors) handle validation/transformation pipelines
  • HTTP interceptors (this namespace) handle cross-cutting HTTP concerns (auth, audit, rate-limit)

HTTP Context Shape: {:request Ring request map :response Ring response map :route Route metadata :system {:logger :metrics-emitter :error-reporter} :attrs Additional attributes :correlation-id UUID :started-at Instant}

Usage: ["/users" {:post {:handler create-user-handler :interceptors ['user.http-interceptors/require-authenticated 'user.http-interceptors/require-admin 'user.http-interceptors/log-action]}}]

HTTP-level interceptors for user module authentication, authorization, and audit.

These interceptors work with the HTTP interceptor architecture (ADR-010) and operate
on HTTP contexts with enter/leave/error semantics.

Key Differences from Domain Interceptors:
- Domain interceptors (user.shell.interceptors) handle validation/transformation pipelines
- HTTP interceptors (this namespace) handle cross-cutting HTTP concerns (auth, audit, rate-limit)

HTTP Context Shape:
{:request       Ring request map
 :response      Ring response map
 :route         Route metadata
 :system        {:logger :metrics-emitter :error-reporter}
 :attrs         Additional attributes
 :correlation-id UUID
 :started-at    Instant}

Usage:
["/users"
 {:post {:handler create-user-handler
         :interceptors ['user.http-interceptors/require-authenticated
                        'user.http-interceptors/require-admin
                        'user.http-interceptors/log-action]}}]
raw docstring

wagoe.user.shell.identity-persistence

IUserIdentityRepository on the user_identities table, which initialize-user-schema! creates.

IUserIdentityRepository on the `user_identities` table, which
`initialize-user-schema!` creates.
raw docstring

wagoe.user.shell.interceptors

User-specific interceptors for the user creation pipeline.

These interceptors handle user domain-specific concerns like:

  • User input validation (required fields, types)
  • User data transformation (normalization, type conversion)
  • User business logic invocation (register-user service call)
  • User-specific response formatting
User-specific interceptors for the user creation pipeline.

These interceptors handle user domain-specific concerns like:
- User input validation (required fields, types)
- User data transformation (normalization, type conversion)
- User business logic invocation (register-user service call)
- User-specific response formatting
raw docstring

wagoe.user.shell.landing

The :login-redirect, :dashboard, :home, :landing and :registration settings of :wagoe/user: checked and resolved at boot, read when a user signs in or a page renders.

The `:login-redirect`, `:dashboard`, `:home`, `:landing` and `:registration`
settings of `:wagoe/user`: checked and resolved at boot, read when a user signs in or a
page renders.
raw docstring

wagoe.user.shell.lockout

The failed-login lockout every credential check shares: sign-in, the second factor, MFA disable and change-password.

The failed-login lockout every credential check shares: sign-in, the second
factor, MFA disable and change-password.
raw docstring

wagoe.user.shell.mfa

Shell Layer - MFA operations with side effects.

This is the SHELL layer for MFA operations:

  • TOTP secret generation
  • TOTP code verification
  • Backup code generation (secure random)
  • QR code generation for authenticator apps

All I/O and side effects happen here. Pure business logic is delegated to wagoe.user.core.mfa.

Shell Layer - MFA operations with side effects.

This is the SHELL layer for MFA operations:
- TOTP secret generation
- TOTP code verification
- Backup code generation (secure random)
- QR code generation for authenticator apps

All I/O and side effects happen here. Pure business logic
is delegated to wagoe.user.core.mfa.
raw docstring

wagoe.user.shell.mfa-crypto

Cryptographic protection for MFA secrets at rest.

The TOTP secret is reversible — it must be recovered to compute one-time codes — so it is AES-256-GCM encrypted under a key derived from JWT_SECRET. Backup codes are one-way — only ever compared against — so they are bcrypt-hashed (constant-time verification, self-salting).

A DB read (SQL injection, backup leak, insider) therefore yields neither a usable TOTP seed nor usable recovery codes.

Cryptographic protection for MFA secrets at rest.

The TOTP secret is *reversible* — it must be recovered to compute one-time
codes — so it is AES-256-GCM encrypted under a key derived from JWT_SECRET.
Backup codes are *one-way* — only ever compared against — so they are
bcrypt-hashed (constant-time verification, self-salting).

A DB read (SQL injection, backup leak, insider) therefore yields neither a
usable TOTP seed nor usable recovery codes.
raw docstring

wagoe.user.shell.mfa-enrolment

The ticket a user whose password was right, but who must set up a second factor before signing in, carries to the setup page: sealed in a cookie, so it proves the password without a session. It holds a fingerprint of the password, so changing the password voids it.

The ticket a user whose password was right, but who must set up a second
factor before signing in, carries to the setup page: sealed in a cookie,
so it proves the password without a session. It holds a fingerprint of the
password, so changing the password voids it.
raw docstring

wagoe.user.shell.middleware

Authentication and authorization middleware for HTTP endpoints.

This middleware provides:

  • JWT token validation
  • Session-based authentication
  • Role-based authorization
  • Request context enrichment with user information
Authentication and authorization middleware for HTTP endpoints.

This middleware provides:
- JWT token validation
- Session-based authentication
- Role-based authorization
- Request context enrichment with user information
raw docstring

wagoe.user.shell.module-wiring

Integrant wiring for the user module.

This namespace owns all Integrant init/halt methods for user-specific components so that shared system wiring does not depend directly on user shell namespaces.

Integrant wiring for the user module.

This namespace owns all Integrant init/halt methods for user-specific
components so that shared system wiring does not depend directly on
user shell namespaces.
raw docstring

wagoe.user.shell.oidc

OpenID Connect sign-in: authorization code flow with PKCE.

The pending sign-in (state, nonce, code verifier) travels in an encrypted, short-lived cookie rather than server state, so any replica can finish what another started. Discovery documents and key sets are cached per process.

Every step returns {:ok …} or {:error {:type :oidc/… :message …}}; only a bad configuration throws, at boot.

OpenID Connect sign-in: authorization code flow with PKCE.

The pending sign-in (state, nonce, code verifier) travels in an encrypted,
short-lived cookie rather than server state, so any replica can finish what
another started. Discovery documents and key sets are cached per process.

Every step returns {:ok …} or {:error {:type :oidc/… :message …}}; only a
bad configuration throws, at boot.
raw docstring

wagoe.user.shell.persistence

Shell layer for user module - implements user ports using database storage.

This namespace contains the SHELL (I/O) implementation that handles database persistence. In FC/IS architecture, this is the SHELL that:

  • Handles all I/O operations (database reads/writes)
  • Manages external system interactions
  • Contains side effects and impure operations
  • Implements wagoe.user.ports interfaces
  • Transforms between domain entities and database records

Key FC/IS principles:

  • ALL business logic stays in wagoe.user.core.*
  • This is ONLY for I/O and persistence concerns
  • No business decisions made here - only data transformation
  • Shell coordinates with core for business logic

This provides proper FC/IS separation where:

  • Core contains pure business logic (no I/O)
  • Shell handles all I/O and external systems
  • Clean boundary between functional and imperative code
Shell layer for user module - implements user ports using database storage.

This namespace contains the SHELL (I/O) implementation that handles database persistence.
In FC/IS architecture, this is the SHELL that:
- Handles all I/O operations (database reads/writes)
- Manages external system interactions
- Contains side effects and impure operations
- Implements wagoe.user.ports interfaces
- Transforms between domain entities and database records

Key FC/IS principles:
- ALL business logic stays in wagoe.user.core.*
- This is ONLY for I/O and persistence concerns
- No business decisions made here - only data transformation
- Shell coordinates with core for business logic

This provides proper FC/IS separation where:
- Core contains pure business logic (no I/O)
- Shell handles all I/O and external systems
- Clean boundary between functional and imperative code
raw docstring

wagoe.user.shell.rights-handlers

Admin pages for roles, permissions and a user's rights (ADR-041 §7). Changes go through the group service, so they are checked and audited.

Admin pages for roles, permissions and a user's rights (ADR-041 §7). Changes
go through the group service, so they are checked and audited.
raw docstring

wagoe.user.shell.sealed

Encrypted, short-lived cookie values that carry one sign-in step to the next without server state.

Encrypted, short-lived cookie values that carry one sign-in step to the
next without server state.
raw docstring

wagoe.user.shell.service

FC/IS Shell Layer - User module service coordination.

This is the SHELL layer in Functional Core / Imperative Shell architecture. The shell coordinates between:

  • Pure functional CORE (wagoe.user.core.*)
  • I/O SHELL persistence (wagoe.user.shell.persistence)

Shell responsibilities:

  1. Coordinate calls between core and persistence layers
  2. Manage external dependencies (time, UUIDs, logging)
  3. Handle all side effects and I/O operations
  4. Orchestrate transaction boundaries
  5. Transform between external and internal representations

The shell does NOT contain business logic - that lives in core.* The shell does NOT handle database operations - that lives in persistence.*

FC/IS Shell Layer - User module service coordination.

This is the SHELL layer in Functional Core / Imperative Shell architecture.
The shell coordinates between:
- Pure functional CORE (wagoe.user.core.*)
- I/O SHELL persistence (wagoe.user.shell.persistence)

Shell responsibilities:
1. Coordinate calls between core and persistence layers
2. Manage external dependencies (time, UUIDs, logging)
3. Handle all side effects and I/O operations
4. Orchestrate transaction boundaries
5. Transform between external and internal representations

The shell does NOT contain business logic - that lives in core.*
The shell does NOT handle database operations - that lives in persistence.*
raw docstring

wagoe.user.shell.session-pruner

Removes expired sessions on a schedule.

Expiry only hides a session: find-session-by-token filters on expires_at and revoked_at, so the reads stay correct while the table grows with every login, forever. Nothing deleted a row until BOU-429.

The schedule lives here rather than in the jobs module because jobs is optional and the user module is not — a deployment that never enables jobs still has the table. One timer per process: every replica prunes, which is harmless, because a DELETE that finds nothing costs a single indexed scan and two replicas deleting the same rows is the same DELETE twice.

Removes expired sessions on a schedule.

Expiry only hides a session: `find-session-by-token` filters on `expires_at`
and `revoked_at`, so the reads stay correct while the table grows with every
login, forever. Nothing deleted a row until BOU-429.

The schedule lives here rather than in the jobs module because jobs is
optional and the user module is not — a deployment that never enables jobs
still has the table. One timer per process: every replica prunes, which is
harmless, because a DELETE that finds nothing costs a single indexed scan
and two replicas deleting the same rows is the same DELETE twice.
raw docstring

wagoe.user.shell.user-tables

The user library's migration (BOU-611): it runs initialize-user-schema!, the definition boot uses, so migrate up and a first boot give the same tables, and a later migration can reference them.

The user library's migration (BOU-611): it runs `initialize-user-schema!`,
the definition boot uses, so `migrate up` and a first boot give the same
tables, and a later migration can reference them.
raw docstring

wagoe.user.shell.web-handlers

Web UI handlers for user module.

This namespace implements Ring handlers that return HTML responses for user-related web pages, either full pages or HTMX partial updates.

Handler Categories:

  • Page Handlers: Return full HTML pages for initial browser requests
  • HTMX Handlers: Return HTML fragments for dynamic updates

All handlers use the shared UI components and user shell services.

Web UI handlers for user module.

This namespace implements Ring handlers that return HTML responses
for user-related web pages, either full pages or HTMX partial updates.

Handler Categories:
- Page Handlers: Return full HTML pages for initial browser requests
- HTMX Handlers: Return HTML fragments for dynamic updates

All handlers use the shared UI components and user shell services.
raw docstring

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
←Move to previous article
→Move to next article
Ctrl+/Jump to the search field
× close