Files
felhom.eu/REPORT.md
T
admin a1d045079f @
hub v0.54.0: change operator login password from the Configuration UI

Adds a "Login password" card on /configuration. The password was previously
settable only via the hub-config ConfigMap (auth.password_hash) + redeploy.

- store: hub_settings key operator_password_hash + Get/SetOperatorPasswordHash
- server: passwordHash field -> configPasswordHash (seed); new
  effectivePasswordHash() (DB override wins, else seed) is now the single
  source for the CSRF gate, RequireAuth, and handleLogin
- POST /configuration/password (handleChangePassword): requires current
  password, 8-72 byte new + confirm, bcrypt cost 10, persists DB override;
  existing sessions kept valid; ConfigMap stays the break-glass reset path
- UI: current/new/confirm form + inline mismatch pre-check + 6 flashes
- tests + red-proofs: override precedence, happy-path via handleLogin,
  wrong-current rejection, mismatch/too-short/no-op, template render
- docs: CHANGELOG, README (auth+config), REUSE, REPORT

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LbMm4T7Ayzs1unB9pN6Uqd
@
2026-07-13 22:46:49 +02:00

60 lines
3.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# felhom.eu — task reports
> **Overwrite** this file with a summary of the most recent task only (uniform with the other repos; not cumulative). The cumulative hub history lives in [hub/CHANGELOG.md](hub/CHANGELOG.md); the scripts history lives in [scripts/CHANGELOG.md](scripts/CHANGELOG.md).
## Hub v0.54.0 — operator login password changeable from the UI — 2026-07-13
### What & why
The hub login password could previously be changed **only** by editing `auth.password_hash` in the
`hub-config` ConfigMap and redeploying — no in-app path existed (operator hit this wall). Added a
**Configuration → Login password** card that changes the password at runtime, persisted in the DB,
with the ConfigMap kept as the break-glass reset path.
### Design (matches the controller-version-floor precedence pattern)
- **Store** (`internal/store/store.go`): new `hub_settings` key `operator_password_hash` with
`GetOperatorPasswordHash()` / `SetOperatorPasswordHash()` (thin wrappers over the existing
`getSetting`/`setSetting`). No schema change.
- **Server** (`internal/web/server.go`): the static `Server.passwordHash` field is renamed
`configPasswordHash` (the hub.yaml SEED). New `effectivePasswordHash()` = **DB override wins, else
config seed** — and it is now the single source for every auth check (CSRF gate, `RequireAuth`
session + Basic-Auth paths, `handleLogin`).
- **Handler** `POST /configuration/password` (`handleChangePassword`): requires the current password
(verified against the effective hash), new password 872 bytes, matching confirmation, rejects a
no-op. On success bcrypts (cost 10) and persists the override. Existing sessions stay valid; CSRF
enforced by the central `ServeHTTP` gate; no secret logged.
- **UI** (`templates/configuration.html`): current/new/confirm fields, inline client-side mismatch
pre-check, six flash outcomes.
### Recovery posture (operator's explicit choices)
- Requires the **current** password to change it (blocks a walk-up attacker on an open session).
- ConfigMap `auth.password_hash` remains the **break-glass fallback** — blank the DB row (or edit the
manifest + redeploy) to reset a forgotten password.
### Tests & red-proofs (`internal/web/change_password_test.go`)
- `TestEffectivePasswordHash_DBOverrideWins` — override wins; clearing falls back to the seed.
- `TestChangePassword_HappyPath` — end-to-end through `handleLogin` (new works, old dead).
- `TestChangePassword_WrongCurrentRejected` — security anchor: no override written.
- `TestChangePassword_ValidationRejections` — mismatch / too-short / no-op refused, no override.
- `TestConfigurationPage_RendersPasswordCard` — form renders through the production template.
- Red-proofs verified: dropping the current-password check → WrongCurrentRejected fails; breaking the
override precedence → precedence + happy-path login assertions fail.
### Gates
- `go build ./... && go vet ./... && go test ./...` (hub): green.
- `python scripts/hub_confirm_gate.py`: green (no native confirm/prompt in templates).
### Docs
- `hub/CHANGELOG.md` (v0.54.0), `hub/README.md` (Authentication + Configuration sections),
`REUSE.md` (`effectivePasswordHash`, `Get/SetOperatorPasswordHash` rows).
### Deploy
Hub image built + pushed as `v0.54.0`; `manifests/hub.yaml` tag bumped; ArgoCD synced; verified live
on `hub.felhom.eu`.