feat(web): registration gate + per-request user-id seam (ADR-012)
Multi-user web surface. Two layered middlewares: Auth.Middleware (Dex session required) wraps registrationGate, which resolves the authenticated subject -> tapir user_id once per request via the new web.Identity port and stashes it. A subject with no tapir user is redirected to GET /register (display name + accept-terms); POST /register calls RegisterUser then redirects to /. /register is inside the auth guard but exempt from the gate (/auth/* and /healthz too). Current-user seam: CurrentUserID(r) (string, bool) returns the resolved id from the request context. The list/detail/action handlers now scope by it, replacing the single configured App.UserID (removed). App gains an Identity field; *store.Store satisfies both Store and Identity. cmd/tapir wires Identity: st and drops UserID. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+6
-5
@@ -144,10 +144,11 @@ func cmdRun(ctx context.Context, log *slog.Logger) error {
|
||||
return r.Loop(ctx, cfg.PollInterval)
|
||||
}
|
||||
|
||||
// cmdServe runs the Stage-0 web UI: the summary reader over the existing store
|
||||
// (ADR-003 — a new transport, not new core). Auth is the StubAuth allow-all seam
|
||||
// keyed to the configured user; the Conductor swaps in oidc.DexAuth at merge —
|
||||
// the only line that changes is the `authn` assignment below.
|
||||
// cmdServe runs the Stage-1 web UI: the summary reader over the existing store
|
||||
// (ADR-003 — a new transport, not new core). Auth (web.Auth) gates access; the
|
||||
// registration gate resolves the authenticated subject to a tapir user_id and
|
||||
// scopes every store access by it (ADR-012). With Dex configured, real OIDC login
|
||||
// is used; otherwise StubAuth (dev only). The store doubles as the Identity port.
|
||||
func cmdServe(ctx context.Context, log *slog.Logger) error {
|
||||
cfg, err := config.Load()
|
||||
if err != nil {
|
||||
@@ -185,7 +186,7 @@ func cmdServe(ctx context.Context, log *slog.Logger) error {
|
||||
log.Warn("web auth: STUB allow-all (no TAPIR_OIDC_ISSUER) — local dev only, do not expose")
|
||||
}
|
||||
|
||||
app := &web.App{Store: st, Auth: authn, UserID: cfg.UserID, Log: log}
|
||||
app := &web.App{Store: st, Identity: st, Auth: authn, Log: log}
|
||||
srv := &http.Server{
|
||||
Addr: cfg.HTTPAddr,
|
||||
Handler: app.Router(),
|
||||
|
||||
Reference in New Issue
Block a user