Skip to content

Commit e8cbf68

Browse files
guguclaude
andcommitted
feat: add dashboard:* full access action and use "All dashboards" wildcard
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent bffa5cf commit e8cbf68

4 files changed

Lines changed: 11 additions & 7 deletions

File tree

frontend/src/app/components/users/cedar-policy-list/cedar-policy-list.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
<mat-form-field *ngIf="editNeedsDashboard" appearance="outline" class="policy-field">
5656
<mat-label>Dashboard</mat-label>
5757
<mat-select [(ngModel)]="editDashboardId" [ngModelOptions]="{standalone: true}">
58-
<mat-option value="__new__">New dashboards</mat-option>
58+
<mat-option value="*">All dashboards</mat-option>
5959
<mat-option *ngFor="let dashboard of availableDashboards" [value]="dashboard.id">
6060
{{ dashboard.name }}
6161
</mat-option>

frontend/src/app/components/users/cedar-policy-list/cedar-policy-list.component.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,6 @@ describe('CedarPolicyListComponent', () => {
187187
it('should return correct dashboard display names', () => {
188188
expect(component.getDashboardDisplayName('dash-1')).toBe('Sales Dashboard');
189189
expect(component.getDashboardDisplayName('unknown')).toBe('unknown');
190-
expect(component.getDashboardDisplayName('__new__')).toBe('New dashboards');
190+
expect(component.getDashboardDisplayName('*')).toBe('All dashboards');
191191
});
192192
});

frontend/src/app/components/users/cedar-policy-list/cedar-policy-list.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ export class CedarPolicyListComponent {
8080
}
8181

8282
getDashboardDisplayName(dashboardId: string): string {
83-
if (dashboardId === '__new__') return 'New dashboards';
83+
if (dashboardId === '*') return 'All dashboards';
8484
return this.availableDashboards.find((d) => d.id === dashboardId)?.name || dashboardId;
8585
}
8686

frontend/src/app/lib/cedar-policy-items.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ export const POLICY_ACTION_GROUPS: PolicyActionGroup[] = [
5050
{
5151
group: 'Dashboard',
5252
actions: [
53+
{ value: 'dashboard:*', label: 'Full dashboard access', needsTable: false, needsDashboard: true },
5354
{ value: 'dashboard:read', label: 'Dashboard read', needsTable: false, needsDashboard: true },
5455
{ value: 'dashboard:create', label: 'Dashboard create', needsTable: false, needsDashboard: true },
5556
{ value: 'dashboard:edit', label: 'Dashboard edit', needsTable: false, needsDashboard: true },
@@ -132,8 +133,8 @@ export function policyItemsToCedarPolicy(items: CedarPolicyItem[], connectionId:
132133
}
133134

134135
const actionRef =
135-
item.action === 'table:*'
136-
? `action like RocketAdmin::Action::"table:*"`
136+
item.action === 'table:*' || item.action === 'dashboard:*'
137+
? `action like RocketAdmin::Action::"${item.action}"`
137138
: `action == RocketAdmin::Action::"${item.action}"`;
138139
let resource: string;
139140

@@ -144,8 +145,11 @@ export function policyItemsToCedarPolicy(items: CedarPolicyItem[], connectionId:
144145
resource = `resource == RocketAdmin::Table::"${connectionId}/${item.tableName}"`;
145146
}
146147
} else if (item.action.startsWith('dashboard:')) {
147-
const dashId = item.dashboardId || '__new__';
148-
resource = `resource == RocketAdmin::Dashboard::"${connectionId}/${dashId}"`;
148+
if (item.dashboardId === '*') {
149+
resource = `resource like RocketAdmin::Dashboard::"${connectionId}/*"`;
150+
} else {
151+
resource = `resource == RocketAdmin::Dashboard::"${connectionId}/${item.dashboardId}"`;
152+
}
149153
} else if (item.action.startsWith('group:')) {
150154
resource = `resource == RocketAdmin::Group::"${groupId}"`;
151155
} else {

0 commit comments

Comments
 (0)