added the catalog.entity.create permission to the validate-entity endpoint

Signed-off-by: Kashish Mittal <kmittal@redhat.com>
This commit is contained in:
Kashish Mittal
2024-08-06 15:05:04 -04:00
parent eb1f19497d
commit 3161dd8c9e
4 changed files with 80 additions and 9 deletions
@@ -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;
};
/**
@@ -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<EntityProcessingResult> {
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();
}
}
}
@@ -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,
@@ -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)