Open
Conversation
Expose cedarPolicy through backend API (DTOs, responses, use cases) and add Monaco-based code editor to group-add-dialog and group-name-edit-dialog in the Angular frontend, allowing users to write Cedar authorization policies when creating or editing user groups. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace the old grid-based permissions form (PermissionsFormComponent) and standalone permissions dialog (PermissionsAddDialogComponent) with a new list-based CedarPolicyListComponent. Each policy is shown as a row with add/edit/delete controls. Remove the "Configure permissions" button from the users page since permissions are now managed inline in group dialogs. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…rom items - Add "All tables" (*) option to table dropdowns in policy list editor - Generate cedar policy directly from CedarPolicyItem[] via policyItemsToCedarPolicy, bypassing the Permissions intermediary to preserve wildcard resource refs - Wildcard tables produce resource == RocketAdmin::Table::"connId/*" - Parser handles wildcard table entries and applies them to all tables - Fix dark theme contrast for table name and empty state text - Remove "Cedar policy" labels from group dialogs Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR introduces a Cedar policy editor workflow for user groups, replacing the legacy “permissions” dialog with a form/code-based Cedar policy editor and wiring cedarPolicy through the frontend and backend group APIs.
Changes:
- Add Cedar policy UI: a policy list form editor + Monaco-based code editor, integrated into create/edit group dialogs.
- Add frontend utilities for Cedar policy parsing and item↔policy transformations, plus a Monaco language definition for Cedar.
- Extend backend group/connection DTOs and use-cases to accept and return
cedarPolicy, and include it in group responses; remove the old permissions dialog UI.
Reviewed changes
Copilot reviewed 37 out of 37 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| frontend/src/app/services/users.service.ts | Send cedarPolicy when creating/editing groups. |
| frontend/src/app/services/users.service.spec.ts | Update request-body expectation to include cedarPolicy. |
| frontend/src/app/models/user.ts | Add cedarPolicy field to UserGroup. |
| frontend/src/app/lib/cedar-policy-parser.ts | New Cedar policy → permissions parser (frontend). |
| frontend/src/app/lib/cedar-policy-items.ts | New helpers to convert permissions ↔ policy “items” ↔ Cedar text. |
| frontend/src/app/lib/cedar-policy-generator.ts | New Cedar policy generator (currently unused). |
| frontend/src/app/lib/cedar-monaco-language.ts | Register Monaco tokenization rules for Cedar. |
| frontend/src/app/components/users/users.component.ts | Remove auto-opening legacy permissions dialog; adjust dialog widths and typings. |
| frontend/src/app/components/users/users.component.spec.ts | Update dialog-width expectations; remove permissions-dialog test. |
| frontend/src/app/components/users/users.component.html | Remove permissions button; add type="button" to non-submit buttons. |
| frontend/src/app/components/users/permissions-add-dialog/* | Remove legacy permissions dialog component + tests + templates/styles. |
| frontend/src/app/components/users/group-name-edit-dialog/group-name-edit-dialog.component.ts | Add Cedar policy editor (form/code modes) to “Edit group” dialog and send policy on save. |
| frontend/src/app/components/users/group-name-edit-dialog/group-name-edit-dialog.component.spec.ts | Add tests around table loading and Cedar policy prepopulation/mode switching. |
| frontend/src/app/components/users/group-name-edit-dialog/group-name-edit-dialog.component.html | Update dialog UI to include mode toggle + Cedar policy editor; adjust button types. |
| frontend/src/app/components/users/group-name-edit-dialog/group-name-edit-dialog.component.css | Add layout styles for the policy editor area. |
| frontend/src/app/components/users/group-add-dialog/group-add-dialog.component.ts | Add Cedar policy editor to “Create group” dialog and send policy on create. |
| frontend/src/app/components/users/group-add-dialog/group-add-dialog.component.spec.ts | Add tests around table loading and mode switching; update create call expectation. |
| frontend/src/app/components/users/group-add-dialog/group-add-dialog.component.html | Add mode toggle + Cedar policy editor UI; adjust button types. |
| frontend/src/app/components/users/group-add-dialog/group-add-dialog.component.css | Add layout styles for the policy editor area. |
| frontend/src/app/components/users/cedar-policy-list/cedar-policy-list.component.ts | New component for adding/editing/removing policy items in “form” mode. |
| frontend/src/app/components/users/cedar-policy-list/cedar-policy-list.component.spec.ts | New tests for CedarPolicyListComponent. |
| frontend/src/app/components/users/cedar-policy-list/cedar-policy-list.component.html | Template for policy item list + add/edit controls. |
| frontend/src/app/components/users/cedar-policy-list/cedar-policy-list.component.css | Styles for policy list UI. |
| backend/src/entities/group/utils/biuld-found-group-response.dto.ts | Include cedarPolicy in group response DTO builder. |
| backend/src/entities/group/use-cases/update-group-title.use.case.ts | Accept optional cedarPolicy on title update; invalidate Cedar policy cache. |
| backend/src/entities/group/dto/update-group-title.dto.ts | Add optional cedarPolicy to DTO. |
| backend/src/entities/group/dto/found-group-response.dto.ts | Add optional cedarPolicy to group response DTO. |
| backend/src/entities/group/application/data-sctructures/found-user-groups.ds.ts | Add optional cedarPolicy to group DS. |
| backend/src/entities/connection/utils/build-found-user-group-in-connection-dto.util.ts | Include cedarPolicy in group-in-connection DTO. |
| backend/src/entities/connection/use-cases/create-group-in-connection.use.case.ts | Accept optional cedarPolicy on group creation; invalidate Cedar policy cache. |
| backend/src/entities/connection/connection.controller.ts | Pass cedarPolicy from request body into create-group use case; minor import formatting. |
| backend/src/entities/connection/application/dto/found-user-groups-in-connection.dto.ts | Add optional cedarPolicy. |
| backend/src/entities/connection/application/dto/create-group-in-connection.dto.ts | Add optional cedarPolicy to create-group DTO. |
| backend/src/entities/connection/application/data-structures/create-group-in-connection.ds.ts | Add optional cedarPolicy to DS. |
Comments suppressed due to low confidence (1)
frontend/src/app/components/users/users.component.spec.ts:31
compileComponents()is asynchronous, but this test setup does notawaitit (or return the Promise). That can make the suite flaky because tests may run before compilation finishes. Make thebeforeEachasync andawait ...compileComponents(), or return the Promise frombeforeEach.
TestBed.configureTestingModule({
imports: [MatSnackBarModule, MatDialogModule, Angulartics2Module.forRoot(), UsersComponent],
providers: [provideHttpClient(), provideRouter([]), { provide: MatDialogRef, useValue: {} }],
}).compileComponents();
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+39
to
43
| savedGroup.cedarPolicy = | ||
| cedarPolicy ?? | ||
| generateCedarPolicyForGroup(connectionId, false, { | ||
| connection: { connectionId, accessLevel: AccessLevelEnum.none }, | ||
| group: { groupId: savedGroup.id, accessLevel: AccessLevelEnum.none }, |
Comment on lines
+44
to
+45
| groupToUpdate.cedarPolicy = cedarPolicy; | ||
| Cacher.invalidateCedarPolicyCache(groupToUpdate.connection.id); |
Comment on lines
+113
to
+116
| if (mode === 'code') { | ||
| // Form → Code: convert policy items directly to cedar text | ||
| this.cedarPolicy = policyItemsToCedarPolicy(this.policyItems, this.connectionID, '__new__'); | ||
| this.cedarPolicyModel = { |
Comment on lines
+58
to
+62
| .overrideComponent(GroupAddDialogComponent, { | ||
| remove: { imports: [CodeEditorModule] }, | ||
| add: { imports: [MockCodeEditorComponent], schemas: [NO_ERRORS_SCHEMA] }, | ||
| }) | ||
| .compileComponents(); |
Comment on lines
+10
to
+14
| export function parseCedarPolicy( | ||
| policyText: string, | ||
| connectionId: string, | ||
| groupId: string, | ||
| availableTables: TablePermission[], |
Comment on lines
+8
to
+12
| export const POLICY_ACTIONS = [ | ||
| { value: '*', label: 'Full access (all permissions)', needsTable: false }, | ||
| { value: 'connection:read', label: 'Connection: Read', needsTable: false }, | ||
| { value: 'connection:edit', label: 'Connection: Full access', needsTable: false }, | ||
| { value: 'group:read', label: 'Group: Read', needsTable: false }, |
Comment on lines
+1
to
+5
| import { AccessLevel, Permissions } from '../models/user'; | ||
|
|
||
| export function generateCedarPolicy(connectionId: string, permissions: Permissions): string { | ||
| const policies: string[] = []; | ||
| const connectionRef = `RocketAdmin::Connection::"${connectionId}"`; |
Comment on lines
+67
to
+71
| .overrideComponent(GroupNameEditDialogComponent, { | ||
| remove: { imports: [CodeEditorModule] }, | ||
| add: { imports: [MockCodeEditorComponent], schemas: [NO_ERRORS_SCHEMA] }, | ||
| }) | ||
| .compileComponents(); |
- Generate `resource like RocketAdmin::Table::"connId/*"` instead of `==` - Update parser to recognize both `==` and `like` for resource matching Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Group actions into optgroups: General, Connection, Group, Table - Add table:* action that expands to all four table permits - Collapse per-table full access into single table:* policy item - Use needsTable from POLICY_ACTIONS lookup instead of string prefix Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Rename "Full access" to "Full table access" for table:* action - Generate single permit with action like RocketAdmin::Action::"table:*" - Fix duplicate action == in permit template - Parser handles table:* action and action like operator Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Contributor
Author
|
blocked by #1668 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.