diff --git a/plugins/catalog-backend/src/permissions/rules/util.ts b/plugins/catalog-backend/src/permissions/rules/util.ts index 37544a14f8..ea25e115d2 100644 --- a/plugins/catalog-backend/src/permissions/rules/util.ts +++ b/plugins/catalog-backend/src/permissions/rules/util.ts @@ -16,6 +16,7 @@ import { Entity } from '@backstage/catalog-model'; import { RESOURCE_TYPE_CATALOG_ENTITY } from '@backstage/plugin-catalog-common'; +import { PermissionRuleParams } from '@backstage/plugin-permission-common'; import { makeCreatePermissionRule, PermissionRule, @@ -30,7 +31,7 @@ import { EntitiesSearchFilter } from '../../catalog/types'; * @alpha */ export type CatalogPermissionRule< - TParams extends Record = Record, + TParams extends PermissionRuleParams = PermissionRuleParams, > = PermissionRule; /** diff --git a/plugins/permission-common/package.json b/plugins/permission-common/package.json index fcf1c47ea6..4c31ecc673 100644 --- a/plugins/permission-common/package.json +++ b/plugins/permission-common/package.json @@ -43,6 +43,7 @@ "dependencies": { "@backstage/config": "workspace:^", "@backstage/errors": "workspace:^", + "@backstage/types": "workspace:^", "cross-fetch": "^3.1.5", "uuid": "^8.0.0", "zod": "^3.11.6" diff --git a/plugins/permission-common/src/PermissionClient.ts b/plugins/permission-common/src/PermissionClient.ts index 7b429dc46f..c5f56be159 100644 --- a/plugins/permission-common/src/PermissionClient.ts +++ b/plugins/permission-common/src/PermissionClient.ts @@ -41,7 +41,7 @@ const permissionCriteriaSchema: z.ZodSchema< .object({ rule: z.string(), resourceType: z.string(), - params: z.record(z.unknown()), + params: z.record(z.any()), }) .or(z.object({ anyOf: z.array(permissionCriteriaSchema).nonempty() })) .or(z.object({ allOf: z.array(permissionCriteriaSchema).nonempty() })) diff --git a/plugins/permission-common/src/types/api.ts b/plugins/permission-common/src/types/api.ts index 70b9e902b8..ca915a65da 100644 --- a/plugins/permission-common/src/types/api.ts +++ b/plugins/permission-common/src/types/api.ts @@ -14,6 +14,7 @@ * limitations under the License. */ +import { JsonPrimitive } from '@backstage/types'; import { ResourcePermission } from '.'; import { Permission } from './permission'; @@ -101,7 +102,7 @@ export type PolicyDecision = */ export type PermissionCondition< TResourceType extends string = string, - TParams extends Record = Record, + TParams extends PermissionRuleParams = PermissionRuleParams, > = { resourceType: TResourceType; rule: string; @@ -148,6 +149,16 @@ export type PermissionCriteria = | NotCriteria | TQuery; +/** + * A parameter to a permission rule. + */ +export type PermissionRuleParam = undefined | JsonPrimitive | JsonPrimitive[]; + +/** + * Types that can be used as parameters to permission rules. + */ +export type PermissionRuleParams = Record; + /** * An individual request sent to the permission backend. * @public diff --git a/plugins/permission-common/src/types/index.ts b/plugins/permission-common/src/types/index.ts index f244a70b1a..5702f47c1c 100644 --- a/plugins/permission-common/src/types/index.ts +++ b/plugins/permission-common/src/types/index.ts @@ -33,6 +33,8 @@ export type { PolicyDecision, PermissionCondition, PermissionCriteria, + PermissionRuleParam, + PermissionRuleParams, AllOfCriteria, AnyOfCriteria, NotCriteria, diff --git a/plugins/permission-node/src/integration/createConditionExports.test.ts b/plugins/permission-node/src/integration/createConditionExports.test.ts index a989206fdd..59639f5119 100644 --- a/plugins/permission-node/src/integration/createConditionExports.test.ts +++ b/plugins/permission-node/src/integration/createConditionExports.test.ts @@ -46,7 +46,7 @@ const testIntegration = () => description: 'Test rule 2', resourceType: 'test-resource', schema: z.object({ - foo: z.object({}), + foo: z.string(), }), apply: (_resource: any) => false, toQuery: params => ({ @@ -76,11 +76,11 @@ describe('createConditionExports', () => { }, }); - expect(conditions.testRule2({ foo: { baz: 'quux' } })).toEqual({ + expect(conditions.testRule2({ foo: 'baz' })).toEqual({ rule: 'testRule2', resourceType: 'test-resource', params: { - foo: { baz: 'quux' }, + foo: 'baz', }, }); }); diff --git a/plugins/permission-node/src/integration/createConditionFactory.ts b/plugins/permission-node/src/integration/createConditionFactory.ts index 5b499ab512..8edeb6230f 100644 --- a/plugins/permission-node/src/integration/createConditionFactory.ts +++ b/plugins/permission-node/src/integration/createConditionFactory.ts @@ -14,7 +14,10 @@ * limitations under the License. */ -import { PermissionCondition } from '@backstage/plugin-permission-common'; +import { + PermissionCondition, + PermissionRuleParams, +} from '@backstage/plugin-permission-common'; import { PermissionRule } from '../types'; /** @@ -34,7 +37,10 @@ import { PermissionRule } from '../types'; * @public */ export const createConditionFactory = - >( + < + TResourceType extends string, + TParams extends PermissionRuleParams = PermissionRuleParams, + >( rule: PermissionRule, ) => (params: TParams): PermissionCondition => ({ diff --git a/plugins/permission-node/src/integration/createConditionTransformer.test.ts b/plugins/permission-node/src/integration/createConditionTransformer.test.ts index 5021b7766d..0544ff3ef8 100644 --- a/plugins/permission-node/src/integration/createConditionTransformer.test.ts +++ b/plugins/permission-node/src/integration/createConditionTransformer.test.ts @@ -39,10 +39,10 @@ const transformConditions = createConditionTransformer([ description: 'Test rule 2', resourceType: 'test-resource', schema: z.object({ - foo: z.object({}), + foo: z.string(), }), apply: jest.fn(), - toQuery: jest.fn(({ foo }) => `test-rule-2:${JSON.stringify(foo)}`), + toQuery: jest.fn(({ foo }) => `test-rule-2:${foo}`), }), ]); @@ -67,10 +67,10 @@ describe('createConditionTransformer', () => { rule: 'test-rule-2', resourceType: 'test-resource', params: { - foo: { foo: 0 }, + foo: '0', }, }, - expectedResult: 'test-rule-2:{"foo":0}', + expectedResult: 'test-rule-2:0', }, { conditions: { @@ -87,13 +87,13 @@ describe('createConditionTransformer', () => { rule: 'test-rule-2', resourceType: 'test-resource', params: { - foo: {}, + foo: 'b', }, }, ], }, expectedResult: { - anyOf: ['test-rule-1:a/1', 'test-rule-2:{}'], + anyOf: ['test-rule-1:a/1', 'test-rule-2:b'], }, }, { @@ -111,13 +111,13 @@ describe('createConditionTransformer', () => { rule: 'test-rule-2', resourceType: 'test-resource', params: { - foo: {}, + foo: 'b', }, }, ], }, expectedResult: { - allOf: ['test-rule-1:a/1', 'test-rule-2:{}'], + allOf: ['test-rule-1:a/1', 'test-rule-2:b'], }, }, { @@ -126,12 +126,12 @@ describe('createConditionTransformer', () => { rule: 'test-rule-2', resourceType: 'test-resource', params: { - foo: {}, + foo: 'a', }, }, }, expectedResult: { - not: 'test-rule-2:{}', + not: 'test-rule-2:a', }, }, { @@ -151,7 +151,7 @@ describe('createConditionTransformer', () => { rule: 'test-rule-2', resourceType: 'test-resource', params: { - foo: {}, + foo: 'b', }, }, ], @@ -171,9 +171,7 @@ describe('createConditionTransformer', () => { rule: 'test-rule-2', resourceType: 'test-resource', params: { - foo: { - c: 3, - }, + foo: 'c', }, }, ], @@ -184,11 +182,11 @@ describe('createConditionTransformer', () => { expectedResult: { allOf: [ { - anyOf: ['test-rule-1:a/1', 'test-rule-2:{}'], + anyOf: ['test-rule-1:a/1', 'test-rule-2:b'], }, { not: { - allOf: ['test-rule-1:b/2', 'test-rule-2:{"c":3}'], + allOf: ['test-rule-1:b/2', 'test-rule-2:c'], }, }, ], @@ -211,9 +209,7 @@ describe('createConditionTransformer', () => { rule: 'test-rule-2', resourceType: 'test-resource', params: { - foo: { - b: 2, - }, + foo: 'b', }, }, ], @@ -234,9 +230,7 @@ describe('createConditionTransformer', () => { rule: 'test-rule-2', resourceType: 'test-resource', params: { - foo: { - d: 4, - }, + foo: 'd', }, }, }, @@ -248,11 +242,11 @@ describe('createConditionTransformer', () => { expectedResult: { allOf: [ { - anyOf: ['test-rule-1:a/1', 'test-rule-2:{"b":2}'], + anyOf: ['test-rule-1:a/1', 'test-rule-2:b'], }, { not: { - allOf: ['test-rule-1:c/3', { not: 'test-rule-2:{"d":4}' }], + allOf: ['test-rule-1:c/3', { not: 'test-rule-2:d' }], }, }, ], diff --git a/plugins/permission-node/src/integration/createPermissionIntegrationRouter.test.ts b/plugins/permission-node/src/integration/createPermissionIntegrationRouter.test.ts index 99e0da8287..adfa57b863 100644 --- a/plugins/permission-node/src/integration/createPermissionIntegrationRouter.test.ts +++ b/plugins/permission-node/src/integration/createPermissionIntegrationRouter.test.ts @@ -53,7 +53,7 @@ const testRule2 = createPermissionRule({ description: 'Test rule 2', resourceType: 'test-resource', schema: z.object({ - foo: z.object({}).describe('foo'), + foo: z.string().describe('foo'), }), apply: (_resource: any, _foo) => false, toQuery: _foo => ({}), @@ -105,7 +105,7 @@ describe('createPermissionIntegrationRouter', () => { { rule: 'test-rule-2', resourceType: 'test-resource', - params: { foo: {} }, + params: { foo: 'b' }, }, ], }, @@ -114,7 +114,7 @@ describe('createPermissionIntegrationRouter', () => { rule: 'test-rule-2', resourceType: 'test-resource', params: { - foo: {}, + foo: 'c', }, }, }, @@ -134,7 +134,7 @@ describe('createPermissionIntegrationRouter', () => { rule: 'test-rule-2', resourceType: 'test-resource', params: { - foo: {}, + foo: 'b', }, }, ], @@ -154,7 +154,7 @@ describe('createPermissionIntegrationRouter', () => { rule: 'test-rule-2', resourceType: 'test-resource', params: { - foo: { c: 3 }, + foo: 'c', }, }, ], @@ -192,7 +192,7 @@ describe('createPermissionIntegrationRouter', () => { rule: 'test-rule-2', resourceType: 'test-resource', params: { - foo: { foo: 0 }, + foo: 'a', }, }, { @@ -208,7 +208,7 @@ describe('createPermissionIntegrationRouter', () => { { rule: 'test-rule-2', resourceType: 'test-resource', - params: { foo: {} }, + params: { foo: 'b' }, }, ], }, @@ -228,7 +228,7 @@ describe('createPermissionIntegrationRouter', () => { rule: 'test-rule-2', resourceType: 'test-resource', params: { - foo: { b: 2 }, + foo: 'b', }, }, ], @@ -249,7 +249,7 @@ describe('createPermissionIntegrationRouter', () => { rule: 'test-rule-2', resourceType: 'test-resource', params: { - foo: { d: 4 }, + foo: 'd', }, }, }, @@ -310,7 +310,7 @@ describe('createPermissionIntegrationRouter', () => { rule: 'test-rule-2', resourceType: 'test-resource', params: { - foo: {}, + foo: 'b', }, }, }, @@ -338,7 +338,7 @@ describe('createPermissionIntegrationRouter', () => { rule: 'test-rule-2', resourceType: 'test-resource', params: { - foo: {}, + foo: 'c', }, }, }, @@ -361,7 +361,7 @@ describe('createPermissionIntegrationRouter', () => { rule: 'test-rule-2', resourceType: 'test-resource', params: { - foo: {}, + foo: 'd', }, }, ], @@ -628,10 +628,8 @@ describe('createPermissionIntegrationRouter', () => { additionalProperties: false, properties: { foo: { - additionalProperties: false, description: 'foo', - properties: {}, - type: 'object', + type: 'string', }, }, required: ['foo'], diff --git a/plugins/permission-node/src/integration/createPermissionIntegrationRouter.ts b/plugins/permission-node/src/integration/createPermissionIntegrationRouter.ts index 7f355467c3..a01006c194 100644 --- a/plugins/permission-node/src/integration/createPermissionIntegrationRouter.ts +++ b/plugins/permission-node/src/integration/createPermissionIntegrationRouter.ts @@ -46,7 +46,7 @@ const permissionCriteriaSchema: z.ZodSchema< z.object({ rule: z.string(), resourceType: z.string(), - params: z.record(z.unknown()), + params: z.record(z.any()), }), ]), ); diff --git a/plugins/permission-node/src/integration/createPermissionRule.ts b/plugins/permission-node/src/integration/createPermissionRule.ts index ef84a5a26f..ea2e37a671 100644 --- a/plugins/permission-node/src/integration/createPermissionRule.ts +++ b/plugins/permission-node/src/integration/createPermissionRule.ts @@ -14,6 +14,7 @@ * limitations under the License. */ +import { PermissionRuleParams } from '@backstage/plugin-permission-common'; import { PermissionRule } from '../types'; /** @@ -25,7 +26,7 @@ export const createPermissionRule = < TResource, TQuery, TResourceType extends string, - TParams extends Record, + TParams extends PermissionRuleParams = PermissionRuleParams, >( rule: PermissionRule, ) => rule; @@ -40,7 +41,7 @@ export const createPermissionRule = < */ export const makeCreatePermissionRule = () => - >( + ( rule: PermissionRule, ) => createPermissionRule(rule); diff --git a/plugins/permission-node/src/types.ts b/plugins/permission-node/src/types.ts index 6d39d7f922..34ff52391a 100644 --- a/plugins/permission-node/src/types.ts +++ b/plugins/permission-node/src/types.ts @@ -14,7 +14,10 @@ * limitations under the License. */ -import type { PermissionCriteria } from '@backstage/plugin-permission-common'; +import type { + PermissionCriteria, + PermissionRuleParams, +} from '@backstage/plugin-permission-common'; import { z } from 'zod'; /** @@ -45,7 +48,7 @@ export type PermissionRule< TResource, TQuery, TResourceType extends string, - TParams extends Record = Record, + TParams extends PermissionRuleParams = PermissionRuleParams, TSchema extends z.ZodType = z.ZodObject<{ // Parameters can be optional, however we we want to make sure that the // parameters are always present in the schema, even if they are undefined. diff --git a/yarn.lock b/yarn.lock index bef0e188c6..168ca96586 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6334,6 +6334,7 @@ __metadata: "@backstage/cli": "workspace:^" "@backstage/config": "workspace:^" "@backstage/errors": "workspace:^" + "@backstage/types": "workspace:^" cross-fetch: ^3.1.5 msw: ^0.47.0 uuid: ^8.0.0