Merge pull request #28677 from backstage/rugvip/permission-refs
permissions: add resources refs and rule accessor
This commit is contained in:
@@ -24,14 +24,14 @@ yarn --cwd packages/backend add zod @backstage/catalog-model
|
||||
...
|
||||
|
||||
import type { Entity } from '@backstage/catalog-model';
|
||||
import { createCatalogPermissionRule } from '@backstage/plugin-catalog-backend/alpha';
|
||||
import { createConditionFactory } from '@backstage/plugin-permission-node';
|
||||
import { catalogEntityPermissionResourceRef } from '@backstage/plugin-catalog-backend/alpha';
|
||||
import { createConditionFactory, createPermissionRule } from '@backstage/plugin-permission-node';
|
||||
import { z } from 'zod';
|
||||
|
||||
export const isInSystemRule = createCatalogPermissionRule({
|
||||
export const isInSystemRule = createPermissionRule({
|
||||
name: 'IS_IN_SYSTEM',
|
||||
description: 'Checks if an entity is part of the system provided',
|
||||
resourceType: 'catalog-entity',
|
||||
resourceRef: catalogEntityPermissionResourceRef,
|
||||
paramsSchema: z.object({
|
||||
systemRef: z
|
||||
.string()
|
||||
@@ -64,22 +64,22 @@ Still in the `packages/backend/src/extensions/permissionsPolicyExtension.ts` fil
|
||||
```ts title="packages/backend/src/extensions/permissionsPolicyExtension.ts"
|
||||
...
|
||||
/* highlight-remove-next-line */
|
||||
import { createCatalogPermissionRule } from '@backstage/plugin-catalog-backend/alpha';
|
||||
import { catalogEntityPermissionResourceRef } from '@backstage/plugin-catalog-backend/alpha';
|
||||
/* highlight-add-next-line */
|
||||
import { catalogConditions, createCatalogConditionalDecision, createCatalogPermissionRule } from '@backstage/plugin-catalog-backend/alpha';
|
||||
import { catalogEntityPermissionResourceRef, createCatalogConditionalDecision, catalogConditions } from '@backstage/plugin-catalog-backend/alpha';
|
||||
/* highlight-remove-next-line */
|
||||
import { createConditionFactory } from '@backstage/plugin-permission-node';
|
||||
import { createConditionFactory, createPermissionRule } from '@backstage/plugin-permission-node';
|
||||
/* highlight-add-next-line */
|
||||
import { PermissionPolicy, PolicyQuery, PolicyQueryUser, createConditionFactory } from '@backstage/plugin-permission-node';
|
||||
import { createConditionFactory, createPermissionRule, PermissionPolicy, PolicyQuery, PolicyQueryUser } from '@backstage/plugin-permission-node';
|
||||
/* highlight-add-start */
|
||||
import { AuthorizeResult, PolicyDecision, isResourcePermission } from '@backstage/plugin-permission-common';
|
||||
/* highlight-add-end */
|
||||
...
|
||||
|
||||
export const isInSystemRule = createCatalogPermissionRule({
|
||||
export const isInSystemRule = createPermissionRule({
|
||||
name: 'IS_IN_SYSTEM',
|
||||
description: 'Checks if an entity is part of the system provided',
|
||||
resourceType: 'catalog-entity',
|
||||
resourceRef: catalogEntityPermissionResourceRef,
|
||||
paramsSchema: z.object({
|
||||
systemRef: z
|
||||
.string()
|
||||
|
||||
@@ -130,16 +130,18 @@ import { TODO_LIST_RESOURCE_TYPE } from '@internal/plugin-todo-list-common';
|
||||
import { z } from 'zod';
|
||||
import { Todo, TodoFilter } from './todos';
|
||||
|
||||
export const createTodoListPermissionRule = makeCreatePermissionRule<
|
||||
export const todoListPermissionResourceRef = createPermissionResourceRef<
|
||||
Todo,
|
||||
TodoFilter,
|
||||
typeof TODO_LIST_RESOURCE_TYPE
|
||||
>();
|
||||
TodoFilter
|
||||
>().with({
|
||||
pluginId: 'todolist',
|
||||
type: TODO_LIST_RESOURCE_TYPE,
|
||||
});
|
||||
|
||||
export const isOwner = createTodoListPermissionRule({
|
||||
export const isOwner = createPermissionRule({
|
||||
name: 'IS_OWNER',
|
||||
description: 'Should allow only if the todo belongs to the user',
|
||||
resourceType: TODO_LIST_RESOURCE_TYPE,
|
||||
resourceType: todoListPermissionResourceRef,
|
||||
paramsSchema: z.object({
|
||||
userId: z.string().describe('User ID to match on the resource'),
|
||||
}),
|
||||
@@ -157,11 +159,11 @@ export const isOwner = createTodoListPermissionRule({
|
||||
export const rules = { isOwner };
|
||||
```
|
||||
|
||||
`makeCreatePermissionRule` is a helper used to ensure that rules created for this plugin use consistent types for the resource and query.
|
||||
The `todoListPermissionResourceRef` is a utility that encapsulates the types and constants related to the resource type. It ensures that the resource and query types are consistent across all rules created for this resource.
|
||||
|
||||
:::note Note
|
||||
|
||||
To support custom rules defined by Backstage integrators, you must export `createTodoListPermissionRule` from the backend package and provide some way for custom rules to be passed in before the backend starts, likely via `extension point`.
|
||||
To support custom rules defined by Backstage integrators, you must export `todoListPermissionResourceRef` from the backend package, or a `*-node` package if you want to enable the creation of third-party modules.
|
||||
|
||||
:::
|
||||
|
||||
@@ -186,14 +188,12 @@ import {
|
||||
} from '@backstage/backend-plugin-api';
|
||||
import { createRouter } from './service/router';
|
||||
import {
|
||||
/* highlight-add-next-line */
|
||||
TODO_LIST_RESOURCE_TYPE,
|
||||
todoListCreatePermission,
|
||||
todoListUpdatePermission,
|
||||
} from '@internal/plugin-todo-list-common';
|
||||
/* highlight-add-start */
|
||||
import { getTodo } from './todos';
|
||||
import { rules } from './rules';
|
||||
import { todoListPermissionResourceRef, rules } from './rules';
|
||||
/* highlight-add-end */
|
||||
|
||||
// ...
|
||||
@@ -206,7 +206,7 @@ permissionsRegistry.addPermissions([
|
||||
/* highlight-remove-end */
|
||||
/* highlight-add-start */
|
||||
permissionsRegistry.addResourceType({
|
||||
resourceType: TODO_LIST_RESOURCE_TYPE,
|
||||
resourceRef: todoListPermissionResourceRef,
|
||||
permissions: [todoListCreatePermission, todoListUpdatePermission],
|
||||
rules: Object.values(rules),
|
||||
getResources: async resourceRefs => {
|
||||
@@ -225,11 +225,10 @@ Create a new `plugins/todo-list-backend/src/conditionExports.ts` file and add th
|
||||
```typescript title="plugins/todo-list-backend/src/conditionExports.ts"
|
||||
import { TODO_LIST_RESOURCE_TYPE } from '@internal/plugin-todo-list-common';
|
||||
import { createConditionExports } from '@backstage/plugin-permission-node';
|
||||
import { rules } from './service/rules';
|
||||
import { todoListPermissionResourceRef, rules } from './service/rules';
|
||||
|
||||
const { conditions, createConditionalDecision } = createConditionExports({
|
||||
pluginId: 'todolist',
|
||||
resourceType: TODO_LIST_RESOURCE_TYPE,
|
||||
resourceRef: todoListPermissionResourceRef,
|
||||
rules,
|
||||
});
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@ import {
|
||||
// ...
|
||||
|
||||
permissionsRegistry.addResourceType({
|
||||
resourceType: TODO_LIST_RESOURCE_TYPE,
|
||||
resourceRef: todoListPermissionResourceRef,
|
||||
/* highlight-remove-next-line */
|
||||
permissions: [todoListCreatePermission, todoListUpdatePermission],
|
||||
/* highlight-add-next-line */
|
||||
@@ -129,17 +129,22 @@ import {
|
||||
import { add, getAll, getTodo, update } from './todos';
|
||||
/* highlight-add-next-line */
|
||||
import { add, getAll, getTodo, TodoFilter, update } from './todos';
|
||||
/* highlight-add-next-line */
|
||||
import { todoListPermissionResourceRef } from './rules';
|
||||
import {
|
||||
todoListCreatePermission,
|
||||
todoListUpdatePermission,
|
||||
/* highlight-add-next-line */
|
||||
todoListReadPermission,
|
||||
} from './permissions';
|
||||
} from '@internal/plugin-todo-list-common';
|
||||
|
||||
// ...
|
||||
|
||||
/* highlight-add-next-line */
|
||||
const transformConditions: ConditionTransformer<TodoFilter> = createConditionTransformer(Object.values(rules));
|
||||
/* highlight-add-start */
|
||||
const transformConditions = createConditionTransformer(
|
||||
permissionsRegistry.getPermissionRuleset(todoListPermissionResourceRef)
|
||||
);
|
||||
/* highlight-add-end */
|
||||
|
||||
/* highlight-remove-next-line */
|
||||
router.get('/todos', async (_req, res) => {
|
||||
|
||||
Reference in New Issue
Block a user