refactor: rename permission to visibilityPermission
Signed-off-by: benjdlambert <ben@blam.sh>
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
'@backstage/backend-plugin-api': minor
|
||||
---
|
||||
|
||||
Added optional `permission` field to `ActionsRegistryActionOptions`, allowing actions to declare a `BasicPermission` that controls visibility and access.
|
||||
Added optional `visibilityPermission` field to `ActionsRegistryActionOptions`, allowing actions to declare a `BasicPermission` that controls visibility and access.
|
||||
|
||||
```typescript
|
||||
import { createPermission } from '@backstage/plugin-permission-common';
|
||||
@@ -16,7 +16,7 @@ actionsRegistry.register({
|
||||
name: 'my-action',
|
||||
title: 'My Action',
|
||||
description: 'An action that requires permission',
|
||||
permission: myPermission,
|
||||
visibilityPermission: myPermission,
|
||||
schema: {
|
||||
input: z => z.object({ name: z.string() }),
|
||||
output: z => z.object({ ok: z.boolean() }),
|
||||
@@ -27,4 +27,4 @@ actionsRegistry.register({
|
||||
});
|
||||
```
|
||||
|
||||
Actions without a `permission` field continue to work as before.
|
||||
Actions without a `visibilityPermission` field continue to work as before.
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
'@backstage/backend-defaults': patch
|
||||
---
|
||||
|
||||
Added permissions integration to the actions registry. Actions registered with a `permission` field are now checked against the permissions framework when listing and invoking. Denied actions are filtered from list results, and invoking a denied action returns a `404 Not Found` as if the action does not exist. Permissions are automatically registered with the `PermissionsRegistryService` so they appear in the permission policy system.
|
||||
Added permissions integration to the actions registry. Actions registered with a `visibilityPermission` field are now checked against the permissions framework when listing and invoking. Denied actions are filtered from list results, and invoking a denied action returns a `404 Not Found` as if the action does not exist. Permissions are automatically registered with the `PermissionsRegistryService` so they appear in the permission policy system.
|
||||
|
||||
@@ -25,7 +25,7 @@ Each action registered with the service must conform to the `ActionsRegistryActi
|
||||
|
||||
### Optional Properties
|
||||
|
||||
- **`permission`:** A `BasicPermission` that controls visibility and access to the action through the permissions framework. See [Permissions](#permissions) below.
|
||||
- **`visibilityPermission`:** A `BasicPermission` that controls visibility and access to the action through the permissions framework. See [Permissions](#permissions) below.
|
||||
- **`attributes`:** Object containing behavioral flags:
|
||||
- **`destructive`:** Boolean indicating if the action modifies or deletes data
|
||||
- **`idempotent`:** Boolean indicating if running the action multiple times produces the same result
|
||||
@@ -160,7 +160,7 @@ export const myPlugin = createBackendPlugin({
|
||||
|
||||
## Permissions
|
||||
|
||||
Actions can optionally declare a `permission` to control visibility and access through the Backstage permissions framework. When a permission is set, the action is only visible in listings and accessible by users who are authorized.
|
||||
Actions can optionally declare a `visibilityPermission` to control visibility and access through the Backstage permissions framework. When a permission is set, the action is only visible in listings and accessible by users who are authorized.
|
||||
|
||||
When accessed via the Actions Service or the `/.backstage/actions/v1/...` HTTP endpoints, actions that are denied by the permission policy are filtered from list results and return a `404 Not Found` on invocation, as if they don't exist.
|
||||
|
||||
@@ -181,7 +181,7 @@ actionsRegistry.register({
|
||||
name: 'delete-entity',
|
||||
title: 'Delete Entity',
|
||||
description: 'Removes an entity from the catalog',
|
||||
permission: myDeletePermission,
|
||||
visibilityPermission: myDeletePermission,
|
||||
schema: {
|
||||
input: z => z.object({ entityRef: z.string() }),
|
||||
output: z => z.object({ deleted: z.boolean() }),
|
||||
@@ -193,7 +193,7 @@ actionsRegistry.register({
|
||||
});
|
||||
```
|
||||
|
||||
Actions without a `permission` field remain visible and accessible by all callers, preserving backwards compatibility.
|
||||
Actions without a `visibilityPermission` field remain visible and accessible by all callers, preserving backwards compatibility.
|
||||
|
||||
## Best Practices
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ backend:
|
||||
|
||||
### Permissions
|
||||
|
||||
Actions registered with a `permission` field are automatically checked against the permissions framework. When listing actions, any actions denied by the active permission policy are filtered out of the results. When invoking a denied action, a `404 Not Found` error is returned. See the [Actions Registry Permissions](./actions-registry.md#permissions) documentation for how to configure permissions on actions.
|
||||
Actions registered with a `visibilityPermission` field are automatically checked against the permissions framework. When listing actions, any actions denied by the active permission policy are filtered out of the results. When invoking a denied action, a `404 Not Found` error is returned. See the [Actions Registry Permissions](./actions-registry.md#permissions) documentation for how to configure permissions on actions.
|
||||
|
||||
## Using the Service
|
||||
|
||||
|
||||
+6
-6
@@ -148,9 +148,9 @@ export class DefaultActionsRegistryService implements ActionsRegistryService {
|
||||
throw new NotFoundError(`Action "${req.params.actionId}" not found`);
|
||||
}
|
||||
|
||||
if (action.permission) {
|
||||
if (action.visibilityPermission) {
|
||||
const [decision] = await this.permissions.authorize(
|
||||
[{ permission: action.permission }],
|
||||
[{ permission: action.visibilityPermission }],
|
||||
{ credentials },
|
||||
);
|
||||
if (decision.result === AuthorizeResult.DENY) {
|
||||
@@ -204,8 +204,8 @@ export class DefaultActionsRegistryService implements ActionsRegistryService {
|
||||
throw new Error(`Action with id "${id}" is already registered`);
|
||||
}
|
||||
|
||||
if (options.permission) {
|
||||
this.permissionsRegistry.addPermissions([options.permission]);
|
||||
if (options.visibilityPermission) {
|
||||
this.permissionsRegistry.addPermissions([options.visibilityPermission]);
|
||||
}
|
||||
|
||||
this.actions.set(id, options);
|
||||
@@ -216,7 +216,7 @@ export class DefaultActionsRegistryService implements ActionsRegistryService {
|
||||
credentials: BackstageCredentials,
|
||||
): Promise<ActionEntry[]> {
|
||||
const permissionedEntries = entries.filter(
|
||||
([_, action]) => action.permission,
|
||||
([_, action]) => action.visibilityPermission,
|
||||
);
|
||||
|
||||
if (permissionedEntries.length === 0) {
|
||||
@@ -225,7 +225,7 @@ export class DefaultActionsRegistryService implements ActionsRegistryService {
|
||||
|
||||
const decisions = await this.permissions.authorize(
|
||||
permissionedEntries.map(([_, action]) => ({
|
||||
permission: action.permission!,
|
||||
permission: action.visibilityPermission!,
|
||||
})),
|
||||
{ credentials },
|
||||
);
|
||||
|
||||
+6
-6
@@ -592,7 +592,7 @@ describe('actionsRegistryServiceFactory', () => {
|
||||
name: 'protected-action',
|
||||
title: 'Protected Action',
|
||||
description: 'Permission required',
|
||||
permission: testPermission,
|
||||
visibilityPermission: testPermission,
|
||||
schema: {
|
||||
input: z => z.object({}),
|
||||
output: z => z.object({}),
|
||||
@@ -640,7 +640,7 @@ describe('actionsRegistryServiceFactory', () => {
|
||||
name: 'protected-action',
|
||||
title: 'Protected Action',
|
||||
description: 'Permission required',
|
||||
permission: testPermission,
|
||||
visibilityPermission: testPermission,
|
||||
schema: {
|
||||
input: z => z.object({}),
|
||||
output: z => z.object({}),
|
||||
@@ -688,7 +688,7 @@ describe('actionsRegistryServiceFactory', () => {
|
||||
name: 'protected-action',
|
||||
title: 'Protected Action',
|
||||
description: 'Permission required',
|
||||
permission: testPermission,
|
||||
visibilityPermission: testPermission,
|
||||
schema: {
|
||||
input: z => z.object({}),
|
||||
output: z => z.object({}),
|
||||
@@ -741,7 +741,7 @@ describe('actionsRegistryServiceFactory', () => {
|
||||
name: 'protected-action',
|
||||
title: 'Protected Action',
|
||||
description: 'Permission required',
|
||||
permission: testPermission,
|
||||
visibilityPermission: testPermission,
|
||||
schema: {
|
||||
input: z => z.object({}),
|
||||
output: z => z.object({ ok: z.boolean() }),
|
||||
@@ -793,7 +793,7 @@ describe('actionsRegistryServiceFactory', () => {
|
||||
name: 'protected-action',
|
||||
title: 'Protected Action',
|
||||
description: 'Permission required',
|
||||
permission: testPermission,
|
||||
visibilityPermission: testPermission,
|
||||
schema: {
|
||||
input: z => z.object({}),
|
||||
output: z => z.object({}),
|
||||
@@ -840,7 +840,7 @@ describe('actionsRegistryServiceFactory', () => {
|
||||
name: 'protected-action',
|
||||
title: 'Protected Action',
|
||||
description: 'Permission required',
|
||||
permission: testPermission,
|
||||
visibilityPermission: testPermission,
|
||||
schema: {
|
||||
input: z => z.object({}),
|
||||
output: z => z.object({}),
|
||||
|
||||
@@ -32,7 +32,7 @@ export type ActionsRegistryActionOptions<
|
||||
input: (zod: typeof z) => TInputSchema;
|
||||
output: (zod: typeof z) => TOutputSchema;
|
||||
};
|
||||
permission?: BasicPermission;
|
||||
visibilityPermission?: BasicPermission;
|
||||
attributes?: {
|
||||
destructive?: boolean;
|
||||
idempotent?: boolean;
|
||||
|
||||
@@ -43,7 +43,7 @@ export type ActionsRegistryActionOptions<
|
||||
input: (zod: typeof z) => TInputSchema;
|
||||
output: (zod: typeof z) => TOutputSchema;
|
||||
};
|
||||
permission?: BasicPermission;
|
||||
visibilityPermission?: BasicPermission;
|
||||
attributes?: {
|
||||
destructive?: boolean;
|
||||
idempotent?: boolean;
|
||||
|
||||
@@ -41,7 +41,7 @@ export type ActionsRegistryActionOptions<
|
||||
input: (zod: typeof z) => TInputSchema;
|
||||
output: (zod: typeof z) => TOutputSchema;
|
||||
};
|
||||
permission?: BasicPermission;
|
||||
visibilityPermission?: BasicPermission;
|
||||
attributes?: {
|
||||
destructive?: boolean;
|
||||
idempotent?: boolean;
|
||||
|
||||
Reference in New Issue
Block a user