From 317085836d2b3b58a62e63af3b4657b1095d9b94 Mon Sep 17 00:00:00 2001 From: Kurt King Date: Fri, 2 Feb 2024 11:36:42 -0700 Subject: [PATCH 01/19] feat: delete unprocessed entity Signed-off-by: Kurt King --- .../src/UnprocessedEntitiesModule.ts | 12 +- .../src/api/index.ts | 10 ++ .../src/components/FailedEntities.tsx | 108 ++++++++++++------ 3 files changed, 92 insertions(+), 38 deletions(-) diff --git a/plugins/catalog-backend-module-unprocessed/src/UnprocessedEntitiesModule.ts b/plugins/catalog-backend-module-unprocessed/src/UnprocessedEntitiesModule.ts index a01f717e12..72713178e8 100644 --- a/plugins/catalog-backend-module-unprocessed/src/UnprocessedEntitiesModule.ts +++ b/plugins/catalog-backend-module-unprocessed/src/UnprocessedEntitiesModule.ts @@ -120,6 +120,16 @@ export class UnprocessedEntitiesModule { owner: req.query.owner as string, }), ); - }); + }) + .delete( + '/entities/unprocessed/delete/:entity_id', + async (request, response) => { + await this.database('refresh_state') + .where({ entity_id: request.params.entity_id }) + .delete(); + + response.status(204).send(); + }, + ); } } diff --git a/plugins/catalog-unprocessed-entities/src/api/index.ts b/plugins/catalog-unprocessed-entities/src/api/index.ts index 92dde93a93..030a4d0293 100644 --- a/plugins/catalog-unprocessed-entities/src/api/index.ts +++ b/plugins/catalog-unprocessed-entities/src/api/index.ts @@ -54,6 +54,10 @@ export interface CatalogUnprocessedEntitiesApi { * Returns a list of entities with state 'failed' */ failed(): Promise; + /** + * Deletes an entity from the refresh_state table + */ + delete(entity_id: string): Promise; } /** @@ -83,4 +87,10 @@ export class CatalogUnprocessedEntitiesClient async failed(): Promise { return await this.fetch('entities/unprocessed/failed'); } + + async delete(entity_id: string): Promise { + await this.fetch(`entities/unprocessed/delete/${entity_id}`, { + method: 'DELETE', + }); + } } diff --git a/plugins/catalog-unprocessed-entities/src/components/FailedEntities.tsx b/plugins/catalog-unprocessed-entities/src/components/FailedEntities.tsx index a1044c6679..4c01b888b2 100644 --- a/plugins/catalog-unprocessed-entities/src/components/FailedEntities.tsx +++ b/plugins/catalog-unprocessed-entities/src/components/FailedEntities.tsx @@ -22,15 +22,18 @@ import { Table, TableColumn, } from '@backstage/core-components'; -import { useApi } from '@backstage/core-plugin-api'; + import Box from '@material-ui/core/Box'; import Typography from '@material-ui/core/Typography'; +import IconButton from '@material-ui/core/IconButton'; import { Theme, makeStyles } from '@material-ui/core/styles'; +import { alertApiRef, useApi } from '@backstage/core-plugin-api'; import { UnprocessedEntity } from '../types'; import { EntityDialog } from './EntityDialog'; import { catalogUnprocessedEntitiesApiRef } from '../api'; import useAsync from 'react-use/lib/useAsync'; +import DeleteIcon from '@material-ui/icons/Delete'; const useStyles = makeStyles((theme: Theme) => ({ errorBox: { @@ -94,6 +97,8 @@ export const FailedEntities = () => { value: data, } = useAsync(async () => await unprocessedApi.failed()); const [, setSelectedSearchTerm] = useState(''); + const unprocessedEntityApi = useApi(catalogUnprocessedEntitiesApiRef); + const alertApi = useApi(alertApiRef); if (loading) { return ; @@ -102,6 +107,21 @@ export const FailedEntities = () => { return ; } + const handleDelete = async ({ id }: { id: string }) => { + try { + await unprocessedEntityApi.delete(id); + alertApi.post({ + message: `Entity has been deleted`, + severity: 'success', + }); + } catch (e) { + alertApi.post({ + message: `Ran into an issue when deleting. Please try again later.`, + severity: 'error', + }); + } + }; + const columns: TableColumn[] = [ { title: entityRef, @@ -136,43 +156,57 @@ export const FailedEntities = () => { ), }, + { + title: Actions, + render: (rowData: UnprocessedEntity | {}) => { + return ( + + await handleDelete({ + id: (rowData as UnprocessedEntity).entity_id, + }) + } + > + + + ); + }, + }, ]; + return ( - <> - - No failed entities found - - } - onSearchChange={(searchTerm: string) => - setSelectedSearchTerm(searchTerm) - } - detailPanel={({ rowData }) => { - const errors = (rowData as UnprocessedEntity).errors; - return ( - <> - {errors?.map(e => { - return ( - - - {e.name} - - - - - ); - })} - - ); - }} - /> - +
+ No failed entities found + + } + onSearchChange={(searchTerm: string) => setSelectedSearchTerm(searchTerm)} + detailPanel={({ rowData }) => { + const errors = (rowData as UnprocessedEntity).errors; + return ( + <> + {errors?.map((e, idx) => { + return ( + + + {e.name} + + + + + ); + })} + + ); + }} + /> ); }; From 93da9004dcecc9816f3f1189fc055b20402bd2e1 Mon Sep 17 00:00:00 2001 From: Kurt King Date: Fri, 2 Feb 2024 12:23:14 -0700 Subject: [PATCH 02/19] docs: new api report Signed-off-by: Kurt King --- plugins/catalog-unprocessed-entities/api-report.md | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/catalog-unprocessed-entities/api-report.md b/plugins/catalog-unprocessed-entities/api-report.md index cc4d6bba88..0fea84256b 100644 --- a/plugins/catalog-unprocessed-entities/api-report.md +++ b/plugins/catalog-unprocessed-entities/api-report.md @@ -14,6 +14,7 @@ import { RouteRef } from '@backstage/core-plugin-api'; // @public export interface CatalogUnprocessedEntitiesApi { + delete(entity_id: string): Promise; failed(): Promise; pending(): Promise; } From 48329dc965057b66e14813a70ddd7e7e8ef632ce Mon Sep 17 00:00:00 2001 From: Kurt King Date: Fri, 2 Feb 2024 12:32:16 -0700 Subject: [PATCH 03/19] include entityRef in alert output Signed-off-by: Kurt King --- .../src/components/FailedEntities.tsx | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/plugins/catalog-unprocessed-entities/src/components/FailedEntities.tsx b/plugins/catalog-unprocessed-entities/src/components/FailedEntities.tsx index 4c01b888b2..4618953af2 100644 --- a/plugins/catalog-unprocessed-entities/src/components/FailedEntities.tsx +++ b/plugins/catalog-unprocessed-entities/src/components/FailedEntities.tsx @@ -107,16 +107,22 @@ export const FailedEntities = () => { return ; } - const handleDelete = async ({ id }: { id: string }) => { + const handleDelete = async ({ + id, + entityRef, + }: { + id: string; + entityRef: string; + }) => { try { await unprocessedEntityApi.delete(id); alertApi.post({ - message: `Entity has been deleted`, + message: `Entity ${entityRef} has been deleted`, severity: 'success', }); } catch (e) { alertApi.post({ - message: `Ran into an issue when deleting. Please try again later.`, + message: `Ran into an issue when deleting ${entityRef}. Please try again later.`, severity: 'error', }); } @@ -165,6 +171,7 @@ export const FailedEntities = () => { onClick={async () => await handleDelete({ id: (rowData as UnprocessedEntity).entity_id, + entityRef: (rowData as UnprocessedEntity).entity_ref, }) } > From fc4a5b0a7f8718d30205e211e28ee4e3ad93e8fd Mon Sep 17 00:00:00 2001 From: Kurt King Date: Fri, 2 Feb 2024 13:09:11 -0700 Subject: [PATCH 04/19] fix: returning resp.json() because 204 status responses do not have a json payload Signed-off-by: Kurt King --- plugins/catalog-unprocessed-entities/src/api/index.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/catalog-unprocessed-entities/src/api/index.ts b/plugins/catalog-unprocessed-entities/src/api/index.ts index 030a4d0293..ae5feedf84 100644 --- a/plugins/catalog-unprocessed-entities/src/api/index.ts +++ b/plugins/catalog-unprocessed-entities/src/api/index.ts @@ -73,11 +73,12 @@ export class CatalogUnprocessedEntitiesClient private async fetch(path: string, init?: RequestInit): Promise { const url = await this.discovery.getBaseUrl('catalog'); const resp = await this.fetchApi.fetch(`${url}/${path}`, init); + if (!resp.ok) { throw await ResponseError.fromResponse(resp); } - return await resp.json(); + return resp.status === 204 ? (resp as T) : await resp.json(); } async pending(): Promise { From 1f471f0ac4b17acffb7c8b8f5e5b78eb1ddc0c34 Mon Sep 17 00:00:00 2001 From: Kurt King Date: Fri, 2 Feb 2024 13:12:51 -0700 Subject: [PATCH 05/19] refactor: id to entityId Signed-off-by: Kurt King --- plugins/catalog-unprocessed-entities/api-report.md | 2 +- .../catalog-unprocessed-entities/src/api/index.ts | 6 +++--- .../src/components/FailedEntities.tsx | 12 +++++++----- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/plugins/catalog-unprocessed-entities/api-report.md b/plugins/catalog-unprocessed-entities/api-report.md index 0fea84256b..7d8f6299da 100644 --- a/plugins/catalog-unprocessed-entities/api-report.md +++ b/plugins/catalog-unprocessed-entities/api-report.md @@ -14,7 +14,7 @@ import { RouteRef } from '@backstage/core-plugin-api'; // @public export interface CatalogUnprocessedEntitiesApi { - delete(entity_id: string): Promise; + delete(entityId: string): Promise; failed(): Promise; pending(): Promise; } diff --git a/plugins/catalog-unprocessed-entities/src/api/index.ts b/plugins/catalog-unprocessed-entities/src/api/index.ts index ae5feedf84..dfff3e15f7 100644 --- a/plugins/catalog-unprocessed-entities/src/api/index.ts +++ b/plugins/catalog-unprocessed-entities/src/api/index.ts @@ -57,7 +57,7 @@ export interface CatalogUnprocessedEntitiesApi { /** * Deletes an entity from the refresh_state table */ - delete(entity_id: string): Promise; + delete(entityId: string): Promise; } /** @@ -89,8 +89,8 @@ export class CatalogUnprocessedEntitiesClient return await this.fetch('entities/unprocessed/failed'); } - async delete(entity_id: string): Promise { - await this.fetch(`entities/unprocessed/delete/${entity_id}`, { + async delete(entityId: string): Promise { + await this.fetch(`entities/unprocessed/delete/${entityId}`, { method: 'DELETE', }); } diff --git a/plugins/catalog-unprocessed-entities/src/components/FailedEntities.tsx b/plugins/catalog-unprocessed-entities/src/components/FailedEntities.tsx index 4618953af2..ca5ca942c7 100644 --- a/plugins/catalog-unprocessed-entities/src/components/FailedEntities.tsx +++ b/plugins/catalog-unprocessed-entities/src/components/FailedEntities.tsx @@ -108,14 +108,14 @@ export const FailedEntities = () => { } const handleDelete = async ({ - id, + entityId, entityRef, }: { - id: string; + entityId: string; entityRef: string; }) => { try { - await unprocessedEntityApi.delete(id); + await unprocessedEntityApi.delete(entityId); alertApi.post({ message: `Entity ${entityRef} has been deleted`, severity: 'success', @@ -165,13 +165,15 @@ export const FailedEntities = () => { { title: Actions, render: (rowData: UnprocessedEntity | {}) => { + const { entity_id, entity_ref } = rowData as UnprocessedEntity; + return ( await handleDelete({ - id: (rowData as UnprocessedEntity).entity_id, - entityRef: (rowData as UnprocessedEntity).entity_ref, + entityId: entity_id, + entityRef: entity_ref, }) } > From e86433526d19bc121758da7dbd2dd1c7f13a478c Mon Sep 17 00:00:00 2001 From: Kurt King Date: Fri, 2 Feb 2024 13:38:04 -0700 Subject: [PATCH 06/19] feat: support permissions Signed-off-by: Kurt King --- .../package.json | 5 +++ .../src/UnprocessedEntitiesModule.ts | 44 ++++++++++++++++++- .../.eslintrc.js | 1 + .../README.md | 5 +++ .../package.json | 35 +++++++++++++++ .../src/index.ts | 23 ++++++++++ .../src/permissions.ts | 25 +++++++++++ .../src/setupTests.ts | 16 +++++++ yarn.lock | 17 +++++-- 9 files changed, 167 insertions(+), 4 deletions(-) create mode 100644 plugins/catalog-unprocessed-entities-common/.eslintrc.js create mode 100644 plugins/catalog-unprocessed-entities-common/README.md create mode 100644 plugins/catalog-unprocessed-entities-common/package.json create mode 100644 plugins/catalog-unprocessed-entities-common/src/index.ts create mode 100644 plugins/catalog-unprocessed-entities-common/src/permissions.ts create mode 100644 plugins/catalog-unprocessed-entities-common/src/setupTests.ts diff --git a/plugins/catalog-backend-module-unprocessed/package.json b/plugins/catalog-backend-module-unprocessed/package.json index 26243bff51..b5091021c6 100644 --- a/plugins/catalog-backend-module-unprocessed/package.json +++ b/plugins/catalog-backend-module-unprocessed/package.json @@ -36,6 +36,11 @@ "dependencies": { "@backstage/backend-plugin-api": "workspace:^", "@backstage/catalog-model": "workspace:^", + "@backstage/errors": "workspace:^", + "@backstage/plugin-auth-node": "workspace:^", + "@backstage/plugin-catalog-unprocessed-entities-common": "workspace:^", + "@backstage/plugin-permission-common": "workspace:^", + "@backstage/plugin-permission-node": "workspace:^", "express-promise-router": "^4.1.1", "knex": "^3.0.0" } diff --git a/plugins/catalog-backend-module-unprocessed/src/UnprocessedEntitiesModule.ts b/plugins/catalog-backend-module-unprocessed/src/UnprocessedEntitiesModule.ts index 72713178e8..51e3f06894 100644 --- a/plugins/catalog-backend-module-unprocessed/src/UnprocessedEntitiesModule.ts +++ b/plugins/catalog-backend-module-unprocessed/src/UnprocessedEntitiesModule.ts @@ -23,6 +23,15 @@ import { import { Knex } from 'knex'; import { HttpRouterService } from '@backstage/backend-plugin-api'; import Router from 'express-promise-router'; +import { getBearerTokenFromAuthorizationHeader } from '@backstage/plugin-auth-node'; +import { + AuthorizeResult, + BasicPermission, + PermissionEvaluator, +} from '@backstage/plugin-permission-common'; +import { createPermissionIntegrationRouter } from '@backstage/plugin-permission-node'; +import { unprocessedEntitiesDeletePermission } from '@backstage/plugin-catalog-unprocessed-entities-common'; +import { NotAllowedError } from '@backstage/errors'; /** * Module providing Unprocessed Entities API endpoints @@ -103,7 +112,31 @@ export class UnprocessedEntitiesModule { return res; } - registerRoutes() { + registerRoutes({ permissions }: { permissions: PermissionEvaluator }) { + const permissionIntegrationRouter = createPermissionIntegrationRouter({ + permissions: [unprocessedEntitiesDeletePermission], + }); + + const isRequestAuthorized = async ( + req: Request, + permission: BasicPermission, + ): Promise => { + const token = getBearerTokenFromAuthorizationHeader( + // @ts-ignore + req.header('authorization'), + ); + + const decision = ( + await permissions.authorize([{ permission }], { + token, + }) + )[0]; + + return decision.result !== AuthorizeResult.DENY; + }; + + this.router.use(permissionIntegrationRouter); + this.moduleRouter .get('/entities/unprocessed/failed', async (req, res) => { return res.json( @@ -124,6 +157,15 @@ export class UnprocessedEntitiesModule { .delete( '/entities/unprocessed/delete/:entity_id', async (request, response) => { + const authorized = await isRequestAuthorized( + request as any as Request, + unprocessedEntitiesDeletePermission, + ); + + if (!authorized) { + throw new NotAllowedError('Unauthorized'); + } + await this.database('refresh_state') .where({ entity_id: request.params.entity_id }) .delete(); diff --git a/plugins/catalog-unprocessed-entities-common/.eslintrc.js b/plugins/catalog-unprocessed-entities-common/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/plugins/catalog-unprocessed-entities-common/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/catalog-unprocessed-entities-common/README.md b/plugins/catalog-unprocessed-entities-common/README.md new file mode 100644 index 0000000000..490c5e8f6e --- /dev/null +++ b/plugins/catalog-unprocessed-entities-common/README.md @@ -0,0 +1,5 @@ +# @backstage/plugin-catalog-unprocessed-entities-common + +Welcome to the common package for the catalog-unprocessed-entities plugin! + +_This plugin was created through the Backstage CLI_ diff --git a/plugins/catalog-unprocessed-entities-common/package.json b/plugins/catalog-unprocessed-entities-common/package.json new file mode 100644 index 0000000000..b90f3d9182 --- /dev/null +++ b/plugins/catalog-unprocessed-entities-common/package.json @@ -0,0 +1,35 @@ +{ + "name": "@backstage/plugin-catalog-unprocessed-entities-common", + "description": "Common functionalities for the catalog-unprocessed-entities plugin", + "version": "0.0.0", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "publishConfig": { + "access": "public", + "main": "dist/index.cjs.js", + "module": "dist/index.esm.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "common-library" + }, + "sideEffects": false, + "scripts": { + "build": "backstage-cli package build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" + }, + "devDependencies": { + "@backstage/cli": "workspace:^" + }, + "files": [ + "dist" + ], + "dependencies": { + "@backstage/plugin-permission-common": "workspace:^" + } +} diff --git a/plugins/catalog-unprocessed-entities-common/src/index.ts b/plugins/catalog-unprocessed-entities-common/src/index.ts new file mode 100644 index 0000000000..cd5a39c731 --- /dev/null +++ b/plugins/catalog-unprocessed-entities-common/src/index.ts @@ -0,0 +1,23 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Common functionalities for the catalog-unprocessed-entities plugin. + * + * @packageDocumentation + */ + +export * from './permissions'; diff --git a/plugins/catalog-unprocessed-entities-common/src/permissions.ts b/plugins/catalog-unprocessed-entities-common/src/permissions.ts new file mode 100644 index 0000000000..c6ac44fc0b --- /dev/null +++ b/plugins/catalog-unprocessed-entities-common/src/permissions.ts @@ -0,0 +1,25 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { createPermission } from '@backstage/plugin-permission-common'; + +export const unprocessedEntitiesDeletePermission = createPermission({ + name: 'unprocessed-entities.delete', + attributes: { action: 'delete' }, +}); + +export const unprocessedEntitiesPermissions = { + unprocessedEntitiesDeletePermission, +}; diff --git a/plugins/catalog-unprocessed-entities-common/src/setupTests.ts b/plugins/catalog-unprocessed-entities-common/src/setupTests.ts new file mode 100644 index 0000000000..c7ce5c0988 --- /dev/null +++ b/plugins/catalog-unprocessed-entities-common/src/setupTests.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2024 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export {}; diff --git a/yarn.lock b/yarn.lock index 69bf765b58..3f0bcdef53 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1,6 +1,3 @@ -# This file is generated by running "yarn install" inside your project. -# Manual changes might be lost - proceed with caution! - __metadata: version: 6 cacheKey: 8 @@ -5775,6 +5772,11 @@ __metadata: "@backstage/backend-plugin-api": "workspace:^" "@backstage/catalog-model": "workspace:^" "@backstage/cli": "workspace:^" + "@backstage/errors": "workspace:^" + "@backstage/plugin-auth-node": "workspace:^" + "@backstage/plugin-catalog-unprocessed-entities-common": "workspace:^" + "@backstage/plugin-permission-common": "workspace:^" + "@backstage/plugin-permission-node": "workspace:^" express-promise-router: ^4.1.1 knex: ^3.0.0 languageName: unknown @@ -6037,6 +6039,15 @@ __metadata: languageName: unknown linkType: soft +"@backstage/plugin-catalog-unprocessed-entities-common@workspace:^, @backstage/plugin-catalog-unprocessed-entities-common@workspace:plugins/catalog-unprocessed-entities-common": + version: 0.0.0-use.local + resolution: "@backstage/plugin-catalog-unprocessed-entities-common@workspace:plugins/catalog-unprocessed-entities-common" + dependencies: + "@backstage/cli": "workspace:^" + "@backstage/plugin-permission-common": "workspace:^" + languageName: unknown + linkType: soft + "@backstage/plugin-catalog-unprocessed-entities@workspace:^, @backstage/plugin-catalog-unprocessed-entities@workspace:plugins/catalog-unprocessed-entities": version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-unprocessed-entities@workspace:plugins/catalog-unprocessed-entities" From ca6b79b6a28223babf44c0397663a5b5fbd91176 Mon Sep 17 00:00:00 2001 From: Kurt King Date: Sat, 3 Feb 2024 14:09:54 -0700 Subject: [PATCH 07/19] chore: update report Signed-off-by: Kurt King --- .../api-report.md | 15 +++++++++++++++ .../src/permissions.ts | 11 ++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 plugins/catalog-unprocessed-entities-common/api-report.md diff --git a/plugins/catalog-unprocessed-entities-common/api-report.md b/plugins/catalog-unprocessed-entities-common/api-report.md new file mode 100644 index 0000000000..6d5dc15ff5 --- /dev/null +++ b/plugins/catalog-unprocessed-entities-common/api-report.md @@ -0,0 +1,15 @@ +## API Report File for "@backstage/plugin-catalog-unprocessed-entities-common" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BasicPermission } from '@backstage/plugin-permission-common'; + +// @alpha +export const unprocessedEntitiesDeletePermission: BasicPermission; + +// @alpha +export const unprocessedEntitiesPermissions: { + unprocessedEntitiesDeletePermission: BasicPermission; +}; +``` diff --git a/plugins/catalog-unprocessed-entities-common/src/permissions.ts b/plugins/catalog-unprocessed-entities-common/src/permissions.ts index c6ac44fc0b..d34cc0d1dc 100644 --- a/plugins/catalog-unprocessed-entities-common/src/permissions.ts +++ b/plugins/catalog-unprocessed-entities-common/src/permissions.ts @@ -15,11 +15,20 @@ */ import { createPermission } from '@backstage/plugin-permission-common'; +/** + * This permission is used to designate actions that involve removing an + * unprocessed entity record from the refresh_state table. + * @public + */ export const unprocessedEntitiesDeletePermission = createPermission({ - name: 'unprocessed-entities.delete', + name: 'catalog.entities.unprocessed.delete', attributes: { action: 'delete' }, }); +/** + * List of all unprocessed entity permissions + * @public + */ export const unprocessedEntitiesPermissions = { unprocessedEntitiesDeletePermission, }; From 845d40e1b6dc09c28e85bdc1941e1bb10fc233cf Mon Sep 17 00:00:00 2001 From: Kurt King Date: Mon, 12 Feb 2024 22:31:23 -0700 Subject: [PATCH 08/19] chore: api reports Signed-off-by: Kurt King --- plugins/catalog-backend-module-unprocessed/api-report.md | 3 ++- plugins/catalog-unprocessed-entities-common/api-report.md | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/plugins/catalog-backend-module-unprocessed/api-report.md b/plugins/catalog-backend-module-unprocessed/api-report.md index 569bd572da..1309e5bdaa 100644 --- a/plugins/catalog-backend-module-unprocessed/api-report.md +++ b/plugins/catalog-backend-module-unprocessed/api-report.md @@ -6,6 +6,7 @@ import { BackendFeature } from '@backstage/backend-plugin-api'; import { HttpRouterService } from '@backstage/backend-plugin-api'; import { Knex } from 'knex'; +import { PermissionEvaluator } from '@backstage/plugin-permission-common'; // @public const catalogModuleUnprocessedEntities: () => BackendFeature; @@ -15,6 +16,6 @@ export default catalogModuleUnprocessedEntities; export class UnprocessedEntitiesModule { constructor(database: Knex, router: Pick); // (undocumented) - registerRoutes(): void; + registerRoutes({ permissions }: { permissions: PermissionEvaluator }): void; } ``` diff --git a/plugins/catalog-unprocessed-entities-common/api-report.md b/plugins/catalog-unprocessed-entities-common/api-report.md index 6d5dc15ff5..03b316eebb 100644 --- a/plugins/catalog-unprocessed-entities-common/api-report.md +++ b/plugins/catalog-unprocessed-entities-common/api-report.md @@ -5,10 +5,10 @@ ```ts import { BasicPermission } from '@backstage/plugin-permission-common'; -// @alpha +// @public export const unprocessedEntitiesDeletePermission: BasicPermission; -// @alpha +// @public export const unprocessedEntitiesPermissions: { unprocessedEntitiesDeletePermission: BasicPermission; }; From db06fce59273110d50457063adc9124602cd7f6c Mon Sep 17 00:00:00 2001 From: Kurt King Date: Tue, 13 Feb 2024 09:25:34 -0700 Subject: [PATCH 09/19] chore: add missing catalog file Signed-off-by: Kurt King --- .../catalog-info.yaml | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 plugins/catalog-unprocessed-entities-common/catalog-info.yaml diff --git a/plugins/catalog-unprocessed-entities-common/catalog-info.yaml b/plugins/catalog-unprocessed-entities-common/catalog-info.yaml new file mode 100644 index 0000000000..7494c41b5c --- /dev/null +++ b/plugins/catalog-unprocessed-entities-common/catalog-info.yaml @@ -0,0 +1,9 @@ +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: backstage-plugin-catalog-unprocessed-entities-common + title: '@backstage/plugin-catalog-unprocessed-entities-common' +spec: + lifecycle: experimental + type: backstage-common-library + owner: catalog-maintainers From 924c1ac616ef8160559ca4812bf6e70b99a27a2d Mon Sep 17 00:00:00 2001 From: Kurt King Date: Thu, 15 Feb 2024 14:38:57 -0700 Subject: [PATCH 10/19] chore: changeset Signed-off-by: Kurt King --- .changeset/warm-buses-do.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .changeset/warm-buses-do.md diff --git a/.changeset/warm-buses-do.md b/.changeset/warm-buses-do.md new file mode 100644 index 0000000000..27eac558c8 --- /dev/null +++ b/.changeset/warm-buses-do.md @@ -0,0 +1,8 @@ +--- +'@backstage/plugin-catalog-backend-module-unprocessed': minor +'@backstage/plugin-catalog-unprocessed-entities': minor +'@backstage/plugin-catalog-unprocessed-entities-common': patch +--- + +Add the ability to delete an unprocessed entity from the `refresh_state` table +∫ From 31855d303c3ee09aa59475c85982e1e01027b296 Mon Sep 17 00:00:00 2001 From: Kurt King Date: Fri, 16 Feb 2024 07:28:58 -0700 Subject: [PATCH 11/19] Update .changeset/warm-buses-do.md Co-authored-by: Ben Lambert Signed-off-by: Kurt King --- .changeset/warm-buses-do.md | 1 - 1 file changed, 1 deletion(-) diff --git a/.changeset/warm-buses-do.md b/.changeset/warm-buses-do.md index 27eac558c8..bd1e354a60 100644 --- a/.changeset/warm-buses-do.md +++ b/.changeset/warm-buses-do.md @@ -5,4 +5,3 @@ --- Add the ability to delete an unprocessed entity from the `refresh_state` table -∫ From 7a40ad392acd9f0e29ab9d8f0eb735da4a2d6e1e Mon Sep 17 00:00:00 2001 From: Kurt King Date: Mon, 4 Mar 2024 08:09:42 -0700 Subject: [PATCH 12/19] chore: update changeset Signed-off-by: Kurt King --- .changeset/warm-buses-do.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.changeset/warm-buses-do.md b/.changeset/warm-buses-do.md index bd1e354a60..2acd90dd48 100644 --- a/.changeset/warm-buses-do.md +++ b/.changeset/warm-buses-do.md @@ -4,4 +4,6 @@ '@backstage/plugin-catalog-unprocessed-entities-common': patch --- -Add the ability to delete an unprocessed entity from the `refresh_state` table +Breaking change - `@backstage/plugin-catalog-backend-module-unprocessed` + +Adds the ability to delete an unprocessed entity from the `refresh_state` table. This change requires enabling permissions for your Backstage instance. From ed4f88b19586218ec8b1e06695745ab1ed4764c5 Mon Sep 17 00:00:00 2001 From: blam Date: Wed, 13 Mar 2024 14:38:00 +0100 Subject: [PATCH 13/19] chore: fix yarn Signed-off-by: blam --- yarn.lock | 3 +++ 1 file changed, 3 insertions(+) diff --git a/yarn.lock b/yarn.lock index 3f0bcdef53..501c88b70e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1,3 +1,6 @@ +# This file is generated by running "yarn install" inside your project. +# Manual changes might be lost - proceed with caution! + __metadata: version: 6 cacheKey: 8 From 319d58e796a7f429cb28a3b6643e63b96018d86a Mon Sep 17 00:00:00 2001 From: blam Date: Wed, 13 Mar 2024 15:02:11 +0100 Subject: [PATCH 14/19] chore: fix build, install and checks Signed-off-by: blam --- packages/backend/src/plugins/catalog.ts | 4 +- .../src/module.ts | 6 ++- .../package.json | 39 +++++++++++-------- 3 files changed, 29 insertions(+), 20 deletions(-) diff --git a/packages/backend/src/plugins/catalog.ts b/packages/backend/src/plugins/catalog.ts index 9b92b4eb06..95e86ddd23 100644 --- a/packages/backend/src/plugins/catalog.ts +++ b/packages/backend/src/plugins/catalog.ts @@ -41,7 +41,9 @@ export default async function createPlugin( await env.database.getClient(), router, ); - unprocessed.registerRoutes(); + + unprocessed.registerRoutes({ permissions: env.permissions }); + await processingEngine.start(); return router; } diff --git a/plugins/catalog-backend-module-unprocessed/src/module.ts b/plugins/catalog-backend-module-unprocessed/src/module.ts index 8c724d432d..310d78810f 100644 --- a/plugins/catalog-backend-module-unprocessed/src/module.ts +++ b/plugins/catalog-backend-module-unprocessed/src/module.ts @@ -34,14 +34,16 @@ export const catalogModuleUnprocessedEntities = createBackendModule({ database: coreServices.database, router: coreServices.httpRouter, logger: coreServices.logger, + permissions: coreServices.permissions, }, - async init({ database, router, logger }) { + async init({ database, router, logger, permissions }) { const module = new UnprocessedEntitiesModule( await database.getClient(), router, ); - module.registerRoutes(); + module.registerRoutes({ permissions }); + logger.info( 'registered additional routes for catalogModuleUnprocessedEntities', ); diff --git a/plugins/catalog-unprocessed-entities-common/package.json b/plugins/catalog-unprocessed-entities-common/package.json index b90f3d9182..68a5a346b5 100644 --- a/plugins/catalog-unprocessed-entities-common/package.json +++ b/plugins/catalog-unprocessed-entities-common/package.json @@ -1,35 +1,40 @@ { "name": "@backstage/plugin-catalog-unprocessed-entities-common", - "description": "Common functionalities for the catalog-unprocessed-entities plugin", "version": "0.0.0", - "main": "src/index.ts", - "types": "src/index.ts", - "license": "Apache-2.0", + "description": "Common functionalities for the catalog-unprocessed-entities plugin", + "backstage": { + "role": "common-library" + }, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", "module": "dist/index.esm.js", "types": "dist/index.d.ts" }, - "backstage": { - "role": "common-library" + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/catalog-unprocessed-entities-common" }, + "license": "Apache-2.0", "sideEffects": false, - "scripts": { - "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", - "clean": "backstage-cli package clean", - "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" - }, - "devDependencies": { - "@backstage/cli": "workspace:^" - }, + "main": "src/index.ts", + "types": "src/index.ts", "files": [ "dist" ], + "scripts": { + "build": "backstage-cli package build", + "clean": "backstage-cli package clean", + "lint": "backstage-cli package lint", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack", + "test": "backstage-cli package test" + }, "dependencies": { "@backstage/plugin-permission-common": "workspace:^" + }, + "devDependencies": { + "@backstage/cli": "workspace:^" } } From 04ab59d00f440ac5695f68e8864439491684c668 Mon Sep 17 00:00:00 2001 From: blam Date: Wed, 13 Mar 2024 19:04:32 +0100 Subject: [PATCH 15/19] chore: update changeset a little Signed-off-by: blam Signed-off-by: blam --- .changeset/warm-buses-do.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.changeset/warm-buses-do.md b/.changeset/warm-buses-do.md index 2acd90dd48..8290679e51 100644 --- a/.changeset/warm-buses-do.md +++ b/.changeset/warm-buses-do.md @@ -4,6 +4,13 @@ '@backstage/plugin-catalog-unprocessed-entities-common': patch --- -Breaking change - `@backstage/plugin-catalog-backend-module-unprocessed` +**BREAKING**- the `@backstage/plugin-catalog-backend-module-unprocessed` now requires the `permissionsApi`. +If you're using this module in the old backend system you'll need to pass the `permissions` object to the `registerRoutes` method in `packages/backend/src/plugins/catalog.ts`. +No changes should be required if you're using the new backend system. + +```diff +- unprocessed.registerRoutes(); ++ unprocessed.registerRoutes({ permissions: env.permissions }); +``` Adds the ability to delete an unprocessed entity from the `refresh_state` table. This change requires enabling permissions for your Backstage instance. From 8068ee84e3a3d2deccc3c89f8491d073dd5637db Mon Sep 17 00:00:00 2001 From: blam Date: Mon, 18 Mar 2024 17:05:44 +0100 Subject: [PATCH 16/19] chore: use the new auth adapters Signed-off-by: blam --- .../package.json | 4 ++- .../src/UnprocessedEntitiesModule.ts | 33 ++++++++++++------- .../src/module.ts | 16 +++++++-- yarn.lock | 2 ++ 4 files changed, 41 insertions(+), 14 deletions(-) diff --git a/plugins/catalog-backend-module-unprocessed/package.json b/plugins/catalog-backend-module-unprocessed/package.json index b5091021c6..16feb612cb 100644 --- a/plugins/catalog-backend-module-unprocessed/package.json +++ b/plugins/catalog-backend-module-unprocessed/package.json @@ -28,12 +28,14 @@ "postpack": "backstage-cli package postpack" }, "devDependencies": { - "@backstage/cli": "workspace:^" + "@backstage/cli": "workspace:^", + "@types/express": "^4.17.6" }, "files": [ "dist" ], "dependencies": { + "@backstage/backend-common": "workspace:^", "@backstage/backend-plugin-api": "workspace:^", "@backstage/catalog-model": "workspace:^", "@backstage/errors": "workspace:^", diff --git a/plugins/catalog-backend-module-unprocessed/src/UnprocessedEntitiesModule.ts b/plugins/catalog-backend-module-unprocessed/src/UnprocessedEntitiesModule.ts index 51e3f06894..48f4ea58cf 100644 --- a/plugins/catalog-backend-module-unprocessed/src/UnprocessedEntitiesModule.ts +++ b/plugins/catalog-backend-module-unprocessed/src/UnprocessedEntitiesModule.ts @@ -21,17 +21,23 @@ import { UnprocessedEntitiesResponse, } from './types'; import { Knex } from 'knex'; -import { HttpRouterService } from '@backstage/backend-plugin-api'; +import { + DiscoveryService, + HttpAuthService, + HttpRouterService, + PermissionsService, +} from '@backstage/backend-plugin-api'; import Router from 'express-promise-router'; -import { getBearerTokenFromAuthorizationHeader } from '@backstage/plugin-auth-node'; +import type { Request } from 'express'; + import { AuthorizeResult, BasicPermission, - PermissionEvaluator, } from '@backstage/plugin-permission-common'; import { createPermissionIntegrationRouter } from '@backstage/plugin-permission-node'; import { unprocessedEntitiesDeletePermission } from '@backstage/plugin-catalog-unprocessed-entities-common'; import { NotAllowedError } from '@backstage/errors'; +import { createLegacyAuthAdapters } from '@backstage/backend-common'; /** * Module providing Unprocessed Entities API endpoints @@ -41,12 +47,22 @@ import { NotAllowedError } from '@backstage/errors'; export class UnprocessedEntitiesModule { private readonly moduleRouter; + private readonly httpAuth: HttpAuthService; + constructor( private readonly database: Knex, private readonly router: Pick, + private readonly permissions: PermissionsService, + discovery: DiscoveryService, + httpAuth?: HttpAuthService, ) { this.moduleRouter = Router(); this.router.use(this.moduleRouter); + + this.httpAuth = createLegacyAuthAdapters({ + discovery, + httpAuth, + }).httpAuth; } private async unprocessed( @@ -112,7 +128,7 @@ export class UnprocessedEntitiesModule { return res; } - registerRoutes({ permissions }: { permissions: PermissionEvaluator }) { + registerRoutes() { const permissionIntegrationRouter = createPermissionIntegrationRouter({ permissions: [unprocessedEntitiesDeletePermission], }); @@ -121,14 +137,9 @@ export class UnprocessedEntitiesModule { req: Request, permission: BasicPermission, ): Promise => { - const token = getBearerTokenFromAuthorizationHeader( - // @ts-ignore - req.header('authorization'), - ); - const decision = ( - await permissions.authorize([{ permission }], { - token, + await this.permissions.authorize([{ permission }], { + credentials: await this.httpAuth.credentials(req), }) )[0]; diff --git a/plugins/catalog-backend-module-unprocessed/src/module.ts b/plugins/catalog-backend-module-unprocessed/src/module.ts index 310d78810f..2420c75cbd 100644 --- a/plugins/catalog-backend-module-unprocessed/src/module.ts +++ b/plugins/catalog-backend-module-unprocessed/src/module.ts @@ -34,15 +34,27 @@ export const catalogModuleUnprocessedEntities = createBackendModule({ database: coreServices.database, router: coreServices.httpRouter, logger: coreServices.logger, + httpAuth: coreServices.httpAuth, + discovery: coreServices.discovery, permissions: coreServices.permissions, }, - async init({ database, router, logger, permissions }) { + async init({ + database, + router, + logger, + permissions, + httpAuth, + discovery, + }) { const module = new UnprocessedEntitiesModule( await database.getClient(), router, + permissions, + discovery, + httpAuth, ); - module.registerRoutes({ permissions }); + module.registerRoutes(); logger.info( 'registered additional routes for catalogModuleUnprocessedEntities', diff --git a/yarn.lock b/yarn.lock index 501c88b70e..73b18a599a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5772,6 +5772,7 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage/plugin-catalog-backend-module-unprocessed@workspace:plugins/catalog-backend-module-unprocessed" dependencies: + "@backstage/backend-common": "workspace:^" "@backstage/backend-plugin-api": "workspace:^" "@backstage/catalog-model": "workspace:^" "@backstage/cli": "workspace:^" @@ -5780,6 +5781,7 @@ __metadata: "@backstage/plugin-catalog-unprocessed-entities-common": "workspace:^" "@backstage/plugin-permission-common": "workspace:^" "@backstage/plugin-permission-node": "workspace:^" + "@types/express": ^4.17.6 express-promise-router: ^4.1.1 knex: ^3.0.0 languageName: unknown From c953d486c7754238ce0f210b874797d198b9b814 Mon Sep 17 00:00:00 2001 From: blam Date: Mon, 18 Mar 2024 17:32:37 +0100 Subject: [PATCH 17/19] chore: fix changese and updating things Signed-off-by: blam --- .changeset/warm-buses-do.md | 20 +++++++++++++++---- packages/backend/src/plugins/catalog.ts | 10 ++++++---- .../src/UnprocessedEntitiesModule.ts | 18 ++++++++++++++++- .../src/module.ts | 6 +++--- 4 files changed, 42 insertions(+), 12 deletions(-) diff --git a/.changeset/warm-buses-do.md b/.changeset/warm-buses-do.md index 8290679e51..b1755b0d0c 100644 --- a/.changeset/warm-buses-do.md +++ b/.changeset/warm-buses-do.md @@ -4,13 +4,25 @@ '@backstage/plugin-catalog-unprocessed-entities-common': patch --- -**BREAKING**- the `@backstage/plugin-catalog-backend-module-unprocessed` now requires the `permissionsApi`. -If you're using this module in the old backend system you'll need to pass the `permissions` object to the `registerRoutes` method in `packages/backend/src/plugins/catalog.ts`. +**BREAKING**- the `@backstage/plugin-catalog-backend-module-unprocessed` constructor is now private, and have been moved to using the static `.create` method instead which now requires a `PermissionService` and `DiscoveryService`. + +If you're using this module in the old backend system you'll need to migrate to using the `.create` method and pass in the new required parameters in `packages/backend/src/plugins/catalog.ts`. + No changes should be required if you're using the new backend system. ```diff -- unprocessed.registerRoutes(); -+ unprocessed.registerRoutes({ permissions: env.permissions }); +- const unprocessed = new UnprocessedEntitiesModule( +- await env.database.getClient(), +- router, +- ); ++ const unprocessed = UnprocessedEntitiesModule.create({ ++ database: await env.database.getClient(), ++ router, ++ permissions: env.permissions, ++ discovery: env.discovery, ++ }); + + unprocessed.registerRoutes(); ``` Adds the ability to delete an unprocessed entity from the `refresh_state` table. This change requires enabling permissions for your Backstage instance. diff --git a/packages/backend/src/plugins/catalog.ts b/packages/backend/src/plugins/catalog.ts index 95e86ddd23..c83d5844d1 100644 --- a/packages/backend/src/plugins/catalog.ts +++ b/packages/backend/src/plugins/catalog.ts @@ -37,12 +37,14 @@ export default async function createPlugin( const { processingEngine, router } = await builder.build(); - const unprocessed = new UnprocessedEntitiesModule( - await env.database.getClient(), + const unprocessed = UnprocessedEntitiesModule.create({ + database: await env.database.getClient(), router, - ); + permissions: env.permissions, + discovery: env.discovery, + }); - unprocessed.registerRoutes({ permissions: env.permissions }); + unprocessed.registerRoutes(); await processingEngine.start(); return router; diff --git a/plugins/catalog-backend-module-unprocessed/src/UnprocessedEntitiesModule.ts b/plugins/catalog-backend-module-unprocessed/src/UnprocessedEntitiesModule.ts index 48f4ea58cf..f177818b28 100644 --- a/plugins/catalog-backend-module-unprocessed/src/UnprocessedEntitiesModule.ts +++ b/plugins/catalog-backend-module-unprocessed/src/UnprocessedEntitiesModule.ts @@ -49,7 +49,7 @@ export class UnprocessedEntitiesModule { private readonly httpAuth: HttpAuthService; - constructor( + private constructor( private readonly database: Knex, private readonly router: Pick, private readonly permissions: PermissionsService, @@ -65,6 +65,22 @@ export class UnprocessedEntitiesModule { }).httpAuth; } + static create(options: { + router: Pick; + database: Knex; + discovery: DiscoveryService; + permissions: PermissionsService; + httpAuth?: HttpAuthService; + }) { + return new UnprocessedEntitiesModule( + options.database, + options.router, + options.permissions, + options.discovery, + options.httpAuth, + ); + } + private async unprocessed( request: UnprocessedEntitiesRequest, ): Promise { diff --git a/plugins/catalog-backend-module-unprocessed/src/module.ts b/plugins/catalog-backend-module-unprocessed/src/module.ts index 2420c75cbd..852b8fb432 100644 --- a/plugins/catalog-backend-module-unprocessed/src/module.ts +++ b/plugins/catalog-backend-module-unprocessed/src/module.ts @@ -46,13 +46,13 @@ export const catalogModuleUnprocessedEntities = createBackendModule({ httpAuth, discovery, }) { - const module = new UnprocessedEntitiesModule( - await database.getClient(), + const module = UnprocessedEntitiesModule.create({ + database: await database.getClient(), router, permissions, discovery, httpAuth, - ); + }); module.registerRoutes(); From 0c234a73ac4a59699b492ce82050f4c95a4e73e6 Mon Sep 17 00:00:00 2001 From: blam Date: Mon, 18 Mar 2024 17:36:56 +0100 Subject: [PATCH 18/19] chore: fix Signed-off-by: blam --- .../src/UnprocessedEntitiesModule.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/catalog-backend-module-unprocessed/src/UnprocessedEntitiesModule.ts b/plugins/catalog-backend-module-unprocessed/src/UnprocessedEntitiesModule.ts index f177818b28..2653ffedac 100644 --- a/plugins/catalog-backend-module-unprocessed/src/UnprocessedEntitiesModule.ts +++ b/plugins/catalog-backend-module-unprocessed/src/UnprocessedEntitiesModule.ts @@ -169,7 +169,7 @@ export class UnprocessedEntitiesModule { return res.json( await this.unprocessed({ reason: 'failed', - owner: req.query.owner as string, + owner: String(req.query.owner), }), ); }) @@ -177,7 +177,7 @@ export class UnprocessedEntitiesModule { return res.json( await this.unprocessed({ reason: 'pending', - owner: req.query.owner as string, + owner: String(req.query.owner), }), ); }) @@ -185,7 +185,7 @@ export class UnprocessedEntitiesModule { '/entities/unprocessed/delete/:entity_id', async (request, response) => { const authorized = await isRequestAuthorized( - request as any as Request, + request, unprocessedEntitiesDeletePermission, ); From e98d1a9eaea83d9373e0a15d6fd5a621ecd360f1 Mon Sep 17 00:00:00 2001 From: blam Date: Tue, 19 Mar 2024 09:02:32 +0100 Subject: [PATCH 19/19] chore: update api-reports Signed-off-by: blam --- .../api-report.md | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/plugins/catalog-backend-module-unprocessed/api-report.md b/plugins/catalog-backend-module-unprocessed/api-report.md index 1309e5bdaa..febde39834 100644 --- a/plugins/catalog-backend-module-unprocessed/api-report.md +++ b/plugins/catalog-backend-module-unprocessed/api-report.md @@ -4,9 +4,11 @@ ```ts import { BackendFeature } from '@backstage/backend-plugin-api'; +import { DiscoveryService } from '@backstage/backend-plugin-api'; +import { HttpAuthService } from '@backstage/backend-plugin-api'; import { HttpRouterService } from '@backstage/backend-plugin-api'; import { Knex } from 'knex'; -import { PermissionEvaluator } from '@backstage/plugin-permission-common'; +import { PermissionsService } from '@backstage/backend-plugin-api'; // @public const catalogModuleUnprocessedEntities: () => BackendFeature; @@ -14,8 +16,15 @@ export default catalogModuleUnprocessedEntities; // @public export class UnprocessedEntitiesModule { - constructor(database: Knex, router: Pick); // (undocumented) - registerRoutes({ permissions }: { permissions: PermissionEvaluator }): void; + static create(options: { + router: Pick; + database: Knex; + discovery: DiscoveryService; + permissions: PermissionsService; + httpAuth?: HttpAuthService; + }): UnprocessedEntitiesModule; + // (undocumented) + registerRoutes(): void; } ```