af60ca446d
The fabledscryer->steward rename had only ever reached host_agent. The other five bundled plugins (http, snmp, traefik, unifi, docker) still imported `from fabledscryer.*` (package no longer exists) and read FABLEDSCRYER_* env vars — so every one of them was broken at import since the original rebrand. CI stayed green only because none are enabled by default and migrations don't import plugin modules. Now that they version in-tree, complete the rename: - fabledscryer.* -> steward.* imports across all five plugins - FABLEDSCRYER_* -> STEWARD_* in plugin migration env.py files - author/repository/homepage + user-facing 'Fabled Scryer' strings -> Steward - snmp/scheduler.py: also drop dead `now`/datetime; record_metric from steward Adds tests/test_no_legacy_names.py — fails if 'scryer'/'roundtable' ever reappear in shipped code (the drift bit twice; this stops a third time). Also clears pre-existing ruff lint debt (unused imports, semicolon statements, mid-file import) surfaced by the new lint lane. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
179 lines
8.1 KiB
HTML
179 lines
8.1 KiB
HTML
{# steward/templates/settings/auth.html #}
|
|
{% extends "base.html" %}
|
|
{% block title %}Settings — Auth — Steward{% endblock %}
|
|
{% block content %}
|
|
{% set active_tab = "auth" %}
|
|
{% include "settings/_tabs.html" %}
|
|
|
|
<form method="post" action="/settings/auth/">
|
|
<div style="display:grid;gap:1.25rem;max-width:640px;">
|
|
|
|
{# ── OIDC ─────────────────────────────────────────────────────────────────── #}
|
|
<div class="card">
|
|
<h2 class="section-title" style="margin-bottom:1.25rem;">OIDC / SSO</h2>
|
|
<p style="font-size:0.82rem;color:var(--text-muted);margin-bottom:1rem;">
|
|
Supports any OIDC provider — Authentik, Keycloak, Authelia, etc. Uses Authorization Code flow.
|
|
Local admin login always works regardless of OIDC status.
|
|
</p>
|
|
|
|
<div class="form-group" style="display:flex;align-items:center;gap:0.75rem;">
|
|
<input type="checkbox" name="oidc.enabled" id="oidc-enabled"
|
|
{% if settings['oidc.enabled'] %}checked{% endif %}>
|
|
<label for="oidc-enabled" style="margin:0;">Enable OIDC login</label>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label>Discovery URL</label>
|
|
<input type="text" name="oidc.discovery_url" value="{{ settings['oidc.discovery_url'] }}"
|
|
placeholder="https://auth.example.com/application/o/steward/.well-known/openid-configuration">
|
|
<p style="font-size:0.75rem;color:var(--text-muted);margin-top:0.2rem;">
|
|
Authentik: <code>https://<host>/application/o/<slug>/.well-known/openid-configuration</code>
|
|
</p>
|
|
</div>
|
|
|
|
<div style="display:grid;grid-template-columns:1fr 1fr;gap:1rem;">
|
|
<div class="form-group">
|
|
<label>Client ID</label>
|
|
<input type="text" name="oidc.client_id" value="{{ settings['oidc.client_id'] }}"
|
|
autocomplete="off">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>Client Secret <span style="color:var(--text-dim);font-size:0.8rem;">(blank = keep current)</span></label>
|
|
<input type="password" name="oidc.client_secret" placeholder="••••••••"
|
|
autocomplete="new-password">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label>Scopes</label>
|
|
<input type="text" name="oidc.scopes" value="{{ settings['oidc.scopes'] }}"
|
|
placeholder="openid profile email">
|
|
</div>
|
|
|
|
<div style="display:grid;grid-template-columns:1fr 1fr 1fr;gap:1rem;">
|
|
<div class="form-group">
|
|
<label>Username claim</label>
|
|
<input type="text" name="oidc.username_claim" value="{{ settings['oidc.username_claim'] }}"
|
|
placeholder="preferred_username">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>Email claim</label>
|
|
<input type="text" name="oidc.email_claim" value="{{ settings['oidc.email_claim'] }}"
|
|
placeholder="email">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>Groups claim</label>
|
|
<input type="text" name="oidc.groups_claim" value="{{ settings['oidc.groups_claim'] }}"
|
|
placeholder="groups">
|
|
</div>
|
|
</div>
|
|
|
|
<div style="display:grid;grid-template-columns:1fr 1fr;gap:1rem;">
|
|
<div class="form-group">
|
|
<label>Admin group name</label>
|
|
<input type="text" name="oidc.admin_group" value="{{ settings['oidc.admin_group'] }}"
|
|
placeholder="steward-admins">
|
|
<p style="font-size:0.75rem;color:var(--text-muted);margin-top:0.2rem;">Members → admin role</p>
|
|
</div>
|
|
<div class="form-group">
|
|
<label>Operator group name</label>
|
|
<input type="text" name="oidc.operator_group" value="{{ settings['oidc.operator_group'] }}"
|
|
placeholder="steward-operators">
|
|
<p style="font-size:0.75rem;color:var(--text-muted);margin-top:0.2rem;">Members → operator role; others → viewer</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{# ── LDAP ─────────────────────────────────────────────────────────────────── #}
|
|
<div class="card">
|
|
<h2 class="section-title" style="margin-bottom:1.25rem;">LDAP</h2>
|
|
<p style="font-size:0.82rem;color:var(--text-muted);margin-bottom:1rem;">
|
|
Binds user credentials against an LDAP/AD directory. Requires the
|
|
<code>ldap3</code> Python package (<code>pip install ldap3</code>).
|
|
If both LDAP and OIDC are enabled, the login form tries LDAP; OIDC uses the SSO button.
|
|
</p>
|
|
|
|
<div class="form-group" style="display:flex;align-items:center;gap:0.75rem;">
|
|
<input type="checkbox" name="ldap.enabled" id="ldap-enabled"
|
|
{% if settings['ldap.enabled'] %}checked{% endif %}>
|
|
<label for="ldap-enabled" style="margin:0;">Enable LDAP login</label>
|
|
</div>
|
|
|
|
<div style="display:grid;grid-template-columns:1fr auto auto;gap:1rem;align-items:end;">
|
|
<div class="form-group">
|
|
<label>LDAP host</label>
|
|
<input type="text" name="ldap.host" value="{{ settings['ldap.host'] }}"
|
|
placeholder="ldap.example.com">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>Port</label>
|
|
<input type="number" name="ldap.port" value="{{ settings['ldap.port'] }}" style="width:80px;">
|
|
</div>
|
|
<div class="form-group" style="display:flex;align-items:center;gap:0.5rem;padding-bottom:0.1rem;">
|
|
<input type="checkbox" name="ldap.tls" id="ldap-tls"
|
|
{% if settings['ldap.tls'] %}checked{% endif %}>
|
|
<label for="ldap-tls" style="margin:0;white-space:nowrap;">StartTLS</label>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label>Service account bind DN</label>
|
|
<input type="text" name="ldap.bind_dn" value="{{ settings['ldap.bind_dn'] }}"
|
|
placeholder="cn=svc-steward,ou=service,dc=example,dc=com">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>Bind password <span style="color:var(--text-dim);font-size:0.8rem;">(blank = keep current)</span></label>
|
|
<input type="password" name="ldap.bind_password" placeholder="••••••••"
|
|
autocomplete="new-password">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>Base DN</label>
|
|
<input type="text" name="ldap.base_dn" value="{{ settings['ldap.base_dn'] }}"
|
|
placeholder="ou=users,dc=example,dc=com">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>User search filter</label>
|
|
<input type="text" name="ldap.user_filter" value="{{ settings['ldap.user_filter'] }}"
|
|
placeholder="(uid={username})">
|
|
<p style="font-size:0.75rem;color:var(--text-muted);margin-top:0.2rem;">
|
|
<code>{username}</code> is replaced with the login username. AD example: <code>(sAMAccountName={username})</code>
|
|
</p>
|
|
</div>
|
|
|
|
<div style="display:grid;grid-template-columns:1fr 1fr;gap:1rem;">
|
|
<div class="form-group">
|
|
<label>Admin group DN</label>
|
|
<input type="text" name="ldap.admin_group_dn" value="{{ settings['ldap.admin_group_dn'] }}"
|
|
placeholder="cn=steward-admins,ou=groups,dc=example,dc=com">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>Operator group DN</label>
|
|
<input type="text" name="ldap.operator_group_dn" value="{{ settings['ldap.operator_group_dn'] }}"
|
|
placeholder="cn=steward-operators,ou=groups,dc=example,dc=com">
|
|
</div>
|
|
</div>
|
|
|
|
<div style="display:grid;grid-template-columns:1fr 1fr;gap:1rem;">
|
|
<div class="form-group">
|
|
<label>Username attribute</label>
|
|
<input type="text" name="ldap.attr_username" value="{{ settings['ldap.attr_username'] }}"
|
|
placeholder="uid">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>Email attribute</label>
|
|
<input type="text" name="ldap.attr_email" value="{{ settings['ldap.attr_email'] }}"
|
|
placeholder="mail">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
<div style="margin-top:1.25rem;">
|
|
<button type="submit" class="btn">Save</button>
|
|
<span style="color:var(--text-muted);font-size:0.82rem;margin-left:1rem;">
|
|
Changes take effect immediately.
|
|
</span>
|
|
</div>
|
|
</form>
|
|
{% endblock %}
|