Avoid PermissionEvaluator breaking changes

Signed-off-by: Vincenzo Scamporlino <me@vinzscam.dev>
This commit is contained in:
Vincenzo Scamporlino
2022-04-05 12:47:28 +02:00
parent 8b27170d30
commit 173aadff5b
5 changed files with 102 additions and 15 deletions
+5 -2
View File
@@ -24,7 +24,10 @@ import {
UrlReader,
} from '@backstage/backend-common';
import { PluginTaskScheduler } from '@backstage/backend-tasks';
import { PermissionEvaluator } from '@backstage/plugin-permission-common';
import {
PermissionAuthorizer,
PermissionEvaluator,
} from '@backstage/plugin-permission-common';
export type PluginEnvironment = {
logger: Logger;
@@ -34,6 +37,6 @@ export type PluginEnvironment = {
reader: UrlReader;
discovery: PluginEndpointDiscovery;
tokenManager: TokenManager;
permissions: PermissionEvaluator;
permissions: PermissionEvaluator | PermissionAuthorizer;
scheduler: PluginTaskScheduler;
};
@@ -79,7 +79,11 @@ import {
CatalogPermissionRule,
permissionRules as catalogPermissionRules,
} from '../permissions/rules';
import { PermissionEvaluator } from '@backstage/plugin-permission-common';
import {
PermissionAuthorizer,
PermissionEvaluator,
toPermissionEvaluator,
} from '@backstage/plugin-permission-common';
import {
createConditionTransformer,
createPermissionIntegrationRouter,
@@ -95,7 +99,7 @@ export type CatalogEnvironment = {
database: PluginDatabaseManager;
config: Config;
reader: UrlReader;
permissions: PermissionEvaluator;
permissions: PermissionEvaluator | PermissionAuthorizer;
};
/**
@@ -376,9 +380,20 @@ export class CatalogBuilder {
policy,
});
const unauthorizedEntitiesCatalog = new DefaultEntitiesCatalog(dbClient);
let permissionEvaluator: PermissionEvaluator;
if (!permissions.hasOwnProperty('query')) {
logger.warn(
'PermissionAuthorizer is deprecated. Please use PermissionEvaluator instead of PermissionAuthorizer in catalog.ts',
);
permissionEvaluator = toPermissionEvaluator(permissions);
} else {
permissionEvaluator = permissions as PermissionEvaluator;
}
const entitiesCatalog = new AuthorizedEntitiesCatalog(
unauthorizedEntitiesCatalog,
permissions,
permissionEvaluator,
createConditionTransformer(this.permissionRules),
);
const permissionIntegrationRouter = createPermissionIntegrationRouter({
@@ -428,11 +443,11 @@ export class CatalogBuilder {
this.locationAnalyzer ?? new RepoLocationAnalyzer(logger, integrations);
const locationService = new AuthorizedLocationService(
new DefaultLocationService(locationStore, orchestrator),
permissions,
permissionEvaluator,
);
const refreshService = new AuthorizedRefreshService(
new DefaultRefreshService({ database: processingDatabase }),
permissions,
permissionEvaluator,
);
const router = await createRouter({
entitiesCatalog,
+20 -4
View File
@@ -20,22 +20,38 @@ import Router from 'express-promise-router';
import { Logger } from 'winston';
import { JenkinsInfoProvider } from './jenkinsInfoProvider';
import { JenkinsApiImpl } from './jenkinsApi';
import { PermissionEvaluator } from '@backstage/plugin-permission-common';
import {
PermissionAuthorizer,
PermissionEvaluator,
toPermissionEvaluator,
} from '@backstage/plugin-permission-common';
import { getBearerTokenFromAuthorizationHeader } from '@backstage/plugin-auth-node';
import { stringifyEntityRef } from '@backstage/catalog-model';
export interface RouterOptions {
logger: Logger;
jenkinsInfoProvider: JenkinsInfoProvider;
permissions?: PermissionEvaluator;
permissions?: PermissionEvaluator | PermissionAuthorizer;
}
export async function createRouter(
options: RouterOptions,
): Promise<express.Router> {
const { jenkinsInfoProvider } = options;
const { jenkinsInfoProvider, permissions, logger } = options;
const jenkinsApi = new JenkinsApiImpl(options.permissions);
let permissionEvaluator: PermissionEvaluator | undefined;
if (permissions?.hasOwnProperty('query')) {
permissionEvaluator = permissions as PermissionEvaluator;
} else {
logger.warn(
'PermissionAuthorizer is deprecated. Please use PermissionEvaluator instead of PermissionAuthorizer in your jenkins.ts',
);
permissionEvaluator = permissions
? toPermissionEvaluator(permissions)
: undefined;
}
const jenkinsApi = new JenkinsApiImpl(permissionEvaluator);
const router = Router();
router.use(express.json());
@@ -14,7 +14,18 @@
* limitations under the License.
*/
import { Permission, ResourcePermission } from '../types';
import {
AuthorizePermissionRequest,
AuthorizePermissionResponse,
DefinitivePolicyDecision,
EvaluatorRequestOptions,
Permission,
PermissionAuthorizer,
PermissionEvaluator,
QueryPermissionRequest,
QueryPermissionResponse,
ResourcePermission,
} from '../types';
/**
* Check if the two parameters are equivalent permissions.
@@ -75,3 +86,26 @@ export function isUpdatePermission(permission: Permission) {
export function isDeletePermission(permission: Permission) {
return permission.attributes.action === 'delete';
}
export function toPermissionEvaluator(
permissionAuthorizer: PermissionAuthorizer,
): PermissionEvaluator {
return {
authorize: async (
requests: AuthorizePermissionRequest[],
options?: EvaluatorRequestOptions,
): Promise<AuthorizePermissionResponse[]> => {
const response = await permissionAuthorizer.authorize(requests, options);
return response as DefinitivePolicyDecision[];
},
query(
requests: QueryPermissionRequest[],
options?: EvaluatorRequestOptions,
): Promise<QueryPermissionResponse[]> {
// @ts-expect-error
const parsedRequests: AuthorizePermissionRequest[] = requests;
return permissionAuthorizer.authorize(parsedRequests, options);
},
};
}
+22 -3
View File
@@ -23,7 +23,11 @@ import { InputError } from '@backstage/errors';
import { Config } from '@backstage/config';
import { JsonObject, JsonValue } from '@backstage/types';
import { getBearerTokenFromAuthorizationHeader } from '@backstage/plugin-auth-node';
import { PermissionEvaluator } from '@backstage/plugin-permission-common';
import {
PermissionAuthorizer,
PermissionEvaluator,
toPermissionEvaluator,
} from '@backstage/plugin-permission-common';
import {
DocumentTypeInfo,
IndexableResultSet,
@@ -50,7 +54,7 @@ const jsonObjectSchema: z.ZodSchema<JsonObject> = z.lazy(() => {
export type RouterOptions = {
engine: SearchEngine;
types: Record<string, DocumentTypeInfo>;
permissions: PermissionEvaluator;
permissions: PermissionEvaluator | PermissionAuthorizer;
config: Config;
logger: Logger;
};
@@ -71,8 +75,23 @@ export async function createRouter(
pageCursor: z.string().optional(),
});
let permissionEvaluator: PermissionEvaluator;
if (!permissions.hasOwnProperty('query')) {
logger.warn(
'PermissionAuthorizer is deprecated. Please use PermissionEvaluator instead of PermissionAuthorizer in search.ts',
);
permissionEvaluator = toPermissionEvaluator(permissions);
} else {
permissionEvaluator = permissions as PermissionEvaluator;
}
const engine = config.getOptionalBoolean('permission.enabled')
? new AuthorizedSearchEngine(inputEngine, types, permissions, config)
? new AuthorizedSearchEngine(
inputEngine,
types,
permissionEvaluator,
config,
)
: inputEngine;
const filterResultSet = ({ results, ...resultSet }: SearchResultSet) => ({