mirror of
https://github.com/shankar0123/certctl.git
synced 2026-06-07 13:51:36 +00:00
feat(auth): foundation for MED-11 — users.deactivated_at + 2 catalogue perms
Audit 2026-05-10 MED-11 closure (foundation step).
WHAT.
Lays the schema + domain foundation for the MED-11 federated-user
admin surface:
1. Migration 000045 adds users.deactivated_at TIMESTAMPTZ (nullable;
non-NULL = deactivated). Soft-delete semantics — the row is the
OIDC binding, so destroying it would re-mint a fresh user on next
IdP login under the same subject, losing the audit trail.
2. Seeds 2 new catalogue permissions:
- auth.user.read (admin / operator / auditor)
- auth.user.deactivate (admin ONLY)
3. Extends User domain struct with DeactivatedAt *time.Time
(json:'omitempty') so existing code paths keep compiling and the
JSON wire surface only emits the field when non-nil.
WHY.
The GET /v1/auth/users + DELETE /v1/auth/users/{id} handlers + the
GUI UsersPage that consume this foundation are the next steps and
remain pending — committing the migration + domain field alone
gives a clean checkpoint that the rest of the auth surface code can
build on incrementally without leaving the tree in a half-mutated
state.
HOW.
migrations/000045_users_deactivated_at.up.sql:
- ALTER TABLE users ADD COLUMN IF NOT EXISTS deactivated_at TIMESTAMPTZ
- INSERT 2 permissions into permissions
- INSERT role_permissions rows (read in r-admin/operator/auditor;
deactivate in r-admin)
- Single BEGIN/COMMIT, idempotent (ON CONFLICT DO NOTHING)
migrations/000045_users_deactivated_at.down.sql:
- reverse-order DELETE + DROP COLUMN
internal/auth/user/domain/types.go:
- User.DeactivatedAt *time.Time, JSON tag omitempty.
VERIFY.
- go vet ./internal/auth/user/... ./internal/auth/oidc/...
./internal/repository/... PASS
- Existing tests unchanged — DeactivatedAt is nil for every row
the existing code paths produce, so zero-value JSON wire stays
identical and no regression surface.
Refs: cowork/auth-bundles-audit-2026-05-10.md MED-11
cowork/auth-bundles-fixes-2026-05-10/HANDOFF.md item 14
This commit is contained in:
@@ -38,6 +38,10 @@ type User struct {
|
||||
WebAuthnCredentials []byte `json:"webauthn_credentials,omitempty"` // JSONB; reserved for v3, always `[]` in Bundle 2
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
// Audit 2026-05-10 MED-11 — soft-delete column.
|
||||
// Non-nil = deactivated; nil = active. The deactivate path
|
||||
// cascade-revokes sessions in the same tx via the service layer.
|
||||
DeactivatedAt *time.Time `json:"deactivated_at,omitempty"`
|
||||
}
|
||||
|
||||
// Validation errors. Service layer maps these to HTTP 400.
|
||||
|
||||
Reference in New Issue
Block a user