Shell Layer - Authentication service with side effects.
This is the SHELL layer for authentication operations:
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.
(authenticate-user auth-service email password login-context)Coordinate user authentication with all security checks including MFA.
Args: auth-service: AuthenticationService instance email: User email password: Plain text password login-context: Map with :ip-address, :user-agent, :mfa-code (optional)
Returns:
On success {:success? true :user … :session …}.
On failure {:success? false :error {:type … :message …}}, the shape
ADR-036 §3 decided — a wrong password is an answer, not an exceptional
condition, and a caller that wants to escalate can rethrow the :error
map as a typed ex-info without inventing a taxonomy. :type is one of
:validation-error, :authentication-failed, :account-locked, :mfa-required,
:mfa-enrolment-required, :mfa-verification-failed; :account-locked, and
an authentication-failed lockout, carry :retry-after.
:requires-mfa? stays at the top level: it is not part of why the attempt
failed, it is what the caller does next.
Coordinate user authentication with all security checks including MFA.
Args:
auth-service: AuthenticationService instance
email: User email
password: Plain text password
login-context: Map with :ip-address, :user-agent, :mfa-code (optional)
Returns:
On success `{:success? true :user … :session …}`.
On failure `{:success? false :error {:type … :message …}}`, the shape
ADR-036 §3 decided — a wrong password is an answer, not an exceptional
condition, and a caller that wants to escalate can rethrow the `:error`
map as a typed `ex-info` without inventing a taxonomy. `:type` is one of
`:validation-error`, `:authentication-failed`, `:account-locked`, `:mfa-required`,
`:mfa-enrolment-required`, `:mfa-verification-failed`; `:account-locked`, and
an authentication-failed lockout, carry `:retry-after`.
`:requires-mfa?` stays at the top level: it is not part of why the attempt
failed, it is what the caller does next.(create-authentication-service user-repository
session-repository
mfa-service
auth-config)Factory function: Create authentication service instance.
Args:
user-repository: IUserRepository implementation
session-repository: IUserSessionRepository implementation
mfa-service: MFAService implementation
auth-config: Authentication configuration map. :mfa-required? is an
optional (fn [user login-context] bool), a symbol naming
one, or an IMfaPolicy; throws :configuration-error otherwise.
Returns: AuthenticationService instance
Factory function: Create authentication service instance.
Args:
user-repository: IUserRepository implementation
session-repository: IUserSessionRepository implementation
mfa-service: MFAService implementation
auth-config: Authentication configuration map. :mfa-required? is an
optional (fn [user login-context] bool), a symbol naming
one, or an IMfaPolicy; throws :configuration-error otherwise.
Returns:
AuthenticationService instance(create-jwt-token user session-duration-hours)Shell function: Create JWT token for authenticated user.
Args: user: User entity session-duration-hours: How long token should be valid
Returns: JWT token string
Side effects: Crypto operations, time-dependent
Shell function: Create JWT token for authenticated user. Args: user: User entity session-duration-hours: How long token should be valid Returns: JWT token string Side effects: Crypto operations, time-dependent
(create-user-with-password user-data _user-repository)Shell function: Create user with hashed password.
Args: user-data: User creation data with plain text password user-repository: IUserRepository implementation
Returns: User entity with password-hash field populated
Side effects: Password hashing, I/O operations
Shell function: Create user with hashed password. Args: user-data: User creation data with plain text password user-repository: IUserRepository implementation Returns: User entity with password-hash field populated Side effects: Password hashing, I/O operations
(generate-session-token)Shell function: Generate cryptographically secure session token.
Returns: URL-safe base64-encoded random token string (no +, /, or = chars). Uses URL-safe encoding so tokens can safely appear in URL paths without triggering Jetty 'Ambiguous URI path separator' errors.
Side effects: Secure random generation
Shell function: Generate cryptographically secure session token. Returns: URL-safe base64-encoded random token string (no +, /, or = chars). Uses URL-safe encoding so tokens can safely appear in URL paths without triggering Jetty 'Ambiguous URI path separator' errors. Side effects: Secure random generation
(get-jwt-secret)The validated JWT_SECRET. Throws :configuration-error when it is missing or short.
The validated JWT_SECRET. Throws :configuration-error when it is missing or short.
(hash-password password)Shell function: Hash password using bcrypt.
Args: password: Plain text password
Returns: Bcrypt hash string (60 characters)
Side effects: Crypto operations with secure random
Shell function: Hash password using bcrypt. Args: password: Plain text password Returns: Bcrypt hash string (60 characters) Side effects: Crypto operations with secure random
(mfa-required? auth-service user login-context)Whether this login needs a second factor: the app's :mfa-required? hook when it set one, else whether the user turned MFA on. Shared by password and OIDC sign-in. The hook sees neither the user's secrets nor the code.
Whether this login needs a second factor: the app's :mfa-required? hook when it set one, else whether the user turned MFA on. Shared by password and OIDC sign-in. The hook sees neither the user's secrets nor the code.
(open-session! auth-service user login-risk login-context current-time)Create the DB session for a user who has proven who they are, under the session policy. Shared by password and OIDC sign-in.
Returns {:policy … :session …}; :session carries a :jwt-token that is not stored.
Create the DB session for a user who has proven who they are, under the
session policy. Shared by password and OIDC sign-in.
Returns {:policy … :session …}; :session carries a :jwt-token that is not
stored.(password-fingerprint user)What changes when user's password does, without revealing its hash: an
enrolment ticket carries it, and a changed password voids the ticket.
What changes when `user`'s password does, without revealing its hash: an enrolment ticket carries it, and a changed password voids the ticket.
(validate-jwt-secret!)Fail-fast startup check: force resolution + validation of JWT_SECRET so a missing or too-short secret aborts boot, rather than booting green and failing on the first authentication request. Call from system wiring.
Fail-fast startup check: force resolution + validation of JWT_SECRET so a missing or too-short secret aborts boot, rather than booting green and failing on the first authentication request. Call from system wiring.
(validate-jwt-token token)Shell function: Validate and decode JWT token.
Args: token: JWT token string
Returns: {:valid? true :claims {...}} or {:valid? false :error string}
Side effects: Crypto operations
Shell function: Validate and decode JWT token.
Args:
token: JWT token string
Returns:
{:valid? true :claims {...}} or {:valid? false :error string}
Side effects: Crypto operations(verify-password password hash)Shell function: Verify password against bcrypt hash.
Args:
password: Plain text password
hash: Bcrypt hash string
Returns: Boolean - true if password matches
Side effects: Crypto operations
Shell function: Verify password against bcrypt hash. Args: password: Plain text password hash: Bcrypt hash string Returns: Boolean - true if password matches Side effects: Crypto operations
(verify-second-factor! auth-service user code)Check the TOTP or backup code for user, spending a backup code. The
caller has claimed the attempt with lockout/claim-attempts!, so a wrong
or blank code stays counted, the same counter as a wrong password (BOU-698).
Returns mfa-shell/verify-mfa-code's map, or nil for a blank code.
Check the TOTP or backup `code` for `user`, spending a backup code. The caller has claimed the attempt with `lockout/claim-attempts!`, so a wrong or blank code stays counted, the same counter as a wrong password (BOU-698). Returns `mfa-shell/verify-mfa-code`'s map, or nil for a blank code.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |