Custom Login Template
Relevant source files
The following files were used as context for generating this wiki page:
The Hodor Custom Login Template allows you to replace the built-in authentication interface with a personalized HTML page. This feature uses the Jinja2 template engine via the minijinja library to render dynamic content such as page titles and error messages while maintaining the security protocols of the reverse proxy.
Hodor provides a default dark-themed login page embedded in the binary. You can override this by providing a path to an external HTML file through configuration.
Sources: README.md:200-205, src/templates.rs:9-10
Template Configuration and Initialization
Hodor manages the custom template through its layered configuration system. The TEMPLATE environment variable or the template key in hodor.toml defines the file path for the custom HTML content.
Initialization Flow
During startup, the application builds the global state and processes template requirements:
- Loading: The
load_templatefunction checks if a custom path exists. If provided, it reads the file from disk; otherwise, it returns the built-in template string. - Validation: The system calls
validate_templateto ensure the HTML is a valid Jinja2 template. It attempts a test render with placeholder data. - Storage: The validated template source is stored in
AppStatefor use during request handling.
Sources: src/state.rs:60-68, src/templates.rs:13-19, src/config.rs:109-112
The diagram shows the logic for selecting and validating the login template during application startup. Sources: src/state.rs:60-70, src/templates.rs:13-19
Template Variables and Logic
Templates have access to specific variables provided by the render_login_page function. Use these variables within double curly braces (e.g., {{ title }}) or control structures.
| Variable | Type | Description |
|---|---|---|
title | string | The configured page title (auto-escaped). |
show_error | bool | Set to true if a previous login attempt failed. |
custom_css | string | Verbatim CSS defined in CUSTOM_CSS config. |
disable_default_css | bool | Indicates if built-in styles should be suppressed. |
Sources: src/templates.rs:64-75, README.md:213-219
Handling CSS Overrides
Hodor supports styling through two complementary configuration options:
CUSTOM_CSS: Injects a<style>block after built-in styles. In your template, you must include{{ custom_css | safe }}to render this CSS without escaping.DISABLE_DEFAULT_CSS: When set totrue, thedisable_default_cssvariable allows you to conditionally omit the default CSS block.
Sources: src/template.html:7-10, README.md:175-180
Implementation Requirements
Custom templates must follow specific functional requirements to interact correctly with the Hodor backend.
Required Form Fields
To authenticate successfully, the template must include a <form> targeting the /_gate/login endpoint.
- POST Method: The form must use
method="post". - Action: The form must point to
action="/_gate/login". - Password Input: An
<input>field withname="password"is required. - Redirect Field: A hidden input with
name="redirect"should be included. This allows Hodor to return the user to their original destination after login.
Sources: src/template.html:105-108, README.md:223-228
Scripting and Redirects
The built-in template uses JavaScript to capture the current URL (path, search, and hash) and populate the redirect hidden input. This ensures deep links are preserved across the authentication boundary.
const redirect = document.querySelector('input[name="redirect"]');
if (redirect) {
redirect.value = `${window.location.pathname}${window.location.search}${window.location.hash}` || '/';
}
Sources: src/template.html:132-135
Sequence of Rendering
When a user accesses a protected path without a valid session, the proxy triggers the login page response.
The sequence diagram illustrates how Hodor selects and renders the login template based on the user's authentication state. Sources: src/templates.rs:89-102, src/auth.rs:72-108, src/proxy.rs:50-60
Testing Custom Templates
You can verify template syntax and rendering behavior using the internal validate_template function. This function checks that the Jinja2 environment can successfully parse the source and render it with the expected context variables.
- Syntactic Validity: Rejects templates with invalid Jinja2 tags (e.g.,
{% invalid %}). - Security: Ensures the
titleis correctly escaped to prevent Cross-Site Scripting (XSS). - CSS Injection: Verifies that
custom_cssis included verbatim when provided.
Sources: src/templates.rs:31-43, src/tests/templates.rs:10-50
Summary
The Custom Login Template feature provides flexibility for branding and user experience while offloading the complexities of session management and brute-force protection to Hodor. By providing a valid Jinja2 HTML file and adhering to the required form structure, you can fully control the entry point of your protected application.