From 3161dd8c9ec82264cf6145dfc92a20a00c2bd676 Mon Sep 17 00:00:00 2001 From: Kashish Mittal Date: Tue, 6 Aug 2024 15:05:04 -0400 Subject: [PATCH] added the catalog.entity.create permission to the validate-entity endpoint Signed-off-by: Kashish Mittal --- .../catalog-backend/src/processing/types.ts | 2 + ...AuthorizedCatalogProcessingOrchestrator.ts | 61 +++++++++++++++++++ .../src/service/CatalogBuilder.ts | 24 +++++--- .../src/service/createRouter.ts | 2 + 4 files changed, 80 insertions(+), 9 deletions(-) create mode 100644 plugins/catalog-backend/src/service/AuthorizedCatalogProcessingOrchestrator.ts diff --git a/plugins/catalog-backend/src/processing/types.ts b/plugins/catalog-backend/src/processing/types.ts index 002747d4c4..db5f85415d 100644 --- a/plugins/catalog-backend/src/processing/types.ts +++ b/plugins/catalog-backend/src/processing/types.ts @@ -20,6 +20,7 @@ import { DeferredEntity, EntityRelationSpec, } from '@backstage/plugin-catalog-node'; +import { BackstageCredentials } from '@backstage/backend-plugin-api'; /** * The request to process an entity. @@ -28,6 +29,7 @@ import { export type EntityProcessingRequest = { entity: Entity; state?: JsonObject; // Versions for multiple deployments etc + credentials?: BackstageCredentials; }; /** diff --git a/plugins/catalog-backend/src/service/AuthorizedCatalogProcessingOrchestrator.ts b/plugins/catalog-backend/src/service/AuthorizedCatalogProcessingOrchestrator.ts new file mode 100644 index 0000000000..e4657f01ba --- /dev/null +++ b/plugins/catalog-backend/src/service/AuthorizedCatalogProcessingOrchestrator.ts @@ -0,0 +1,61 @@ +/* + * Copyright 2021 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 { NotAllowedError } from '@backstage/errors'; +import { catalogEntityCreatePermission } from '@backstage/plugin-catalog-common/alpha'; +import { AuthorizeResult } from '@backstage/plugin-permission-common'; +import { + CatalogProcessingOrchestrator, + EntityProcessingRequest, + EntityProcessingResult, +} from '../processing/types'; +import { + BackstageCredentials, + PermissionsService, +} from '@backstage/backend-plugin-api'; + +export class AuthorizedCatalogProcessingOrchestrator + implements CatalogProcessingOrchestrator +{ + constructor( + private readonly service: CatalogProcessingOrchestrator, + private readonly permissionApi: PermissionsService, + ) {} + async process( + request: EntityProcessingRequest, + ): Promise { + if (request.credentials) { + await this.ensureAuthorized(request.credentials); + } + return this.service.process(request); + } + + private async ensureAuthorized(credentials: BackstageCredentials) { + const authorizeDecision = ( + await this.permissionApi.authorize( + [ + { + permission: catalogEntityCreatePermission, + }, + ], + { credentials }, + ) + )[0]; + + if (authorizeDecision.result !== AuthorizeResult.ALLOW) { + throw new NotAllowedError(); + } + } +} diff --git a/plugins/catalog-backend/src/service/CatalogBuilder.ts b/plugins/catalog-backend/src/service/CatalogBuilder.ts index aabef51195..67c7bf74af 100644 --- a/plugins/catalog-backend/src/service/CatalogBuilder.ts +++ b/plugins/catalog-backend/src/service/CatalogBuilder.ts @@ -76,6 +76,7 @@ import { DefaultCatalogProcessingEngine } from '../processing/DefaultCatalogProc import { DefaultLocationService } from './DefaultLocationService'; import { DefaultEntitiesCatalog } from './DefaultEntitiesCatalog'; import { DefaultCatalogProcessingOrchestrator } from '../processing/DefaultCatalogProcessingOrchestrator'; +import { AuthorizedCatalogProcessingOrchestrator } from './AuthorizedCatalogProcessingOrchestrator'; import { DefaultStitcher } from '../stitching/DefaultStitcher'; import { createRouter } from './createRouter'; import { DefaultRefreshService } from './DefaultRefreshService'; @@ -510,15 +511,7 @@ export class CatalogBuilder { }); const integrations = ScmIntegrations.fromConfig(config); const rulesEnforcer = DefaultCatalogRulesEnforcer.fromConfig(config); - const orchestrator = new DefaultCatalogProcessingOrchestrator({ - processors, - integrations, - rulesEnforcer, - logger, - parser, - policy, - legacySingleProcessorValidation: this.legacySingleProcessorValidation, - }); + const unauthorizedEntitiesCatalog = new DefaultEntitiesCatalog({ database: dbClient, logger, @@ -535,6 +528,19 @@ export class CatalogBuilder { permissionsService = toPermissionEvaluator(permissions); } + const orchestrator = new AuthorizedCatalogProcessingOrchestrator( + new DefaultCatalogProcessingOrchestrator({ + processors, + integrations, + rulesEnforcer, + logger, + parser, + policy, + legacySingleProcessorValidation: this.legacySingleProcessorValidation, + }), + permissionsService, + ); + const entitiesCatalog = new AuthorizedEntitiesCatalog( unauthorizedEntitiesCatalog, permissionsService, diff --git a/plugins/catalog-backend/src/service/createRouter.ts b/plugins/catalog-backend/src/service/createRouter.ts index 774ee61a6d..a4fd29cf76 100644 --- a/plugins/catalog-backend/src/service/createRouter.ts +++ b/plugins/catalog-backend/src/service/createRouter.ts @@ -342,6 +342,7 @@ export async function createRouter( }); } + const credentials = await httpAuth.credentials(req); const processingResult = await orchestrator.process({ entity: { ...entity, @@ -354,6 +355,7 @@ export async function createRouter( }, }, }, + credentials: credentials, }); if (!processingResult.ok)