Repository navigation
fix(access): the Grants grid shows what a principal holds, and changes only that - #478
Conversation
…s only that
Reported: an existing role or user showed every box unticked, and the DDL /
DML grid was hard to read. Both were worse than they looked.
- The grid opened empty for a principal that held privileges, and the SQL
compared the ticks with the whole catalog: ticking one box produced
REVOKEs for everything else it held, CONNECT on the database included.
It now opens on what is held (heldGridPermissions) and compiles only the
difference (compileGridChanges): a new tick is a GRANT, a held box cleared
is a REVOKE, and nothing the grid does not show is touched.
- Each cell shows what will happen: held, green for a grant, red for a
revoke, with a legend and "N held · N to grant · N to revoke". The change
list reads "Grant INSERT on public.orders", not missing/extra. "Custom",
which cleared every box (now: revoke everything), is "Reset to current".
- The privilege columns were off-screen: an "All / none: <name>" button per
row sat in one unwrapped strip (66 rows = 2,587px), and the pane had no
min-w-0, so the grid pushed past the window and was cut off. "All" moved
into each row; the pane is min-w-0. Catalog rows show their name as text
rather than an editable box under the schema badge.
- Bands say what they mean: "Work with rows · DML", "Change the table ·
DDL", with tooltips.
- A preset clicked while schemas were loading ticked only what had loaded;
it now applies to rows that arrive after it.
- User Management: an existing account's roles were never shown and could
not be changed ("Member of" existed only on create). New alteration
"Roles it belongs to": current roles ticked; joining is GRANT, leaving is
REVOKE (MySQL/TiDB also SET DEFAULT ROLE ALL; MariaDB's single default is
left alone, as a comment).
- Permission Diff's summary says "missing — will be granted" and "extra —
will be revoked".
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: 812280d6-18e8-436d-8be3-bcdd8d43787c) |
Test IDsRemoved (1) · a test or recorded flow outside this repo may still use these
Added (7)
|
A catalog read with no schema list keeps its rows schema-less, and the grid then keys them with the connection's default schema; the held map keyed them with none, so on such a connection a held grant would not tick its box. heldGridPermissions takes the grid's fallback schema and matches when either side's schema is unknown; two known schemas must still agree. Checked live: a MySQL role and a MariaDB role holding SELECT and INSERT on orders open with exactly those two cells ticked. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: e0e6c930-d64b-49d5-be17-092a8990b3a8) |
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: 2d0b20ca-688c-418f-8739-1bee20eba7e1) |
Reported: in Database Access an existing role or user group always shows unticked boxes, and the DDL/DML grid is hard to understand. Both were real, and the first was worse than it looked.
What was wrong
CONNECTon the database.min-w-0. The grid pushed past the window and the overflow was cut off, including the credential picker.What changes
@foxschema/sql(object-grid.ts):heldGridPermissions()maps a principal's object grants onto grid cells: exact privilege per column,ALL PRIVILEGESto every cell the engine can grant, DENY and scope-wide grants left out.compileGridChanges()turns a grid into GRANTs for new ticks and REVOKEs for held boxes cleared, and nothing else.PermissionMatrix:resetNonceputs the grid back to what is held;AccessGrantsStage:AccessPermissionPanel: the right pane ismin-w-0, so the grid scrolls inside it.SET DEFAULT ROLE ALL.Verification
object-grid.held.test.ts(8): mapping, ALL, DENY and scope-wide grants left out, by-name matching, and change sets with no stray REVOKE;user-sql.membership.test.ts(5);held;REVOKE "readonly" FROM "alice".report_userwith SELECT and INSERT on two tables.ordersopens with exactly those two cells ticked. This needed a follow-up commit, because a schema-less catalog row and a schema-qualified grant were keyed differently.npm run typecheck(web + e2e): clean. Unit project: 4,949 passed. web-ui: 332 passed, three runs in a row. ESLint: clean.🤖 Generated with Claude Code
Note
Medium Risk
Changes how access and role-membership SQL is computed in a security-sensitive area; behavior is heavily tested but mistakes could still grant or revoke the wrong privileges.
Overview
Fixes the Access Grants flow so the privilege matrix starts from what the principal already holds, and generated SQL is only the delta (new ticks → GRANT, cleared held boxes → REVOKE) instead of reconciling an empty grid against the full catalog—which could mass-revoke hidden grants like
CONNECT.@foxschema/sqladdsheldGridPermissions,compileGridChanges, andgridObjectKey; User Management gains a “Roles it belongs to” alter path that diffs memberships intoGRANT/REVOKE(with MySQL/TiDB default-role handling). The UI updatesAccessGrantsStageandPermissionMatrix(held/grant/revoke styling, legend, Reset to current, presets applied to late-loaded catalog rows, clearer DML/DDL headings, per-row All, catalog names as text), fixes wide-grid overflow viamin-w-0, and clarifies Permission Diff labels. Tests, E2E expectations, and test IDs follow the new behavior.Reviewed by Cursor Bugbot for commit 957a6a2. Bugbot is set up for automated code reviews on this repo. Configure here.