Skip to content

Commit

Permalink
fix: issue template not resolving
Browse files Browse the repository at this point in the history
  • Loading branch information
hitesh-sourcefuse committed Dec 9, 2024
1 parent 41df43e commit 2009aa9
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 16 deletions.
44 changes: 44 additions & 0 deletions .vscode/bookmarks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"files": [
{
"path": "node_modules/@backstage/plugin-catalog-backend/dist/cjs/CatalogBuilder-CGSl8LEN.cjs.js",
"bookmarks": [
{
"line": 2369,
"column": 0,
"label": "FilterQueryBuilder"
},
{
"line": 2452,
"column": 0,
"label": "DB Query execution"
},
{
"line": 5559,
"column": 0,
"label": "Catalog entities router "
},
{
"line": 7111,
"column": 0,
"label": "Catalog permission router"
},
{
"line": 7170,
"column": 0,
"label": "CatalogRoute creation"
}
]
},
{
"path": "node_modules/@backstage/plugin-permission-node/dist/index.cjs.js",
"bookmarks": [
{
"line": 26,
"column": 0,
"label": "Permission JSON creation fn"
}
]
}
]
}
16 changes: 16 additions & 0 deletions packages/backend/src/extensions/catalogPermissionRules.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { createBackendModule } from '@backstage/backend-plugin-api';
import { catalogPermissionExtensionPoint } from '@backstage/plugin-catalog-node/alpha';
import { isHaveRepositoryAccess } from '../premissions/repository.rule';

export default createBackendModule({
pluginId: 'catalog',
moduleId: 'permission-rules',
register(reg) {
reg.registerInit({
deps: { catalog: catalogPermissionExtensionPoint },
async init({ catalog }) {
catalog.addPermissionRules(isHaveRepositoryAccess);
},
});
},
});
1 change: 1 addition & 0 deletions packages/backend/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ backend.add(import('@backstage/plugin-catalog-backend/alpha'));
backend.add(
import('@backstage/plugin-catalog-backend-module-scaffolder-entity-model'),
);
backend.add(import('./extensions/catalogPermissionRules'));

// See https://backstage.io/docs/features/software-catalog/configuration#subscribing-to-catalog-errors
backend.add(import('@backstage/plugin-catalog-backend-module-logs'));
Expand Down
36 changes: 20 additions & 16 deletions packages/backend/src/plugins/permission.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,11 @@ import {
isPermission,
type PolicyDecision,
} from '@backstage/plugin-permission-common';
import type {
PermissionPolicy,
PolicyQuery,
} from '@backstage/plugin-permission-node';
import {
catalogConditions,
createCatalogConditionalDecision,
} from '@backstage/plugin-catalog-backend/alpha';
type PermissionPolicy,
type PolicyQuery,
} from '@backstage/plugin-permission-node';
import { createCatalogConditionalDecision } from '@backstage/plugin-catalog-backend/alpha';
import { catalogEntityReadPermission } from '@backstage/plugin-catalog-common/alpha';
import type { BackstageIdentityResponse } from '@backstage/plugin-auth-node';
import type { PaginatingEndpoints } from '@octokit/plugin-paginate-rest';
Expand All @@ -26,6 +23,7 @@ import { policyExtensionPoint } from '@backstage/plugin-permission-node/alpha';
import { coreServices } from '@backstage/backend-plugin-api';
import { Octokit } from 'octokit';
import * as _ from 'lodash';
import { RepositoryAccessCondition as repositoryAccessCondition } from '../premissions/repository.rule';

class RequestPermissionPolicy implements PermissionPolicy {
readonly orgRepositories: Promise<
Expand All @@ -50,6 +48,7 @@ class RequestPermissionPolicy implements PermissionPolicy {
request: PolicyQuery,
user?: BackstageIdentityResponse,
): Promise<PolicyDecision> {
// return { result: AuthorizeResult.ALLOW };
if (!user?.identity) {
this.logger.error('not able to found the name', {
user: JSON.stringify(user),
Expand All @@ -73,7 +72,7 @@ class RequestPermissionPolicy implements PermissionPolicy {
}

this.logger.info("didn't received any handler for the policy request", {
request,
request: JSON.stringify(request, null, 2),
});
return { result: AuthorizeResult.ALLOW };
}
Expand Down Expand Up @@ -179,8 +178,15 @@ class RequestPermissionPolicy implements PermissionPolicy {
user.identity.userEntityRef,
);

if (!userPermission) {
if (!userPermission?.length) {
// permission not resolved from the Github API
this.logger.info(
"Not able to fetch user Permission or Github didn't have repos for the user",
{
user: user.identity.userEntityRef,
resolvedPermission: JSON.stringify(userPermission),
},
);
return { result: AuthorizeResult.DENY };
}
this.logger.debug('Permission resolution benchmark', {
Expand All @@ -189,13 +195,11 @@ class RequestPermissionPolicy implements PermissionPolicy {
this.logger.debug('Permission resolution benchmark', {
totalTimeInMilliSeconds: startTimeBenchmark - performance.now(),
});
return createCatalogConditionalDecision(request.permission, {
//@ts-ignore
anyOf: userPermission.map(value =>
//@ts-ignore
catalogConditions.hasMetadata({ key: 'name', value }),
),
});
const condition = createCatalogConditionalDecision(
request.permission,
repositoryAccessCondition({ repos: userPermission }),
);
return condition;
}
}

Expand Down
42 changes: 42 additions & 0 deletions packages/backend/src/premissions/repository.rule.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import type { Entity } from '@backstage/catalog-model';
import { z } from 'zod';
import { createCatalogPermissionRule } from '@backstage/plugin-catalog-backend/alpha';
import { createConditionFactory } from '@backstage/plugin-permission-node';

export const isHaveRepositoryAccess = createCatalogPermissionRule({
name: 'IS_HAVE_REPO_ACCESS',
description: 'Checks if entity have repository access',
resourceType: 'catalog-entity',
paramsSchema: z.object({
repos: z.string().array().describe('name of repositories to check'),
}),
apply: (resource: Entity, { repos }) => {
if (!resource.relations) {
return false;
}

return resource.relations
.filter(relation => relation.type === 'partOf')
.some(relation => repos.includes(relation.targetRef));
},
toQuery: ({ repos }) => {
// it will add sql query to check repo or all the templates
// "metadata.name" in ["repoName"] or kind in ['template']
return {
anyOf: [
{
key: 'metadata.name',
values: repos,
},
{
// Skip from the check it will allow all the templates
key: 'kind',
values: ['template'],
},
],
};
},
});
export const RepositoryAccessCondition = createConditionFactory(
isHaveRepositoryAccess,
);

0 comments on commit 2009aa9

Please sign in to comment.