From 8fe84eadaf5a414240aac2ba7d57141a4a5122a5 Mon Sep 17 00:00:00 2001 From: MT Lewis Date: Thu, 6 Jan 2022 16:46:17 +0000 Subject: [PATCH 1/5] catalog-backend: add type parameter to CatalogPermissionRule type Previously the CatalogPermissionRule type had a fixed type of unknown[] for the parameters expected in the `apply` and `toQuery` methods. This meant that conditions generated for these rules would always have unknown parameters too, which makes using them in policies much more difficult. To address this, this commit introduces a mandatory type parameter for CatalogPermissionRule which is expected to be set to a tuple corresponding to the expected parameters. Signed-off-by: MT Lewis --- plugins/catalog-backend/api-report.md | 23 +++++++++++-------- .../permissions/rules/createPropertyRule.ts | 2 +- .../src/permissions/rules/hasAnnotation.ts | 2 +- .../src/permissions/rules/hasLabel.ts | 2 +- .../src/permissions/rules/isEntityKind.ts | 2 +- .../src/permissions/rules/isEntityOwner.ts | 2 +- .../catalog-backend/src/permissions/types.ts | 5 ++-- .../src/service/NextCatalogBuilder.ts | 4 ++-- .../catalog-backend/src/service/NextRouter.ts | 2 +- 9 files changed, 24 insertions(+), 20 deletions(-) diff --git a/plugins/catalog-backend/api-report.md b/plugins/catalog-backend/api-report.md index 6d7834001a..33f0fab18e 100644 --- a/plugins/catalog-backend/api-report.md +++ b/plugins/catalog-backend/api-report.md @@ -307,9 +307,10 @@ export type CatalogEnvironment = { }; // @public -export type CatalogPermissionRule = PermissionRule< +export type CatalogPermissionRule = PermissionRule< Entity, - EntitiesSearchFilter + EntitiesSearchFilter, + TParams >; // Warning: (ae-missing-release-tag) "CatalogProcessingEngine" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -1311,7 +1312,9 @@ export class NextCatalogBuilder { addEntityPolicy(...policies: EntityPolicy[]): NextCatalogBuilder; // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen addEntityProvider(...providers: EntityProvider[]): NextCatalogBuilder; - addPermissionRules(...permissionRules: CatalogPermissionRule[]): void; + addPermissionRules( + ...permissionRules: CatalogPermissionRule[] + ): void; // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen addProcessor(...processors: CatalogProcessor[]): NextCatalogBuilder; build(): Promise<{ @@ -1359,7 +1362,7 @@ export interface NextRouterOptions { // (undocumented) logger: Logger_2; // (undocumented) - permissionRules?: CatalogPermissionRule[]; + permissionRules?: CatalogPermissionRule[]; // (undocumented) refreshService?: RefreshService; } @@ -1394,12 +1397,12 @@ export function parseEntityYaml( // @public export const permissionRules: { - hasAnnotation: CatalogPermissionRule; - hasLabel: CatalogPermissionRule; - hasMetadata: CatalogPermissionRule; - hasSpec: CatalogPermissionRule; - isEntityKind: CatalogPermissionRule; - isEntityOwner: CatalogPermissionRule; + hasAnnotation: CatalogPermissionRule<[annotation: string]>; + hasLabel: CatalogPermissionRule<[label: string]>; + hasMetadata: CatalogPermissionRule<[key: string, value?: string | undefined]>; + hasSpec: CatalogPermissionRule<[key: string, value?: string | undefined]>; + isEntityKind: CatalogPermissionRule<[kinds: string[]]>; + isEntityOwner: CatalogPermissionRule<[claims: string[]]>; }; // Warning: (ae-missing-release-tag) "PlaceholderProcessor" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) diff --git a/plugins/catalog-backend/src/permissions/rules/createPropertyRule.ts b/plugins/catalog-backend/src/permissions/rules/createPropertyRule.ts index 92e53f930f..254eb164da 100644 --- a/plugins/catalog-backend/src/permissions/rules/createPropertyRule.ts +++ b/plugins/catalog-backend/src/permissions/rules/createPropertyRule.ts @@ -21,7 +21,7 @@ import { get } from 'lodash'; export function createPropertyRule( propertyType: 'metadata' | 'spec', -): CatalogPermissionRule { +): CatalogPermissionRule<[key: string, value?: string]> { return { name: `HAS_${propertyType.toUpperCase()}`, description: `Allow entities which have the specified ${propertyType} subfield.`, diff --git a/plugins/catalog-backend/src/permissions/rules/hasAnnotation.ts b/plugins/catalog-backend/src/permissions/rules/hasAnnotation.ts index 57ded3d779..baab28d838 100644 --- a/plugins/catalog-backend/src/permissions/rules/hasAnnotation.ts +++ b/plugins/catalog-backend/src/permissions/rules/hasAnnotation.ts @@ -23,7 +23,7 @@ import { CatalogPermissionRule } from '../types'; * annotation on a given entity. * @public */ -export const hasAnnotation: CatalogPermissionRule = { +export const hasAnnotation: CatalogPermissionRule<[annotation: string]> = { name: 'HAS_ANNOTATION', description: 'Allow entities which are annotated with the specified annotation', diff --git a/plugins/catalog-backend/src/permissions/rules/hasLabel.ts b/plugins/catalog-backend/src/permissions/rules/hasLabel.ts index f93c5aeae6..a790f1441f 100644 --- a/plugins/catalog-backend/src/permissions/rules/hasLabel.ts +++ b/plugins/catalog-backend/src/permissions/rules/hasLabel.ts @@ -23,7 +23,7 @@ import { CatalogPermissionRule } from '../types'; * label in its metadata. * @public */ -export const hasLabel: CatalogPermissionRule = { +export const hasLabel: CatalogPermissionRule<[label: string]> = { name: 'HAS_LABEL', description: 'Allow entities which have the specified label metadata.', apply: (resource: Entity, label: string) => diff --git a/plugins/catalog-backend/src/permissions/rules/isEntityKind.ts b/plugins/catalog-backend/src/permissions/rules/isEntityKind.ts index 64fcf7482d..024188939f 100644 --- a/plugins/catalog-backend/src/permissions/rules/isEntityKind.ts +++ b/plugins/catalog-backend/src/permissions/rules/isEntityKind.ts @@ -22,7 +22,7 @@ import { CatalogPermissionRule } from '../types'; * kind. * @public */ -export const isEntityKind: CatalogPermissionRule = { +export const isEntityKind: CatalogPermissionRule<[kinds: string[]]> = { name: 'IS_ENTITY_KIND', description: 'Allow entities with the specified kind', apply(resource: Entity, kinds: string[]) { diff --git a/plugins/catalog-backend/src/permissions/rules/isEntityOwner.ts b/plugins/catalog-backend/src/permissions/rules/isEntityOwner.ts index e89159e6b4..e450cdf721 100644 --- a/plugins/catalog-backend/src/permissions/rules/isEntityOwner.ts +++ b/plugins/catalog-backend/src/permissions/rules/isEntityOwner.ts @@ -27,7 +27,7 @@ import { CatalogPermissionRule } from '../types'; * owner. * @public */ -export const isEntityOwner: CatalogPermissionRule = { +export const isEntityOwner: CatalogPermissionRule<[claims: string[]]> = { name: 'IS_ENTITY_OWNER', description: 'Allow entities owned by the current user', apply: (resource: Entity, claims: string[]) => { diff --git a/plugins/catalog-backend/src/permissions/types.ts b/plugins/catalog-backend/src/permissions/types.ts index cc2b8f4d45..4a0d9dc1fc 100644 --- a/plugins/catalog-backend/src/permissions/types.ts +++ b/plugins/catalog-backend/src/permissions/types.ts @@ -24,7 +24,8 @@ import { EntitiesSearchFilter } from '../catalog/types'; * * @public */ -export type CatalogPermissionRule = PermissionRule< +export type CatalogPermissionRule = PermissionRule< Entity, - EntitiesSearchFilter + EntitiesSearchFilter, + TParams >; diff --git a/plugins/catalog-backend/src/service/NextCatalogBuilder.ts b/plugins/catalog-backend/src/service/NextCatalogBuilder.ts index 1dcb632e64..e707423670 100644 --- a/plugins/catalog-backend/src/service/NextCatalogBuilder.ts +++ b/plugins/catalog-backend/src/service/NextCatalogBuilder.ts @@ -130,7 +130,7 @@ export class NextCatalogBuilder { maxSeconds: 150, }); private locationAnalyzer: LocationAnalyzer | undefined = undefined; - private permissionRules: CatalogPermissionRule[]; + private permissionRules: CatalogPermissionRule[]; constructor(env: CatalogEnvironment) { this.env = env; @@ -331,7 +331,7 @@ export class NextCatalogBuilder { * * @param permissionRules - Additional permission rules */ - addPermissionRules(...permissionRules: CatalogPermissionRule[]) { + addPermissionRules(...permissionRules: CatalogPermissionRule[]) { this.permissionRules.push(...permissionRules); } diff --git a/plugins/catalog-backend/src/service/NextRouter.ts b/plugins/catalog-backend/src/service/NextRouter.ts index 7aae564a45..948424ec88 100644 --- a/plugins/catalog-backend/src/service/NextRouter.ts +++ b/plugins/catalog-backend/src/service/NextRouter.ts @@ -49,7 +49,7 @@ export interface NextRouterOptions { refreshService?: RefreshService; logger: Logger; config: Config; - permissionRules?: CatalogPermissionRule[]; + permissionRules?: CatalogPermissionRule[]; } export async function createNextRouter( From 9db1b86f3244579c0e5b1f5aced5371aabf08c59 Mon Sep 17 00:00:00 2001 From: MT Lewis Date: Fri, 7 Jan 2022 11:26:54 +0000 Subject: [PATCH 2/5] permission-node: add helpers for creating PermissionRules Signed-off-by: MT Lewis --- .changeset/healthy-toes-laugh.md | 5 +++ plugins/permission-node/api-report.md | 16 +++++++ .../src/integration/createPermissionRule.ts | 45 +++++++++++++++++++ .../permission-node/src/integration/index.ts | 1 + 4 files changed, 67 insertions(+) create mode 100644 .changeset/healthy-toes-laugh.md create mode 100644 plugins/permission-node/src/integration/createPermissionRule.ts diff --git a/.changeset/healthy-toes-laugh.md b/.changeset/healthy-toes-laugh.md new file mode 100644 index 0000000000..e0db38e5e3 --- /dev/null +++ b/.changeset/healthy-toes-laugh.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-permission-node': patch +--- + +Add helpers for creating PermissionRules with inferred types diff --git a/plugins/permission-node/api-report.md b/plugins/permission-node/api-report.md index 25a8be06c8..e743f18311 100644 --- a/plugins/permission-node/api-report.md +++ b/plugins/permission-node/api-report.md @@ -95,6 +95,22 @@ export const createPermissionIntegrationRouter: (options: { getResource: (resourceRef: string) => Promise; }) => Router; +// @public +export const createPermissionRule: < + TResource, + TQuery, + TParams extends unknown[], +>( + rule: PermissionRule, +) => PermissionRule; + +// @public +export const makeCreatePermissionRule: () => < + TParams extends unknown[], +>( + rule: PermissionRule, +) => PermissionRule; + // @public export interface PermissionPolicy { // (undocumented) diff --git a/plugins/permission-node/src/integration/createPermissionRule.ts b/plugins/permission-node/src/integration/createPermissionRule.ts new file mode 100644 index 0000000000..f3a0519a70 --- /dev/null +++ b/plugins/permission-node/src/integration/createPermissionRule.ts @@ -0,0 +1,45 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { PermissionRule } from '../types'; + +/** + * Helper function to ensure that {@link PermissionRule} definitions are typed correctly. + * + * @public + */ +export const createPermissionRule = < + TResource, + TQuery, + TParams extends unknown[], +>( + rule: PermissionRule, +) => rule; + +/** + * Helper for making plugin-specific createPermissionRule functions, that have + * the TResource and TQuery type parameters populated but infer the params from + * the supplied rule. This helps ensure that rules created for this plugin use + * consistent types for the resource and query. + * + * @public + */ +export const makeCreatePermissionRule = + () => + ( + rule: PermissionRule, + ) => + createPermissionRule(rule); diff --git a/plugins/permission-node/src/integration/index.ts b/plugins/permission-node/src/integration/index.ts index f070d57c8f..978342e4ed 100644 --- a/plugins/permission-node/src/integration/index.ts +++ b/plugins/permission-node/src/integration/index.ts @@ -18,3 +18,4 @@ export * from './createConditionFactory'; export * from './createConditionExports'; export * from './createConditionTransformer'; export * from './createPermissionIntegrationRouter'; +export * from './createPermissionRule'; From 82cfdc8d02e5595d89604b698e10c9bdb52dadfb Mon Sep 17 00:00:00 2001 From: MT Lewis Date: Fri, 7 Jan 2022 11:47:14 +0000 Subject: [PATCH 3/5] catalog-backend: use createPermissionRule helper instead of manually typing rules Signed-off-by: MT Lewis --- plugins/catalog-backend/api-report.md | 33 +++++++++++++++---- .../permissions/rules/createPropertyRule.ts | 16 ++++----- .../src/permissions/rules/hasAnnotation.ts | 9 +++-- .../src/permissions/rules/hasLabel.ts | 9 +++-- .../src/permissions/rules/index.ts | 2 ++ .../src/permissions/rules/isEntityKind.ts | 6 ++-- .../src/permissions/rules/isEntityOwner.ts | 9 +++-- .../src/permissions/rules/util.ts | 31 +++++++++++++++++ 8 files changed, 81 insertions(+), 34 deletions(-) create mode 100644 plugins/catalog-backend/src/permissions/rules/util.ts diff --git a/plugins/catalog-backend/api-report.md b/plugins/catalog-backend/api-report.md index 33f0fab18e..aafff2a22e 100644 --- a/plugins/catalog-backend/api-report.md +++ b/plugins/catalog-backend/api-report.md @@ -529,6 +529,11 @@ export class CommonDatabase implements Database { ): Promise; } +// @public +export const createCatalogPermissionRule: ( + rule: PermissionRule, +) => PermissionRule; + // Warning: (ae-missing-release-tag) "CreateDatabaseOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public @deprecated (undocumented) @@ -1397,12 +1402,28 @@ export function parseEntityYaml( // @public export const permissionRules: { - hasAnnotation: CatalogPermissionRule<[annotation: string]>; - hasLabel: CatalogPermissionRule<[label: string]>; - hasMetadata: CatalogPermissionRule<[key: string, value?: string | undefined]>; - hasSpec: CatalogPermissionRule<[key: string, value?: string | undefined]>; - isEntityKind: CatalogPermissionRule<[kinds: string[]]>; - isEntityOwner: CatalogPermissionRule<[claims: string[]]>; + hasAnnotation: PermissionRule< + Entity, + EntitiesSearchFilter, + [annotation: string] + >; + hasLabel: PermissionRule; + hasMetadata: PermissionRule< + Entity, + EntitiesSearchFilter, + [key: string, value?: string | undefined] + >; + hasSpec: PermissionRule< + Entity, + EntitiesSearchFilter, + [key: string, value?: string | undefined] + >; + isEntityKind: PermissionRule; + isEntityOwner: PermissionRule< + Entity, + EntitiesSearchFilter, + [claims: string[]] + >; }; // Warning: (ae-missing-release-tag) "PlaceholderProcessor" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) diff --git a/plugins/catalog-backend/src/permissions/rules/createPropertyRule.ts b/plugins/catalog-backend/src/permissions/rules/createPropertyRule.ts index 254eb164da..27a6033362 100644 --- a/plugins/catalog-backend/src/permissions/rules/createPropertyRule.ts +++ b/plugins/catalog-backend/src/permissions/rules/createPropertyRule.ts @@ -14,15 +14,12 @@ * limitations under the License. */ -import { Entity } from '@backstage/catalog-model'; -import { EntitiesSearchFilter } from '../../catalog/types'; -import { CatalogPermissionRule } from '../types'; import { get } from 'lodash'; +import { Entity } from '@backstage/catalog-model'; +import { createCatalogPermissionRule } from './util'; -export function createPropertyRule( - propertyType: 'metadata' | 'spec', -): CatalogPermissionRule<[key: string, value?: string]> { - return { +export const createPropertyRule = (propertyType: 'metadata' | 'spec') => + createCatalogPermissionRule({ name: `HAS_${propertyType.toUpperCase()}`, description: `Allow entities which have the specified ${propertyType} subfield.`, apply: (resource: Entity, key: string, value?: string) => { @@ -32,9 +29,8 @@ export function createPropertyRule( } return !!foundValue; }, - toQuery: (key: string, value?: string): EntitiesSearchFilter => ({ + toQuery: (key: string, value?: string) => ({ key: `${propertyType}.${key}`, ...(value !== undefined && { values: [value] }), }), - }; -} + }); diff --git a/plugins/catalog-backend/src/permissions/rules/hasAnnotation.ts b/plugins/catalog-backend/src/permissions/rules/hasAnnotation.ts index baab28d838..f82ace6580 100644 --- a/plugins/catalog-backend/src/permissions/rules/hasAnnotation.ts +++ b/plugins/catalog-backend/src/permissions/rules/hasAnnotation.ts @@ -15,21 +15,20 @@ */ import { Entity } from '@backstage/catalog-model'; -import { EntitiesSearchFilter } from '../../catalog/types'; -import { CatalogPermissionRule } from '../types'; +import { createCatalogPermissionRule } from './util'; /** * A {@link CatalogPermissionRule} which filters for the presence of an * annotation on a given entity. * @public */ -export const hasAnnotation: CatalogPermissionRule<[annotation: string]> = { +export const hasAnnotation = createCatalogPermissionRule({ name: 'HAS_ANNOTATION', description: 'Allow entities which are annotated with the specified annotation', apply: (resource: Entity, annotation: string) => !!resource.metadata.annotations?.hasOwnProperty(annotation), - toQuery: (annotation: string): EntitiesSearchFilter => ({ + toQuery: (annotation: string) => ({ key: `metadata.annotations.${annotation}`, }), -}; +}); diff --git a/plugins/catalog-backend/src/permissions/rules/hasLabel.ts b/plugins/catalog-backend/src/permissions/rules/hasLabel.ts index a790f1441f..8e5a3341d7 100644 --- a/plugins/catalog-backend/src/permissions/rules/hasLabel.ts +++ b/plugins/catalog-backend/src/permissions/rules/hasLabel.ts @@ -15,20 +15,19 @@ */ import { Entity } from '@backstage/catalog-model'; -import { EntitiesSearchFilter } from '../../catalog/types'; -import { CatalogPermissionRule } from '../types'; +import { createCatalogPermissionRule } from './util'; /** * A {@link CatalogPermissionRule} which filters for entities with a specified * label in its metadata. * @public */ -export const hasLabel: CatalogPermissionRule<[label: string]> = { +export const hasLabel = createCatalogPermissionRule({ name: 'HAS_LABEL', description: 'Allow entities which have the specified label metadata.', apply: (resource: Entity, label: string) => !!resource.metadata.labels?.hasOwnProperty(label), - toQuery: (label: string): EntitiesSearchFilter => ({ + toQuery: (label: string) => ({ key: `metadata.labels.${label}`, }), -}; +}); diff --git a/plugins/catalog-backend/src/permissions/rules/index.ts b/plugins/catalog-backend/src/permissions/rules/index.ts index 68d1e38715..4eec796c74 100644 --- a/plugins/catalog-backend/src/permissions/rules/index.ts +++ b/plugins/catalog-backend/src/permissions/rules/index.ts @@ -34,3 +34,5 @@ export const permissionRules = { isEntityKind, isEntityOwner, }; + +export { createCatalogPermissionRule } from './util'; diff --git a/plugins/catalog-backend/src/permissions/rules/isEntityKind.ts b/plugins/catalog-backend/src/permissions/rules/isEntityKind.ts index 024188939f..ddaecd314e 100644 --- a/plugins/catalog-backend/src/permissions/rules/isEntityKind.ts +++ b/plugins/catalog-backend/src/permissions/rules/isEntityKind.ts @@ -15,14 +15,14 @@ */ import { Entity } from '@backstage/catalog-model'; import { EntitiesSearchFilter } from '../../catalog/types'; -import { CatalogPermissionRule } from '../types'; +import { createCatalogPermissionRule } from './util'; /** * A {@link CatalogPermissionRule} which filters for entities with a specified * kind. * @public */ -export const isEntityKind: CatalogPermissionRule<[kinds: string[]]> = { +export const isEntityKind = createCatalogPermissionRule({ name: 'IS_ENTITY_KIND', description: 'Allow entities with the specified kind', apply(resource: Entity, kinds: string[]) { @@ -35,4 +35,4 @@ export const isEntityKind: CatalogPermissionRule<[kinds: string[]]> = { values: kinds.map(kind => kind.toLocaleLowerCase('en-US')), }; }, -}; +}); diff --git a/plugins/catalog-backend/src/permissions/rules/isEntityOwner.ts b/plugins/catalog-backend/src/permissions/rules/isEntityOwner.ts index e450cdf721..a7413c4941 100644 --- a/plugins/catalog-backend/src/permissions/rules/isEntityOwner.ts +++ b/plugins/catalog-backend/src/permissions/rules/isEntityOwner.ts @@ -19,15 +19,14 @@ import { RELATION_OWNED_BY, stringifyEntityRef, } from '@backstage/catalog-model'; -import { EntitiesSearchFilter } from '../../catalog/types'; -import { CatalogPermissionRule } from '../types'; +import { createCatalogPermissionRule } from './util'; /** * A {@link CatalogPermissionRule} which filters for entities with a specified * owner. * @public */ -export const isEntityOwner: CatalogPermissionRule<[claims: string[]]> = { +export const isEntityOwner = createCatalogPermissionRule({ name: 'IS_ENTITY_OWNER', description: 'Allow entities owned by the current user', apply: (resource: Entity, claims: string[]) => { @@ -39,8 +38,8 @@ export const isEntityOwner: CatalogPermissionRule<[claims: string[]]> = { .filter(relation => relation.type === RELATION_OWNED_BY) .some(relation => claims.includes(stringifyEntityRef(relation.target))); }, - toQuery: (claims: string[]): EntitiesSearchFilter => ({ + toQuery: (claims: string[]) => ({ key: 'relations.ownedBy', values: claims, }), -}; +}); diff --git a/plugins/catalog-backend/src/permissions/rules/util.ts b/plugins/catalog-backend/src/permissions/rules/util.ts new file mode 100644 index 0000000000..7ef0ca3546 --- /dev/null +++ b/plugins/catalog-backend/src/permissions/rules/util.ts @@ -0,0 +1,31 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Entity } from '@backstage/catalog-model'; +import { makeCreatePermissionRule } from '@backstage/plugin-permission-node'; +import { EntitiesSearchFilter } from '../../catalog/types'; + +/** + * Helper function for creating correctly-typed + * {@link @backstage/plugin-permission-node#PermissionRule}s for the + * catalog-backend. + * + * @public + */ +export const createCatalogPermissionRule = makeCreatePermissionRule< + Entity, + EntitiesSearchFilter +>(); From bef617807bb39973f9d458dce9227e172232e80c Mon Sep 17 00:00:00 2001 From: MT Lewis Date: Fri, 7 Jan 2022 11:50:51 +0000 Subject: [PATCH 4/5] catalog-backend: custom createPermissionRule implementation Signed-off-by: MT Lewis --- plugins/catalog-backend/api-report.md | 32 +++++-------------- .../src/permissions/rules/util.ts | 11 +++---- 2 files changed, 12 insertions(+), 31 deletions(-) diff --git a/plugins/catalog-backend/api-report.md b/plugins/catalog-backend/api-report.md index aafff2a22e..d310ab001f 100644 --- a/plugins/catalog-backend/api-report.md +++ b/plugins/catalog-backend/api-report.md @@ -531,8 +531,8 @@ export class CommonDatabase implements Database { // @public export const createCatalogPermissionRule: ( - rule: PermissionRule, -) => PermissionRule; + rule: CatalogPermissionRule, +) => CatalogPermissionRule; // Warning: (ae-missing-release-tag) "CreateDatabaseOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // @@ -1402,28 +1402,12 @@ export function parseEntityYaml( // @public export const permissionRules: { - hasAnnotation: PermissionRule< - Entity, - EntitiesSearchFilter, - [annotation: string] - >; - hasLabel: PermissionRule; - hasMetadata: PermissionRule< - Entity, - EntitiesSearchFilter, - [key: string, value?: string | undefined] - >; - hasSpec: PermissionRule< - Entity, - EntitiesSearchFilter, - [key: string, value?: string | undefined] - >; - isEntityKind: PermissionRule; - isEntityOwner: PermissionRule< - Entity, - EntitiesSearchFilter, - [claims: string[]] - >; + hasAnnotation: CatalogPermissionRule<[annotation: string]>; + hasLabel: CatalogPermissionRule<[label: string]>; + hasMetadata: CatalogPermissionRule<[key: string, value?: string | undefined]>; + hasSpec: CatalogPermissionRule<[key: string, value?: string | undefined]>; + isEntityKind: CatalogPermissionRule<[kinds: string[]]>; + isEntityOwner: CatalogPermissionRule<[claims: string[]]>; }; // Warning: (ae-missing-release-tag) "PlaceholderProcessor" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) diff --git a/plugins/catalog-backend/src/permissions/rules/util.ts b/plugins/catalog-backend/src/permissions/rules/util.ts index 7ef0ca3546..7d17d64e49 100644 --- a/plugins/catalog-backend/src/permissions/rules/util.ts +++ b/plugins/catalog-backend/src/permissions/rules/util.ts @@ -14,9 +14,7 @@ * limitations under the License. */ -import { Entity } from '@backstage/catalog-model'; -import { makeCreatePermissionRule } from '@backstage/plugin-permission-node'; -import { EntitiesSearchFilter } from '../../catalog/types'; +import { CatalogPermissionRule } from '../types'; /** * Helper function for creating correctly-typed @@ -25,7 +23,6 @@ import { EntitiesSearchFilter } from '../../catalog/types'; * * @public */ -export const createCatalogPermissionRule = makeCreatePermissionRule< - Entity, - EntitiesSearchFilter ->(); +export const createCatalogPermissionRule = ( + rule: CatalogPermissionRule, +) => rule; From 10b4ba686f234ef0b301a5204a71fba6f12c0637 Mon Sep 17 00:00:00 2001 From: MT Lewis Date: Fri, 7 Jan 2022 15:04:50 +0000 Subject: [PATCH 5/5] catalog-backend: remove CatalogPermissionRule type Signed-off-by: MT Lewis --- plugins/catalog-backend/api-report.md | 47 ++++++++++++------- .../catalog-backend/src/permissions/index.ts | 1 - .../src/permissions/rules/hasAnnotation.ts | 5 +- .../src/permissions/rules/hasLabel.ts | 4 +- .../src/permissions/rules/hasMetadata.ts | 5 +- .../src/permissions/rules/hasSpec.ts | 5 +- .../src/permissions/rules/isEntityKind.ts | 4 +- .../src/permissions/rules/isEntityOwner.ts | 4 +- .../src/permissions/rules/util.ts | 11 +++-- .../catalog-backend/src/permissions/types.ts | 31 ------------ .../src/service/NextCatalogBuilder.ts | 19 ++++++-- .../catalog-backend/src/service/NextRouter.ts | 10 ++-- 12 files changed, 73 insertions(+), 73 deletions(-) delete mode 100644 plugins/catalog-backend/src/permissions/types.ts diff --git a/plugins/catalog-backend/api-report.md b/plugins/catalog-backend/api-report.md index d310ab001f..4b4036ee8a 100644 --- a/plugins/catalog-backend/api-report.md +++ b/plugins/catalog-backend/api-report.md @@ -306,13 +306,6 @@ export type CatalogEnvironment = { permissions: PermissionAuthorizer; }; -// @public -export type CatalogPermissionRule = PermissionRule< - Entity, - EntitiesSearchFilter, - TParams ->; - // Warning: (ae-missing-release-tag) "CatalogProcessingEngine" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -531,8 +524,8 @@ export class CommonDatabase implements Database { // @public export const createCatalogPermissionRule: ( - rule: CatalogPermissionRule, -) => CatalogPermissionRule; + rule: PermissionRule, +) => PermissionRule; // Warning: (ae-missing-release-tag) "CreateDatabaseOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // @@ -1318,7 +1311,11 @@ export class NextCatalogBuilder { // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen addEntityProvider(...providers: EntityProvider[]): NextCatalogBuilder; addPermissionRules( - ...permissionRules: CatalogPermissionRule[] + ...permissionRules: PermissionRule< + Entity, + EntitiesSearchFilter, + unknown[] + >[] ): void; // Warning: (tsdoc-param-tag-missing-hyphen) The @param block should be followed by a parameter name and then a hyphen addProcessor(...processors: CatalogProcessor[]): NextCatalogBuilder; @@ -1367,7 +1364,7 @@ export interface NextRouterOptions { // (undocumented) logger: Logger_2; // (undocumented) - permissionRules?: CatalogPermissionRule[]; + permissionRules?: PermissionRule[]; // (undocumented) refreshService?: RefreshService; } @@ -1402,12 +1399,28 @@ export function parseEntityYaml( // @public export const permissionRules: { - hasAnnotation: CatalogPermissionRule<[annotation: string]>; - hasLabel: CatalogPermissionRule<[label: string]>; - hasMetadata: CatalogPermissionRule<[key: string, value?: string | undefined]>; - hasSpec: CatalogPermissionRule<[key: string, value?: string | undefined]>; - isEntityKind: CatalogPermissionRule<[kinds: string[]]>; - isEntityOwner: CatalogPermissionRule<[claims: string[]]>; + hasAnnotation: PermissionRule< + Entity, + EntitiesSearchFilter, + [annotation: string] + >; + hasLabel: PermissionRule; + hasMetadata: PermissionRule< + Entity, + EntitiesSearchFilter, + [key: string, value?: string | undefined] + >; + hasSpec: PermissionRule< + Entity, + EntitiesSearchFilter, + [key: string, value?: string | undefined] + >; + isEntityKind: PermissionRule; + isEntityOwner: PermissionRule< + Entity, + EntitiesSearchFilter, + [claims: string[]] + >; }; // Warning: (ae-missing-release-tag) "PlaceholderProcessor" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) diff --git a/plugins/catalog-backend/src/permissions/index.ts b/plugins/catalog-backend/src/permissions/index.ts index e7ece1dbc7..624d6dd7ac 100644 --- a/plugins/catalog-backend/src/permissions/index.ts +++ b/plugins/catalog-backend/src/permissions/index.ts @@ -15,4 +15,3 @@ */ export * from './rules'; -export type { CatalogPermissionRule } from './types'; diff --git a/plugins/catalog-backend/src/permissions/rules/hasAnnotation.ts b/plugins/catalog-backend/src/permissions/rules/hasAnnotation.ts index f82ace6580..81ebd52789 100644 --- a/plugins/catalog-backend/src/permissions/rules/hasAnnotation.ts +++ b/plugins/catalog-backend/src/permissions/rules/hasAnnotation.ts @@ -18,8 +18,9 @@ import { Entity } from '@backstage/catalog-model'; import { createCatalogPermissionRule } from './util'; /** - * A {@link CatalogPermissionRule} which filters for the presence of an - * annotation on a given entity. + * A catalog {@link @backstage/plugin-permission-node#PermissionRule} which + * filters for the presence of an annotation on a given entity. + * * @public */ export const hasAnnotation = createCatalogPermissionRule({ diff --git a/plugins/catalog-backend/src/permissions/rules/hasLabel.ts b/plugins/catalog-backend/src/permissions/rules/hasLabel.ts index 8e5a3341d7..04b00d68fa 100644 --- a/plugins/catalog-backend/src/permissions/rules/hasLabel.ts +++ b/plugins/catalog-backend/src/permissions/rules/hasLabel.ts @@ -18,8 +18,8 @@ import { Entity } from '@backstage/catalog-model'; import { createCatalogPermissionRule } from './util'; /** - * A {@link CatalogPermissionRule} which filters for entities with a specified - * label in its metadata. + * A catalog {@link @backstage/plugin-permission-node#PermissionRule} which + * filters for entities with a specified label in its metadata. * @public */ export const hasLabel = createCatalogPermissionRule({ diff --git a/plugins/catalog-backend/src/permissions/rules/hasMetadata.ts b/plugins/catalog-backend/src/permissions/rules/hasMetadata.ts index fa592feb44..f5f25a5ecf 100644 --- a/plugins/catalog-backend/src/permissions/rules/hasMetadata.ts +++ b/plugins/catalog-backend/src/permissions/rules/hasMetadata.ts @@ -17,8 +17,9 @@ import { createPropertyRule } from './createPropertyRule'; /** - * A {@link CatalogPermissionRule} which filters for entities with the specified - * metadata subfield. Also matches on values if value is provided. + * A catalog {@link @backstage/plugin-permission-node#PermissionRule} which + * filters for entities with the specified metadata subfield. Also matches on + * values if value is provided. * * The key argument to the `apply` and `toQuery` methods can be nested, such as * 'field.nestedfield'. diff --git a/plugins/catalog-backend/src/permissions/rules/hasSpec.ts b/plugins/catalog-backend/src/permissions/rules/hasSpec.ts index 73a7519e1a..891cf1d58c 100644 --- a/plugins/catalog-backend/src/permissions/rules/hasSpec.ts +++ b/plugins/catalog-backend/src/permissions/rules/hasSpec.ts @@ -17,8 +17,9 @@ import { createPropertyRule } from './createPropertyRule'; /** - * A {@link CatalogPermissionRule} which filters for entities with the specified - * spec subfield. Also matches on values if value is provided. + * A catalog {@link @backstage/plugin-permission-node#PermissionRule} which + * filters for entities with the specified spec subfield. Also matches on values + * if value is provided. * * The key argument to the `apply` and `toQuery` methods can be nested, such as * 'field.nestedfield'. diff --git a/plugins/catalog-backend/src/permissions/rules/isEntityKind.ts b/plugins/catalog-backend/src/permissions/rules/isEntityKind.ts index ddaecd314e..6356c94dc4 100644 --- a/plugins/catalog-backend/src/permissions/rules/isEntityKind.ts +++ b/plugins/catalog-backend/src/permissions/rules/isEntityKind.ts @@ -18,8 +18,8 @@ import { EntitiesSearchFilter } from '../../catalog/types'; import { createCatalogPermissionRule } from './util'; /** - * A {@link CatalogPermissionRule} which filters for entities with a specified - * kind. + * A catalog {@link @backstage/plugin-permission-node#PermissionRule} which + * filters for entities with a specified kind. * @public */ export const isEntityKind = createCatalogPermissionRule({ diff --git a/plugins/catalog-backend/src/permissions/rules/isEntityOwner.ts b/plugins/catalog-backend/src/permissions/rules/isEntityOwner.ts index a7413c4941..3176b31b87 100644 --- a/plugins/catalog-backend/src/permissions/rules/isEntityOwner.ts +++ b/plugins/catalog-backend/src/permissions/rules/isEntityOwner.ts @@ -22,8 +22,8 @@ import { import { createCatalogPermissionRule } from './util'; /** - * A {@link CatalogPermissionRule} which filters for entities with a specified - * owner. + * A catalog {@link @backstage/plugin-permission-node#PermissionRule} which + * filters for entities with a specified owner. * @public */ export const isEntityOwner = createCatalogPermissionRule({ diff --git a/plugins/catalog-backend/src/permissions/rules/util.ts b/plugins/catalog-backend/src/permissions/rules/util.ts index 7d17d64e49..7ef0ca3546 100644 --- a/plugins/catalog-backend/src/permissions/rules/util.ts +++ b/plugins/catalog-backend/src/permissions/rules/util.ts @@ -14,7 +14,9 @@ * limitations under the License. */ -import { CatalogPermissionRule } from '../types'; +import { Entity } from '@backstage/catalog-model'; +import { makeCreatePermissionRule } from '@backstage/plugin-permission-node'; +import { EntitiesSearchFilter } from '../../catalog/types'; /** * Helper function for creating correctly-typed @@ -23,6 +25,7 @@ import { CatalogPermissionRule } from '../types'; * * @public */ -export const createCatalogPermissionRule = ( - rule: CatalogPermissionRule, -) => rule; +export const createCatalogPermissionRule = makeCreatePermissionRule< + Entity, + EntitiesSearchFilter +>(); diff --git a/plugins/catalog-backend/src/permissions/types.ts b/plugins/catalog-backend/src/permissions/types.ts deleted file mode 100644 index 4a0d9dc1fc..0000000000 --- a/plugins/catalog-backend/src/permissions/types.ts +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2021 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { Entity } from '@backstage/catalog-model'; -import { PermissionRule } from '@backstage/plugin-permission-node'; -import { EntitiesSearchFilter } from '../catalog/types'; - -/** - * A conditional rule that can be used to filter catalog entities for an - * authorization request. See - * {@link @backstage/plugin-permission-node#PermissionRule} for more details. - * - * @public - */ -export type CatalogPermissionRule = PermissionRule< - Entity, - EntitiesSearchFilter, - TParams ->; diff --git a/plugins/catalog-backend/src/service/NextCatalogBuilder.ts b/plugins/catalog-backend/src/service/NextCatalogBuilder.ts index e707423670..36d4347ede 100644 --- a/plugins/catalog-backend/src/service/NextCatalogBuilder.ts +++ b/plugins/catalog-backend/src/service/NextCatalogBuilder.ts @@ -17,6 +17,7 @@ import { PluginDatabaseManager, UrlReader } from '@backstage/backend-common'; import { DefaultNamespaceEntityPolicy, + Entity, EntityPolicies, EntityPolicy, FieldFormatEntityPolicy, @@ -29,7 +30,7 @@ import { ScmIntegrations } from '@backstage/integration'; import { createHash } from 'crypto'; import { Router } from 'express'; import lodash from 'lodash'; -import { EntitiesCatalog } from '../catalog'; +import { EntitiesCatalog, EntitiesSearchFilter } from '../catalog'; import { DatabaseLocationsCatalog, LocationsCatalog, @@ -83,9 +84,9 @@ import { Config } from '@backstage/config'; import { Logger } from 'winston'; import { LocationService } from './types'; import { connectEntityProviders } from '../processing/connectEntityProviders'; -import { CatalogPermissionRule } from '../permissions/types'; import { permissionRules as catalogPermissionRules } from '../permissions/rules'; import { PermissionAuthorizer } from '@backstage/plugin-permission-common'; +import { PermissionRule } from '@backstage/plugin-permission-node'; export type CatalogEnvironment = { logger: Logger; @@ -130,7 +131,11 @@ export class NextCatalogBuilder { maxSeconds: 150, }); private locationAnalyzer: LocationAnalyzer | undefined = undefined; - private permissionRules: CatalogPermissionRule[]; + private permissionRules: PermissionRule< + Entity, + EntitiesSearchFilter, + unknown[] + >[]; constructor(env: CatalogEnvironment) { this.env = env; @@ -331,7 +336,13 @@ export class NextCatalogBuilder { * * @param permissionRules - Additional permission rules */ - addPermissionRules(...permissionRules: CatalogPermissionRule[]) { + addPermissionRules( + ...permissionRules: PermissionRule< + Entity, + EntitiesSearchFilter, + unknown[] + >[] + ) { this.permissionRules.push(...permissionRules); } diff --git a/plugins/catalog-backend/src/service/NextRouter.ts b/plugins/catalog-backend/src/service/NextRouter.ts index 948424ec88..5338f58f91 100644 --- a/plugins/catalog-backend/src/service/NextRouter.ts +++ b/plugins/catalog-backend/src/service/NextRouter.ts @@ -25,14 +25,16 @@ import { import { Config } from '@backstage/config'; import { NotFoundError } from '@backstage/errors'; import { RESOURCE_TYPE_CATALOG_ENTITY } from '@backstage/plugin-catalog-common'; -import { createPermissionIntegrationRouter } from '@backstage/plugin-permission-node'; +import { + createPermissionIntegrationRouter, + PermissionRule, +} from '@backstage/plugin-permission-node'; import express from 'express'; import Router from 'express-promise-router'; import { Logger } from 'winston'; import yn from 'yn'; -import { EntitiesCatalog } from '../catalog'; +import { EntitiesCatalog, EntitiesSearchFilter } from '../catalog'; import { LocationAnalyzer } from '../ingestion/types'; -import { CatalogPermissionRule } from '../permissions/types'; import { basicEntityFilter, parseEntityFilterParams, @@ -49,7 +51,7 @@ export interface NextRouterOptions { refreshService?: RefreshService; logger: Logger; config: Config; - permissionRules?: CatalogPermissionRule[]; + permissionRules?: PermissionRule[]; } export async function createNextRouter(