UI: pgcreds create button; show logged-in user
* web/templates/pgcreds.html: New Credentials card is now always rendered; Add Credentials toggle button reveals the create form (hidden by default). Shows a message when all system accounts already have credentials. Previously the card was hidden when UncredentialedAccounts was empty. * internal/ui/ui.go: added ActorName string field to PageData; added actorName(r) helper resolving username from JWT claims via DB lookup, returns empty string if unauthenticated. * internal/ui/handlers_*.go: all full-page PageData constructors now pass ActorName: u.actorName(r). * web/templates/base.html: nav bar renders actor username as a muted label before the Logout button when logged in. * web/static/style.css: added .nav-actor rule (muted grey, 0.85rem).
This commit is contained in:
102
PROGRESS.md
102
PROGRESS.md
@@ -4,6 +4,108 @@ Source of truth for current development state.
|
||||
---
|
||||
All phases complete. **v1.0.0 tagged.** All packages pass `go test ./...`; `golangci-lint run ./...` clean.
|
||||
|
||||
### 2026-03-12 — UI: pgcreds create button; show logged-in user
|
||||
|
||||
**web/templates/pgcreds.html**
|
||||
- "New Credentials" card is now always rendered; an "Add Credentials" toggle
|
||||
button reveals the create form (hidden by default). When all system accounts
|
||||
already have credentials, a message is shown instead of the form. Previously
|
||||
the entire card was hidden when `UncredentialedAccounts` was empty.
|
||||
|
||||
**internal/ui/ui.go**
|
||||
- Added `ActorName string` field to `PageData` (embedded in every page view struct)
|
||||
- Added `actorName(r *http.Request) string` helper — resolves username from JWT
|
||||
claims via a DB lookup; returns `""` if unauthenticated
|
||||
|
||||
**internal/ui/handlers_{accounts,audit,dashboard,policy}.go**
|
||||
- All full-page `PageData` constructors now pass `ActorName: u.actorName(r)`
|
||||
|
||||
**web/templates/base.html**
|
||||
- Nav bar renders the actor's username as a muted label immediately before the
|
||||
Logout button when logged in
|
||||
|
||||
**web/static/style.css**
|
||||
- Added `.nav-actor` rule (muted grey, 0.85rem) for the username label
|
||||
|
||||
All tests pass (`go test ./...`); `golangci-lint run ./...` clean.
|
||||
|
||||
### 2026-03-12 — PG credentials create form on /pgcreds page
|
||||
|
||||
**internal/ui/handlers_accounts.go**
|
||||
- `handlePGCredsList`: extended to build `UncredentialedAccounts` — system
|
||||
accounts that have no credentials yet, passed to the template for the create
|
||||
form; filters from `ListAccounts()` by type and excludes accounts already in
|
||||
the accessible-credentials set
|
||||
- `handleCreatePGCreds`: `POST /pgcreds` — validates selected account UUID
|
||||
(must be a system account), host, port, database, username, password;
|
||||
encrypts password with AES-256-GCM; calls `WritePGCredentials` then
|
||||
`SetPGCredentialOwner`; writes `EventPGCredUpdated` audit event; redirects
|
||||
to `GET /pgcreds` on success
|
||||
|
||||
**internal/ui/ui.go**
|
||||
- Registered `POST /pgcreds` route
|
||||
- Added `UncredentialedAccounts []*model.Account` field to `PGCredsData`
|
||||
|
||||
**web/templates/pgcreds.html**
|
||||
- New "New Credentials" card shown when `UncredentialedAccounts` is non-empty;
|
||||
contains a plain POST form (no HTMX, redirect on success) with:
|
||||
- Service Account dropdown populated from `UncredentialedAccounts`
|
||||
- Host / Port / Database / Username / Password inputs
|
||||
- CSRF token hidden field
|
||||
|
||||
All tests pass (`go test ./...`); `golangci-lint run ./...` clean.
|
||||
|
||||
### 2026-03-12 — PG credentials access grants UI
|
||||
|
||||
**internal/ui/handlers_accounts.go**
|
||||
- `handleGrantPGCredAccess`: `POST /accounts/{id}/pgcreds/access` — grants a
|
||||
nominated account read access to the credential set; ownership enforced
|
||||
server-side by comparing stored `owner_id` with the logged-in actor;
|
||||
grantee resolved via UUID lookup (not raw ID); writes
|
||||
`EventPGCredAccessGranted` audit event; re-renders `pgcreds_form` fragment
|
||||
- `handleRevokePGCredAccess`: `DELETE /accounts/{id}/pgcreds/access/{grantee}`
|
||||
— removes a specific grantee's read access; same ownership check as grant;
|
||||
writes `EventPGCredAccessRevoked` audit event; re-renders fragment
|
||||
- `handlePGCredsList`: `GET /pgcreds` — lists all pg_credentials accessible to
|
||||
the currently logged-in user (owned + explicitly granted)
|
||||
|
||||
**internal/ui/ui.go**
|
||||
- Registered three new routes: `POST /accounts/{id}/pgcreds/access`,
|
||||
`DELETE /accounts/{id}/pgcreds/access/{grantee}`, `GET /pgcreds`
|
||||
- Added `pgcreds` to the page template map (renders `pgcreds.html`)
|
||||
- Added `isPGCredOwner(*int64, *model.PGCredential) bool` template function
|
||||
— nil-safe ownership check used in `pgcreds_form` to gate owner-only controls
|
||||
- Added `derefInt64(*int64) int64` template function (nil-safe dereference)
|
||||
|
||||
**internal/model/model.go**
|
||||
- Added `ServiceAccountUUID string` field to `PGCredential` — populated by
|
||||
list queries so the PG creds list page can link to the account detail page
|
||||
|
||||
**internal/db/pgcred_access.go**
|
||||
- `ListAccessiblePGCreds`: extended SELECT to also fetch `a.uuid`; updated
|
||||
`scanPGCredWithUsername` to populate `ServiceAccountUUID`
|
||||
|
||||
**web/templates/fragments/pgcreds_form.html**
|
||||
- Owner sees a collapsible "Update credentials" `<details>` block; non-owners
|
||||
and grantees see metadata read-only
|
||||
- Non-owners who haven't yet created a credential see the full create form
|
||||
(first save sets them as owner)
|
||||
- New "Access Grants" section below the credential metadata:
|
||||
- Table listing all grantees with username and grant timestamp
|
||||
- Revoke button (DELETE HTMX, `hx-confirm`) — owner only
|
||||
- "Grant Access" dropdown form (POST HTMX) — owner only, populated with
|
||||
all accounts
|
||||
|
||||
**web/templates/pgcreds.html** (new page)
|
||||
- Lists all accessible credentials in a table: service account, host:port,
|
||||
database, username, updated-at, link to account detail page
|
||||
- Falls back to "No Postgres credentials accessible" when list is empty
|
||||
|
||||
**web/templates/base.html**
|
||||
- Added "PG Creds" nav link pointing to `/pgcreds`
|
||||
|
||||
All tests pass (`go test ./...`); `golangci-lint run ./...` clean.
|
||||
|
||||
### 2026-03-11 — Postgres Credentials UI + Policy/Tags UI completion
|
||||
|
||||
**internal/ui/**
|
||||
|
||||
Reference in New Issue
Block a user