added the catalog.location.create permission to the analyze-location endpoint

Signed-off-by: Kashish Mittal <kmittal@redhat.com>
This commit is contained in:
Kashish Mittal
2024-08-06 15:17:03 -04:00
parent 3161dd8c9e
commit 8c3821c24a
4 changed files with 61 additions and 2 deletions
@@ -0,0 +1,49 @@
/*
* 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 { catalogLocationCreatePermission } from '@backstage/plugin-catalog-common/alpha';
import { AuthorizeResult } from '@backstage/plugin-permission-common';
import { PermissionsService } from '@backstage/backend-plugin-api';
import { LocationAnalyzer } from '@backstage/plugin-catalog-node';
import { AnalyzeLocationRequest } from '@backstage/plugin-catalog-common';
import { AnalyzeLocationResponse } from '@backstage/plugin-catalog-common';
export class AuthorizedLocationAnalyzer implements LocationAnalyzer {
constructor(
private readonly service: LocationAnalyzer,
private readonly permissionApi: PermissionsService,
) {}
async analyzeLocation(
request: AnalyzeLocationRequest,
): Promise<AnalyzeLocationResponse> {
const authorizeDecision = (
await this.permissionApi.authorize(
[
{
permission: catalogLocationCreatePermission,
},
],
{ credentials: request.credentials },
)
)[0];
if (authorizeDecision.result !== AuthorizeResult.ALLOW) {
throw new NotAllowedError();
}
return this.service.analyzeLocation(request);
}
}
@@ -59,6 +59,7 @@ import {
import { ConfigLocationEntityProvider } from '../modules/core/ConfigLocationEntityProvider';
import { DefaultLocationStore } from '../modules/core/DefaultLocationStore';
import { RepoLocationAnalyzer } from '../ingestion/LocationAnalyzer';
import { AuthorizedLocationAnalyzer } from './AuthorizedLocationAnalyzer';
import {
jsonPlaceholderResolver,
textPlaceholderResolver,
@@ -600,7 +601,10 @@ export class CatalogBuilder {
const locationAnalyzer =
this.locationAnalyzer ??
new RepoLocationAnalyzer(logger, integrations, this.locationAnalyzers);
new AuthorizedLocationAnalyzer(
new RepoLocationAnalyzer(logger, integrations, this.locationAnalyzers),
permissionsService,
);
const locationService = new AuthorizedLocationService(
new DefaultLocationService(locationStore, orchestrator, {
allowedLocationTypes: this.allowedLocationType,
@@ -301,9 +301,13 @@ export async function createRouter(
location: locationInput,
catalogFilename: z.string().optional(),
});
const credentials = await httpAuth.credentials(req);
const parsedBody = schema.parse(body);
const analyzeLocationRequest = { ...parsedBody, credentials };
try {
const output = await locationAnalyzer.analyzeLocation(parsedBody);
const output = await locationAnalyzer.analyzeLocation(
analyzeLocationRequest,
);
res.status(200).json(output);
} catch (err) {
if (
@@ -17,11 +17,13 @@
import { LocationSpec } from '../common';
import { Entity } from '@backstage/catalog-model';
import { RecursivePartial } from './RecursivePartial';
import { BackstageCredentials } from '@backstage/backend-plugin-api';
/** @public */
export type AnalyzeLocationRequest = {
location: LocationSpec;
catalogFilename?: string;
credentials: BackstageCredentials;
};
/** @public */