diff --git a/.changeset/sweet-ducks-wait.md b/.changeset/sweet-ducks-wait.md new file mode 100644 index 0000000000..4792fafe84 --- /dev/null +++ b/.changeset/sweet-ducks-wait.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-test-utils': minor +--- + +Added mock implementations for `ActionsService` and `ActionsRegistryService` diff --git a/.changeset/wet-bars-report.md b/.changeset/wet-bars-report.md index 2890fa846d..d556f6cc61 100644 --- a/.changeset/wet-bars-report.md +++ b/.changeset/wet-bars-report.md @@ -1,6 +1,5 @@ --- '@backstage/backend-plugin-api': minor -'@backstage/backend-defaults': patch --- Added `coreServices.actionsRegistry` and `coreServices.actions` to allow registration of distributed actions from plugins, and the ability to invoke these actions diff --git a/.changeset/wet-bars-reporting.md b/.changeset/wet-bars-reporting.md new file mode 100644 index 0000000000..7dc66cb280 --- /dev/null +++ b/.changeset/wet-bars-reporting.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-defaults': patch +--- + +Added some default implementations for the `ActionsService` and `ActionsRegistryService` that allow registration of actions for a particular plugin. diff --git a/packages/backend-defaults/src/entrypoints/actionsRegistry/DefaultActionsRegistryService.ts b/packages/backend-defaults/src/entrypoints/actionsRegistry/DefaultActionsRegistryService.ts index a1777cb9b6..17523a2ee5 100644 --- a/packages/backend-defaults/src/entrypoints/actionsRegistry/DefaultActionsRegistryService.ts +++ b/packages/backend-defaults/src/entrypoints/actionsRegistry/DefaultActionsRegistryService.ts @@ -82,6 +82,19 @@ export class DefaultActionsRegistryService implements ActionsRegistryService { router.post( '/.backstage/actions/v1/actions/:actionId/invoke', async (req, res) => { + const credentials = await this.httpAuth.credentials(req); + if (this.auth.isPrincipal(credentials, 'user')) { + if (!credentials.principal.actor) { + throw new NotAllowedError( + `Actions must be invoked by a service, not a user`, + ); + } + } else if (this.auth.isPrincipal(credentials, 'none')) { + throw new NotAllowedError( + `Actions must be invoked by a service, not an anonymous request`, + ); + } + const action = this.actions.get(req.params.actionId); if (!action) { @@ -99,19 +112,6 @@ export class DefaultActionsRegistryService implements ActionsRegistryService { ); } - const credentials = await this.httpAuth.credentials(req); - if (this.auth.isPrincipal(credentials, 'user')) { - if (!credentials.principal.actor) { - throw new NotAllowedError( - `Actions must be invoked by a service, not a user`, - ); - } - } else if (this.auth.isPrincipal(credentials, 'none')) { - throw new NotAllowedError( - `Actions must be invoked by a service, not an anonymous request`, - ); - } - try { const result = await action.action({ input: input.data,