Harden Control Plane login; fix /ui redirect

Strip whitespace/quotes on pasted tokens; clearer error naming the
OpenBao founding-admin path. Redirect /ui to /ui/. Image 0.1.3.
This commit is contained in:
tegwick 2026-08-06 21:51:11 +02:00
parent 856dc354d8
commit 8cf124530c
5 changed files with 24 additions and 6 deletions

View file

@ -30,7 +30,7 @@ spec:
fsGroup: 10001 fsGroup: 10001
containers: containers:
- name: bootstrap - name: bootstrap
image: forgejo.coulomb.social/coulomb/target-revenue:0.1.2 image: forgejo.coulomb.social/coulomb/target-revenue:0.1.3
imagePullPolicy: IfNotPresent imagePullPolicy: IfNotPresent
env: env:
- name: TRF_BOOTSTRAP_BINKY - name: TRF_BOOTSTRAP_BINKY

View file

@ -25,7 +25,7 @@ spec:
fsGroup: 10001 fsGroup: 10001
containers: containers:
- name: target-revenue - name: target-revenue
image: forgejo.coulomb.social/coulomb/target-revenue:0.1.2 image: forgejo.coulomb.social/coulomb/target-revenue:0.1.3
imagePullPolicy: IfNotPresent imagePullPolicy: IfNotPresent
ports: ports:
- name: http - name: http

View file

@ -28,7 +28,7 @@ spec:
fsGroup: 10001 fsGroup: 10001
containers: containers:
- name: migrate - name: migrate
image: forgejo.coulomb.social/coulomb/target-revenue:0.1.2 image: forgejo.coulomb.social/coulomb/target-revenue:0.1.3
imagePullPolicy: IfNotPresent imagePullPolicy: IfNotPresent
env: env:
- name: TRF_RUN_MIGRATIONS - name: TRF_RUN_MIGRATIONS

View file

@ -15,6 +15,7 @@ default so a single Service port works without Traefik strip-prefix.
from __future__ import annotations from __future__ import annotations
from fastapi import FastAPI from fastapi import FastAPI
from fastapi.responses import RedirectResponse
from .app import app as trust_service_app from .app import app as trust_service_app
from .control_plane_app import app as control_plane_app from .control_plane_app import app as control_plane_app
@ -27,6 +28,12 @@ def healthz() -> dict[str, str]:
return {"status": "ok"} return {"status": "ok"}
@app.get("/ui")
def ui_no_trailing_slash() -> RedirectResponse:
"""Browsers often hit /ui without a trailing slash; the mount needs /ui/."""
return RedirectResponse(url="/ui/", status_code=307)
# More specific mount first. # More specific mount first.
app.mount("/ui", control_plane_app) app.mount("/ui", control_plane_app)
app.mount("/", trust_service_app) app.mount("/", trust_service_app)

View file

@ -166,11 +166,22 @@ def login_submit(
token: str = Form(...), token: str = Form(...),
conn: Connection = Depends(get_connection), conn: Connection = Depends(get_connection),
): ):
# OpenBao / password-manager paste often includes trailing newlines or quotes.
cleaned = token.strip().strip('"').strip("'").strip()
if not cleaned:
return _redirect("/login", request, "Credential token is required.", "danger")
try: try:
registry.authenticate(conn, token) registry.authenticate(conn, cleaned)
except registry.RegistrationError: except registry.RegistrationError:
return _redirect("/login", request, "Invalid or revoked credential token.", "danger") return _redirect(
request.session["token"] = token "/login",
request,
"Invalid or revoked credential token. Use field `token` from "
"OpenBao path platform/operators/founding-admin/revenue "
"(not a runtime DSN or signing key).",
"danger",
)
request.session["token"] = cleaned
return _redirect("/", request) return _redirect("/", request)