From 8e72b573aa0b7b9e6fbd43de137b48614aac4bf7 Mon Sep 17 00:00:00 2001 From: MT Lewis Date: Mon, 20 Dec 2021 17:17:20 +0000 Subject: [PATCH] permission-node: switch to array for getResources return value Signed-off-by: MT Lewis --- .changeset/shiny-bugs-beam.md | 2 +- .../service/PermissionIntegrationClient.test.ts | 7 +++---- plugins/permission-node/api-report.md | 2 +- .../createPermissionIntegrationRouter.test.ts | 9 ++++----- .../createPermissionIntegrationRouter.ts | 14 +++++++++++--- 5 files changed, 20 insertions(+), 14 deletions(-) diff --git a/.changeset/shiny-bugs-beam.md b/.changeset/shiny-bugs-beam.md index bc50486526..b16c8d6729 100644 --- a/.changeset/shiny-bugs-beam.md +++ b/.changeset/shiny-bugs-beam.md @@ -8,4 +8,4 @@ Optimizations to the integration between the permission backend and plugin-backe - The permission backend already supported batched requests to authorize, but would make calls to plugin backend to apply conditions serially. Now, after applying the policy for each authorization request, the permission backend makes a single batched /apply-conditions request to each plugin backend referenced in policy decisions. - The `getResource` method accepted by `createPermissionIntegrationRouter` has been replaced with `getResources`, to allow consumers to make batch requests to upstream data stores. When /apply-conditions is called with a batch of requests, all required resources are requested in a single invocation of `getResources`. -Plugin owners consuming `createPermissionIntegrationRouter` should replace the `getResource` method in the options with a `getResources` method, accepting an array of resourceRefs, and returning a record object mapping those resourceRefs to resources (if present). +Plugin owners consuming `createPermissionIntegrationRouter` should replace the `getResource` method in the options with a `getResources` method, accepting an array of resourceRefs, and returning an array of the corresponding resources. diff --git a/plugins/permission-backend/src/service/PermissionIntegrationClient.test.ts b/plugins/permission-backend/src/service/PermissionIntegrationClient.test.ts index 57beda9c1f..4697277377 100644 --- a/plugins/permission-backend/src/service/PermissionIntegrationClient.test.ts +++ b/plugins/permission-backend/src/service/PermissionIntegrationClient.test.ts @@ -276,10 +276,9 @@ describe('PermissionIntegrationClient', () => { createPermissionIntegrationRouter({ resourceType: 'test-resource', getResources: async resourceRefs => - resourceRefs.reduce((acc, ref) => { - acc[ref] = { id: ref }; - return acc; - }, {} as Record), + resourceRefs.map(resourceRef => ({ + id: resourceRef, + })), rules: [ { name: 'RULE_1', diff --git a/plugins/permission-node/api-report.md b/plugins/permission-node/api-report.md index e90a1f2677..7023369306 100644 --- a/plugins/permission-node/api-report.md +++ b/plugins/permission-node/api-report.md @@ -97,7 +97,7 @@ export const createConditionTransformer: < export const createPermissionIntegrationRouter: (options: { resourceType: string; rules: PermissionRule[]; - getResources: (resourceRefs: string[]) => Promise>; + getResources: (resourceRefs: string[]) => Promise<(TResource | undefined)[]>; }) => express.Router; // @public diff --git a/plugins/permission-node/src/integration/createPermissionIntegrationRouter.test.ts b/plugins/permission-node/src/integration/createPermissionIntegrationRouter.test.ts index 37495ae76e..2e911b7cae 100644 --- a/plugins/permission-node/src/integration/createPermissionIntegrationRouter.test.ts +++ b/plugins/permission-node/src/integration/createPermissionIntegrationRouter.test.ts @@ -22,10 +22,7 @@ import { createPermissionIntegrationRouter } from './createPermissionIntegration const mockGetResources: jest.MockedFunction< Parameters[0]['getResources'] > = jest.fn(async resourceRefs => - resourceRefs.reduce( - (acc, resourceRef) => ({ ...acc, [resourceRef]: { id: resourceRef } }), - {}, - ), + resourceRefs.map(resourceRef => ({ id: resourceRef })), ); const testRule1 = { @@ -251,7 +248,9 @@ describe('createPermissionIntegrationRouter', () => { }); it('returns 200/DENY when resource is not found', async () => { - mockGetResources.mockReturnValueOnce(Promise.resolve({})); + mockGetResources.mockImplementationOnce(async resourceRefs => + resourceRefs.map(() => undefined), + ); const response = await request(app) .post('/.well-known/backstage/permissions/apply-conditions') diff --git a/plugins/permission-node/src/integration/createPermissionIntegrationRouter.ts b/plugins/permission-node/src/integration/createPermissionIntegrationRouter.ts index c15f3cc80b..0fdbab7a9f 100644 --- a/plugins/permission-node/src/integration/createPermissionIntegrationRouter.ts +++ b/plugins/permission-node/src/integration/createPermissionIntegrationRouter.ts @@ -156,7 +156,9 @@ const applyConditions = ( export const createPermissionIntegrationRouter = (options: { resourceType: string; rules: PermissionRule[]; - getResources: (resourceRefs: string[]) => Promise>; + getResources: ( + resourceRefs: string[], + ) => Promise>; }): express.Router => { const { resourceType, rules, getResources } = options; const router = Router(); @@ -188,9 +190,15 @@ export const createPermissionIntegrationRouter = (options: { assertValidResourceTypes(body); - const resources = await getResources( - Array.from(new Set(body.map(({ resourceRef }) => resourceRef))), + const resourceRefs = Array.from( + new Set(body.map(({ resourceRef }) => resourceRef)), ); + const resourceArray = await getResources(resourceRefs); + const resources = resourceRefs.reduce((acc, resourceRef, index) => { + acc[resourceRef] = resourceArray[index]; + + return acc; + }, {} as Record); return res.status(200).json( body.map(request => ({