Skip to content

Privileged RDAP grant administration (RPD §9)#2941

Merged
OlegPhenomenon merged 2 commits into
feat/rdap-data-apifrom
feat/09-registry-privileged-admin
Jul 13, 2026
Merged

Privileged RDAP grant administration (RPD §9)#2941
OlegPhenomenon merged 2 commits into
feat/rdap-data-apifrom
feat/09-registry-privileged-admin

Conversation

@OlegPhenomenon

Copy link
Copy Markdown
Contributor

Admin CRUD for RdapPrivilegeGrant, built inside the registry app next to the data it manages (spec 09-registry-privileged-admin; RDAP specs-repo companion PR internetee/RDAP#feat/09-registry-privileged-admin). Stacks on feat/rdap-data-api (PR #2937).

What this adds

  • Migrations: full_name (NOT NULL), legal_basis_ref (NOT NULL), optional personal_id_code on rdap_privilege_grants; new per-model log_rdap_privilege_grants paper_trail table + creator_str/updator_str.
  • Model: include Versions (immutable audit), presence validations, read-time derived expired?/display_status. Stored STATUSES stays active/revoked/suspended.
  • Admin CRUD: controller/views/routes mirroring admin_users, with distinct suspend/revoke member actions and no destroy. can :manage, RdapPrivilegeGrant for the admin role only. Gated menu link + fresh i18n.
  • PII discipline: personal_id_code is capture-only — absent from the index and the frozen internal serializer, filtered from logs (config.filter_parameters), omitted from the rendered audit-change table.

Frozen contract preserved

api/v1/internal/rdap/grants_controller#serialize is byte-for-byte unchanged (git diff empty); active_for_subject and grant_id untouched. A serializer test asserts the new admin-only fields never leak.

Tests (Docker shared stack)

docker exec docker-images-registry-1 bin/rails test on the affected files: 42 runs / 135 assertions / 0 failures / 0 errors — model, admin integration (CRUD, suspend/revoke, auth gating, audit history, no-delete route, no PII, no missing translations), and serializer no-leak. Audit test proves a log_rdap_privilege_grants row is written on create and update with whodunnit = id_role_username.

Notes for reviewers

  • The plan's permit list omitted eeid_subject, but the model requires it and creating a valid grant is impossible without it — so it is permitted and on the form.
  • personal_id_code encryption-at-rest is deferred to a follow-up (Rails 6.1 has no ActiveRecord::Encryption, no in-app precedent); recorded, not dropped.
  • The network/VPN restriction is a documented deploy precondition, not app code.

Do not merge without review.

Admin CRUD, inside the registry app, for managing RdapPrivilegeGrant
(spec 09-registry-privileged-admin), sitting next to the data it manages.

- Migration: add full_name (NOT NULL), legal_basis_ref (NOT NULL) and
  optional personal_id_code to rdap_privilege_grants; new per-model
  log_rdap_privilege_grants audit table + creator_str/updator_str columns.
- Model: include the Versions concern (immutable paper_trail audit),
  presence validations for full_name/legal_basis_ref, and a read-time
  derived expired?/display_status (STATUSES stays active/revoked/suspended).
- Controller/views/routes: top-level admin CRUD mirroring admin_users, with
  distinct suspend/revoke member actions and no destroy (grants end via
  suspend/revoke only; audit entries have no edit/delete route).
- Ability: can :manage, RdapPrivilegeGrant for the admin role only.
- personal_id_code is capture-only: never in the index, never in the frozen
  internal grants serializer, filtered from logs (config.filter_parameters).
- The frozen api/v1/internal/rdap/grants_controller#serialize is untouched;
  active_for_subject and grant_id are unchanged.
- Fresh i18n keys + menu link; all 6 fixtures populated for the new columns.
- Tests: model (validations, derived expired, revoke-takes-effect), admin
  integration (CRUD, suspend/revoke, auth gating, audit history, no-delete
  route, no PII/no missing-translation), serializer no-leak.
…it history

Closes the AC23 gap the tester found: the show page's paper_trail audit
table is built from object_changes, a potential PII vector. The view already
does object_changes.except('personal_id_code'); this test proves it — creates
a grant with the code, makes an audit-generating change, asserts the value
never appears on the rendered show page.

43 runs / 140 assertions / 0 failures via docker exec docker-images-registry-1.
@OlegPhenomenon OlegPhenomenon merged commit 5726937 into feat/rdap-data-api Jul 13, 2026
1 of 3 checks passed
@OlegPhenomenon OlegPhenomenon deleted the feat/09-registry-privileged-admin branch July 13, 2026 12:43
@mergify

mergify Bot commented Jul 13, 2026

Copy link
Copy Markdown

⚠️ The sha of the head commit of this PR conflicts with #2937. Mergify cannot evaluate rules on this PR. Once #2937 is merged or closed, Mergify will resume processing this PR. ⚠️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant