Merge pull request #17388 from backstage/permission/plugin-author-docs-update

Update plugin author permission docs to match correct usage of createPermissionIntegrationRouter
This commit is contained in:
Ben Lambert
2023-04-18 11:35:00 +02:00
committed by GitHub
3 changed files with 72 additions and 21 deletions
@@ -37,7 +37,7 @@ export const todoListPermissions = [todoListCreatePermission];
For this tutorial, we've automatically exported all permissions from this file (see `plugins/todo-list-common/src/index.ts`).
> Note: We use a separate `todo-list-common` package since all permissions authorized by your plugin should be exported from a ["common-library" package](https://backstage.io/docs/local-dev/cli-build-system#package-roles). This allows Backstage integrators to reference them in frontend components and permission policies.
> Note: We use a separate `todo-list-common` package since all permissions authorized by your plugin should be exported from a ["common-library" package](https://backstage.io/docs/local-dev/cli-build-system#package-roles). This allows Backstage integrators to reference them in frontend components as well as permission policies.
## Authorizing using the new permission
@@ -45,7 +45,7 @@ Install the following module:
```
$ yarn workspace @internal/plugin-todo-list-backend \
add @backstage/plugin-permission-common @internal/plugin-todo-list-common
add @backstage/plugin-permission-common @backstage/plugin-permission-node @internal/plugin-todo-list-common
```
Edit `plugins/todo-list-backend/src/service/router.ts`:
@@ -59,6 +59,7 @@ import { IdentityApi } from '@backstage/plugin-auth-node';
import { InputError, NotAllowedError } from '@backstage/errors';
import { getBearerTokenFromAuthorizationHeader, IdentityApi } from '@backstage/plugin-auth-node';
import { PermissionEvaluator, AuthorizeResult } from '@backstage/plugin-permission-common';
import { createPermissionIntegrationRouter } from '@backstage/plugin-permission-node';
import { todoListCreatePermission } from '@internal/plugin-todo-list-common';
/* highlight-add-end */
@@ -77,6 +78,27 @@ export async function createRouter(
/* highlight-add-next-line */
const { logger, identity, permissions } = options;
/* highlight-add-start */
const permissionIntegrationRouter = createPermissionIntegrationRouter({
permissions: [todoListCreatePermission],
});
/* highlight-add-end */
const router = Router();
router.use(express.json());
router.get('/health', (_, response) => {
logger.info('PONG!');
response.json({ status: 'ok' });
});
/* highlight-add-next-line */
router.use(permissionIntegrationRouter);
router.get('/todos', async (_req, res) => {
res.json(getAll());
});
router.post('/todos', async (req, res) => {
let author: string | undefined = undefined;
@@ -103,7 +125,9 @@ export async function createRouter(
const todo = add({ title: req.body.title, author });
res.json(todo);
});
});
// ...
```
Pass the `permissions` object to the plugin in `packages/backend/src/plugins/todolist.ts`:
@@ -247,7 +271,7 @@ describe('createRouter', () => {
});
```
Then we want to update the `plugins/todo-list-backend/src/service/standaloneServer.ts`, first we need to add the `@backstage/plugin-permission-node` package to `plugins/todo-list-backend/package.json` and then we can make the following edits:
Then we want to update the `plugins/todo-list-backend/src/service/standaloneServer.ts`:
```ts title="plugins/todo-list-backend/src/service/standaloneServer.ts"
import {
@@ -47,11 +47,23 @@ To start, let's edit `plugins/todo-list-backend/src/service/router.ts` in the sa
```ts title="plugins/todo-list-backend/src/service/router.ts"
/* highlight-remove-next-line */
import { todoListCreatePermission } from '@internal/plugin-todo-list-common';
/* highlight-add-next-line */
/* highlight-add-start */
import {
todoListCreatePermission,
todoListUpdatePermission,
} from '@internal/plugin-todo-list-common';
/* highlight-add-end */
// ...
const permissionIntegrationRouter = createPermissionIntegrationRouter({
/* highlight-remove-next-line */
permissions: [todoListCreatePermission],
/* highlight-add-next-line */
permissions: [todoListCreatePermission, todoListUpdatePermission],
});
// ...
router.put('/todos', async (req, res) => {
/* highlight-add-start */
@@ -91,7 +103,7 @@ This enables decisions based on characteristics of the resource, but it's import
Install the missing module:
```bash
$ yarn workspace @internal/plugin-todo-list-backend add @backstage/plugin-permission-node zod
$ yarn workspace @internal/plugin-todo-list-backend add zod
```
Create a new `plugins/todo-list-backend/src/service/rules.ts` file and append the following code:
@@ -146,12 +158,17 @@ Now, let's create the new endpoint by editing `plugins/todo-list-backend/src/ser
- `rules`: an array of all the permission rules you want to support in conditional decisions.
```ts title="plugins/todo-list-backend/src/service/router.ts"
// ...
import {
/* highlight-add-next-line */
TODO_LIST_RESOURCE_TYPE,
todoListCreatePermission,
todoListUpdatePermission,
} from '@internal/plugin-todo-list-common';
/* highlight-remove-next-line */
import { add, getAll, update } from './todos';
/* highlight-add-start */
import { add, getAll, getTodo, update } from './todos';
import { createPermissionIntegrationRouter } from '@backstage/plugin-permission-node';
import { TODO_LIST_RESOURCE_TYPE, todoListPermissions } from '@internal/plugin-todo-list-common';
import { rules } from './rules';
/* highlight-add-end */
@@ -160,27 +177,21 @@ export async function createRouter(
): Promise<express.Router> {
const { logger, identity, permissions } = options;
/* highlight-add-start */
const permissionIntegrationRouter = createPermissionIntegrationRouter({
permissions: [todoListCreatePermission, todoListUpdatePermission],
/* highlight-add-start */
getResources: async resourceRefs => {
return resourceRefs.map(getTodo);
},
resourceType: TODO_LIST_RESOURCE_TYPE,
permissions: todoListPermissions,
rules: Object.values(rules),
/* highlight-add-end */
});
/* highlight-add-end */
const router = Router();
router.use(express.json());
/* highlight-add-next-line */
router.use(permissionIntegrationRouter);
router.post('/todos', async (req, res) => {
// ..
}
// ..
// ...
}
```
@@ -98,13 +98,29 @@ import { add, getAll, getTodo, update } from './todos';
/* highlight-add-next-line */
import { add, getAll, getTodo, TodoFilter, update } from './todos';
import {
todosListCreate,
todosListUpdate,
TODO_LIST_RESOURCE_TYPE,
todoListCreatePermission,
todoListUpdatePermission,
/* highlight-add-next-line */
todoListReadPermission,
TODO_LIST_RESOURCE_TYPE,
} from './permissions';
// ...
const permissionIntegrationRouter = createPermissionIntegrationRouter({
/* highlight-remove-next-line */
permissions: [todoListCreatePermission, todoListUpdatePermission],
/* highlight-add-next-line */
permissions: [todoListCreatePermission, todoListUpdatePermission, todoListReadPermission],
getResources: async resourceRefs => {
return resourceRefs.map(getTodo);
},
resourceType: TODO_LIST_RESOURCE_TYPE,
rules: Object.values(rules),
});
// ...
/* highlight-add-next-line */
const transformConditions: ConditionTransformer<TodoFilter> = createConditionTransformer(Object.values(rules));