diff --git a/plugins/permission-backend/src/service/PermissionIntegrationClient.test.ts b/plugins/permission-backend/src/service/PermissionIntegrationClient.test.ts index 79f604e948..57beda9c1f 100644 --- a/plugins/permission-backend/src/service/PermissionIntegrationClient.test.ts +++ b/plugins/permission-backend/src/service/PermissionIntegrationClient.test.ts @@ -275,7 +275,11 @@ describe('PermissionIntegrationClient', () => { router.use( createPermissionIntegrationRouter({ resourceType: 'test-resource', - getResource: async resourceRef => ({ id: resourceRef }), + getResources: async resourceRefs => + resourceRefs.reduce((acc, ref) => { + acc[ref] = { id: ref }; + return acc; + }, {} as Record), rules: [ { name: 'RULE_1', diff --git a/plugins/permission-node/api-report.md b/plugins/permission-node/api-report.md index 9e0d521cd3..e90a1f2677 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[]; - getResource: (resourceRef: string) => Promise; + getResources: (resourceRefs: string[]) => Promise>; }) => express.Router; // @public diff --git a/plugins/permission-node/src/integration/createPermissionIntegrationRouter.test.ts b/plugins/permission-node/src/integration/createPermissionIntegrationRouter.test.ts index c7c48ae9fc..37495ae76e 100644 --- a/plugins/permission-node/src/integration/createPermissionIntegrationRouter.test.ts +++ b/plugins/permission-node/src/integration/createPermissionIntegrationRouter.test.ts @@ -19,9 +19,14 @@ import express, { Express, Router } from 'express'; import request, { Response } from 'supertest'; import { createPermissionIntegrationRouter } from './createPermissionIntegrationRouter'; -const mockGetResource: jest.MockedFunction< - Parameters[0]['getResource'] -> = jest.fn(async resourceRef => ({ id: resourceRef })); +const mockGetResources: jest.MockedFunction< + Parameters[0]['getResources'] +> = jest.fn(async resourceRefs => + resourceRefs.reduce( + (acc, resourceRef) => ({ ...acc, [resourceRef]: { id: resourceRef } }), + {}, + ), +); const testRule1 = { name: 'test-rule-1', @@ -46,7 +51,7 @@ describe('createPermissionIntegrationRouter', () => { beforeAll(() => { router = createPermissionIntegrationRouter({ resourceType: 'test-resource', - getResource: mockGetResource, + getResources: mockGetResources, rules: [testRule1, testRule2], }); @@ -214,6 +219,15 @@ describe('createPermissionIntegrationRouter', () => { { id: '567', result: AuthorizeResult.ALLOW }, ]); }); + + it('calls getResources for all required resources at once', () => { + expect(mockGetResources).toHaveBeenCalledWith([ + 'default:test/resource-1', + 'default:test/resource-2', + 'default:test/resource-3', + 'default:test/resource-4', + ]); + }); }); it('returns 400 when called with incorrect resource type', async () => { @@ -237,7 +251,7 @@ describe('createPermissionIntegrationRouter', () => { }); it('returns 200/DENY when resource is not found', async () => { - mockGetResource.mockReturnValueOnce(Promise.resolve(undefined)); + mockGetResources.mockReturnValueOnce(Promise.resolve({})); 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 919af47c02..c15f3cc80b 100644 --- a/plugins/permission-node/src/integration/createPermissionIntegrationRouter.ts +++ b/plugins/permission-node/src/integration/createPermissionIntegrationRouter.ts @@ -156,9 +156,9 @@ const applyConditions = ( export const createPermissionIntegrationRouter = (options: { resourceType: string; rules: PermissionRule[]; - getResource: (resourceRef: string) => Promise; + getResources: (resourceRefs: string[]) => Promise>; }): express.Router => { - const { resourceType, rules, getResource } = options; + const { resourceType, rules, getResources } = options; const router = Router(); const getRule = createGetRule(rules); @@ -188,12 +188,9 @@ export const createPermissionIntegrationRouter = (options: { assertValidResourceTypes(body); - const resources = {} as Record; - for (const { resourceRef } of body) { - if (!resources[resourceRef]) { - resources[resourceRef] = await getResource(resourceRef); - } - } + const resources = await getResources( + Array.from(new Set(body.map(({ resourceRef }) => resourceRef))), + ); return res.status(200).json( body.map(request => ({