@backstage/plugin-catalog-backend 1.0.1-next.0 → 1.1.0-next.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,82 @@
1
1
  # @backstage/plugin-catalog-backend
2
2
 
3
+ ## 1.1.0-next.3
4
+
5
+ ### Patch Changes
6
+
7
+ - 23646e51a5: Use new `PermissionEvaluator#authorizeConditional` method when retrieving permission conditions.
8
+ - 48405ed232: Added `spec.profile.displayName` to search index for Group kinds
9
+ - Updated dependencies
10
+ - @backstage/plugin-permission-common@0.6.0-next.1
11
+ - @backstage/plugin-permission-node@0.6.0-next.2
12
+ - @backstage/backend-common@0.13.2-next.2
13
+ - @backstage/integration@1.1.0-next.2
14
+
15
+ ## 1.1.0-next.2
16
+
17
+ ### Minor Changes
18
+
19
+ - bf82edf4c9: Added `/validate-entity` endpoint
20
+
21
+ ### Patch Changes
22
+
23
+ - 8592cacfd3: Fixed an issue where sometimes entities would have stale relations "stuck" and
24
+ not getting removed as expected, after the other end of the relation had stopped
25
+ referring to them.
26
+ - Updated dependencies
27
+ - @backstage/catalog-model@1.0.1-next.1
28
+
29
+ ## 1.1.0-next.1
30
+
31
+ ### Minor Changes
32
+
33
+ - 8012ac46a0: **BREAKING (alpha api):** Replace `createCatalogPolicyDecision` export with `createCatalogConditionalDecision`, which accepts a permission parameter of type `ResourcePermission<'catalog-entity'>` along with conditions. The permission passed is expected to be the handled permission in `PermissionPolicy#handle`, whose type must first be narrowed using methods like `isPermission` and `isResourcePermission`:
34
+
35
+ ```typescript
36
+ class TestPermissionPolicy implements PermissionPolicy {
37
+ async handle(
38
+ request: PolicyQuery<Permission>,
39
+ _user?: BackstageIdentityResponse,
40
+ ): Promise<PolicyDecision> {
41
+ if (
42
+ // Narrow type of `request.permission` to `ResourcePermission<'catalog-entity'>
43
+ isResourcePermission(request.permission, RESOURCE_TYPE_CATALOG_ENTITY)
44
+ ) {
45
+ return createCatalogConditionalDecision(
46
+ request.permission,
47
+ catalogConditions.isEntityOwner(
48
+ _user?.identity.ownershipEntityRefs ?? [],
49
+ ),
50
+ );
51
+ }
52
+
53
+ return {
54
+ result: AuthorizeResult.ALLOW,
55
+ };
56
+ ```
57
+
58
+ - 8012ac46a0: **BREAKING:** Mark CatalogBuilder#addPermissionRules as @alpha.
59
+ - fb02d2d94d: export `locationSpecToLocationEntity`
60
+
61
+ ### Patch Changes
62
+
63
+ - ada4446733: Specify type of `visibilityPermission` property on collators and collator factories.
64
+ - 1691c6c5c2: Clarify that config locations that emit User and Group kinds now need to declare so in the `catalog.locations.[].rules`
65
+ - 8012ac46a0: Handle changes to @alpha permission-related types.
66
+
67
+ - All exported permission rules and conditions now have a `resourceType`.
68
+ - `createCatalogConditionalDecision` now expects supplied conditions to have the appropriate `resourceType`.
69
+ - `createCatalogPermissionRule` now expects `resourceType` as part of the supplied rule object.
70
+ - Introduce new `CatalogPermissionRule` convenience type.
71
+
72
+ - Updated dependencies
73
+ - @backstage/integration@1.1.0-next.1
74
+ - @backstage/plugin-permission-common@0.6.0-next.0
75
+ - @backstage/plugin-permission-node@0.6.0-next.1
76
+ - @backstage/plugin-catalog-common@1.0.1-next.1
77
+ - @backstage/backend-common@0.13.2-next.1
78
+ - @backstage/plugin-search-common@0.3.3-next.1
79
+
3
80
  ## 1.0.1-next.0
4
81
 
5
82
  ### Patch Changes
@@ -1394,6 +1471,8 @@
1394
1471
  locations:
1395
1472
  - type: github-multi-org
1396
1473
  target: https://github.myorg.com
1474
+ rules:
1475
+ - allow: [User, Group]
1397
1476
 
1398
1477
  processors:
1399
1478
  githubMultiOrg:
package/README.md CHANGED
@@ -27,8 +27,7 @@ restoring the plugin, if you previously removed it.
27
27
 
28
28
  ```bash
29
29
  # From your Backstage root directory
30
- cd packages/backend
31
- yarn add @backstage/plugin-catalog-backend
30
+ yarn add --cwd packages/backend @backstage/plugin-catalog-backend
32
31
  ```
33
32
 
34
33
  ### Adding the plugin to your `packages/backend`
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/plugin-catalog-backend",
3
- "version": "1.0.1-next.0",
3
+ "version": "1.1.0-next.3",
4
4
  "main": "../dist/index.cjs.js",
5
5
  "types": "../dist/index.alpha.d.ts"
6
6
  }
@@ -9,7 +9,7 @@
9
9
  import { CatalogApi } from '@backstage/catalog-client';
10
10
  import { CatalogEntityDocument } from '@backstage/plugin-catalog-common';
11
11
  import { CompoundEntityRef } from '@backstage/catalog-model';
12
- import { ConditionalPolicyDecision } from '@backstage/plugin-permission-node';
12
+ import { ConditionalPolicyDecision } from '@backstage/plugin-permission-common';
13
13
  import { Conditions } from '@backstage/plugin-permission-node';
14
14
  import { Config } from '@backstage/config';
15
15
  import { DocumentCollatorFactory } from '@backstage/plugin-search-common';
@@ -17,15 +17,18 @@ import { Entity } from '@backstage/catalog-model';
17
17
  import { EntityPolicy } from '@backstage/catalog-model';
18
18
  import { GetEntitiesRequest } from '@backstage/catalog-client';
19
19
  import { JsonValue } from '@backstage/types';
20
+ import { LocationEntityV1alpha1 } from '@backstage/catalog-model';
20
21
  import { Logger } from 'winston';
21
22
  import { Permission } from '@backstage/plugin-permission-common';
22
23
  import { PermissionAuthorizer } from '@backstage/plugin-permission-common';
23
24
  import { PermissionCondition } from '@backstage/plugin-permission-common';
24
25
  import { PermissionCriteria } from '@backstage/plugin-permission-common';
26
+ import { PermissionEvaluator } from '@backstage/plugin-permission-common';
25
27
  import { PermissionRule } from '@backstage/plugin-permission-node';
26
28
  import { PluginDatabaseManager } from '@backstage/backend-common';
27
29
  import { PluginEndpointDiscovery } from '@backstage/backend-common';
28
30
  import { Readable } from 'stream';
31
+ import { ResourcePermission } from '@backstage/plugin-permission-common';
29
32
  import { Router } from 'express';
30
33
  import { ScmIntegrationRegistry } from '@backstage/integration';
31
34
  import { TokenManager } from '@backstage/backend-common';
@@ -269,8 +272,9 @@ export declare class CatalogBuilder {
269
272
  * {@link @backstage/plugin-permission-node#PermissionRule}.
270
273
  *
271
274
  * @param permissionRules - Additional permission rules
275
+ * @alpha
272
276
  */
273
- addPermissionRules(...permissionRules: PermissionRule<Entity, EntitiesSearchFilter, unknown[]>[]): void;
277
+ addPermissionRules(...permissionRules: CatalogPermissionRule[]): void;
274
278
  /**
275
279
  * Wires up and returns all of the component parts of the catalog
276
280
  */
@@ -285,18 +289,18 @@ export declare class CatalogBuilder {
285
289
  }
286
290
 
287
291
  /**
288
- * These conditions are used when creating conditional decisions that are returned
289
- * by authorization policies.
292
+ * These conditions are used when creating conditional decisions for catalog
293
+ * entities that are returned by authorization policies.
290
294
  *
291
295
  * @alpha
292
296
  */
293
297
  export declare const catalogConditions: Conditions< {
294
- hasAnnotation: PermissionRule<Entity, EntitiesSearchFilter, [annotation: string]>;
295
- hasLabel: PermissionRule<Entity, EntitiesSearchFilter, [label: string]>;
296
- hasMetadata: PermissionRule<Entity, EntitiesSearchFilter, [key: string, value?: string | undefined]>;
297
- hasSpec: PermissionRule<Entity, EntitiesSearchFilter, [key: string, value?: string | undefined]>;
298
- isEntityKind: PermissionRule<Entity, EntitiesSearchFilter, [kinds: string[]]>;
299
- isEntityOwner: PermissionRule<Entity, EntitiesSearchFilter, [claims: string[]]>;
298
+ hasAnnotation: PermissionRule<Entity, EntitiesSearchFilter, "catalog-entity", [annotation: string]>;
299
+ hasLabel: PermissionRule<Entity, EntitiesSearchFilter, "catalog-entity", [label: string]>;
300
+ hasMetadata: PermissionRule<Entity, EntitiesSearchFilter, "catalog-entity", [key: string, value?: string | undefined]>;
301
+ hasSpec: PermissionRule<Entity, EntitiesSearchFilter, "catalog-entity", [key: string, value?: string | undefined]>;
302
+ isEntityKind: PermissionRule<Entity, EntitiesSearchFilter, "catalog-entity", [kinds: string[]]>;
303
+ isEntityOwner: PermissionRule<Entity, EntitiesSearchFilter, "catalog-entity", [claims: string[]]>;
300
304
  }>;
301
305
 
302
306
  /** @public */
@@ -305,9 +309,18 @@ export declare type CatalogEnvironment = {
305
309
  database: PluginDatabaseManager;
306
310
  config: Config;
307
311
  reader: UrlReader;
308
- permissions: PermissionAuthorizer;
312
+ permissions: PermissionEvaluator | PermissionAuthorizer;
309
313
  };
310
314
 
315
+ /**
316
+ * Convenience type for {@link @backstage/plugin-permission-node#PermissionRule}
317
+ * instances with the correct resource type, resource, and filter to work with
318
+ * the catalog.
319
+ *
320
+ * @alpha
321
+ */
322
+ export declare type CatalogPermissionRule<TParams extends unknown[] = unknown[]> = PermissionRule<Entity, EntitiesSearchFilter, 'catalog-entity', TParams>;
323
+
311
324
  /** @public */
312
325
  export declare interface CatalogProcessingEngine {
313
326
  start(): Promise<void>;
@@ -465,37 +478,46 @@ export declare class CodeOwnersProcessor implements CatalogProcessor {
465
478
  }
466
479
 
467
480
  /**
468
- * Helper function for creating correctly-typed
469
- * {@link @backstage/plugin-permission-node#PermissionRule}s for the
470
- * catalog-backend.
471
- *
472
- * @alpha
473
- */
474
- export declare const createCatalogPermissionRule: <TParams extends unknown[]>(rule: PermissionRule<Entity, EntitiesSearchFilter, TParams>) => PermissionRule<Entity, EntitiesSearchFilter, TParams>;
475
-
476
- /**
477
- * `createCatalogPolicyDecision` can be used when authoring policies to create
478
- * conditional decisions.
481
+ * `createCatalogConditionalDecision` can be used when authoring policies to
482
+ * create conditional decisions. It requires a permission of type
483
+ * `ResourcePermission<'catalog-entity'>` to be passed as the first parameter.
484
+ * It's recommended that you use the provided `isResourcePermission` and
485
+ * `isPermission` helper methods to narrow the type of the permission passed to
486
+ * the handle method as shown below.
479
487
  *
480
488
  * ```
481
489
  * // MyAuthorizationPolicy.ts
482
490
  * ...
483
491
  * import { createCatalogPolicyDecision } from '@backstage/plugin-catalog-backend';
492
+ * import { RESOURCE_TYPE_CATALOG_ENTITY } from '@backstage/plugin-catalog-common';
484
493
  *
485
494
  * class MyAuthorizationPolicy implements PermissionPolicy {
486
495
  * async handle(request, user) {
487
496
  * ...
488
497
  *
489
- * return createCatalogPolicyDecision({
490
- * anyOf: [...insert conditions here...],
491
- * });
492
- * }
498
+ * if (isResourcePermission(request.permission, RESOURCE_TYPE_CATALOG_ENTITY)) {
499
+ * return createCatalogConditionalDecision(
500
+ * request.permission,
501
+ * { anyOf: [...insert conditions here...] }
502
+ * );
503
+ * }
504
+ *
505
+ * ...
493
506
  * }
494
507
  * ```
495
508
  *
496
509
  * @alpha
497
510
  */
498
- export declare const createCatalogPolicyDecision: (conditions: PermissionCriteria<PermissionCondition<unknown[]>>) => ConditionalPolicyDecision;
511
+ export declare const createCatalogConditionalDecision: (permission: ResourcePermission<"catalog-entity">, conditions: PermissionCriteria<PermissionCondition<"catalog-entity", unknown[]>>) => ConditionalPolicyDecision;
512
+
513
+ /**
514
+ * Helper function for creating correctly-typed
515
+ * {@link @backstage/plugin-permission-node#PermissionRule}s for the
516
+ * catalog-backend.
517
+ *
518
+ * @alpha
519
+ */
520
+ export declare const createCatalogPermissionRule: <TParams extends unknown[]>(rule: PermissionRule<Entity, EntitiesSearchFilter, "catalog-entity", TParams>) => PermissionRule<Entity, EntitiesSearchFilter, "catalog-entity", TParams>;
499
521
 
500
522
  /**
501
523
  * Creates a function that returns a random processing interval between minSeconds and maxSeconds.
@@ -551,8 +573,6 @@ export declare class DefaultCatalogCollatorFactory implements DocumentCollatorFa
551
573
  private constructor();
552
574
  getCollator(): Promise<Readable>;
553
575
  private applyArgsToFormat;
554
- private isUserEntity;
555
- private getDocumentText;
556
576
  private execute;
557
577
  }
558
578
 
@@ -716,6 +736,12 @@ export declare type LocationSpec = {
716
736
  presence?: 'optional' | 'required';
717
737
  };
718
738
 
739
+ /** @public */
740
+ export declare function locationSpecToLocationEntity(opts: {
741
+ location: LocationSpec;
742
+ parentEntity?: Entity;
743
+ }): LocationEntityV1alpha1;
744
+
719
745
  /** @public */
720
746
  export declare function parseEntityYaml(data: Buffer, location: LocationSpec): Iterable<CatalogProcessorResult>;
721
747
 
@@ -726,12 +752,12 @@ export declare function parseEntityYaml(data: Buffer, location: LocationSpec): I
726
752
  * @alpha
727
753
  */
728
754
  export declare const permissionRules: {
729
- hasAnnotation: PermissionRule<Entity, EntitiesSearchFilter, [annotation: string]>;
730
- hasLabel: PermissionRule<Entity, EntitiesSearchFilter, [label: string]>;
731
- hasMetadata: PermissionRule<Entity, EntitiesSearchFilter, [key: string, value?: string | undefined]>;
732
- hasSpec: PermissionRule<Entity, EntitiesSearchFilter, [key: string, value?: string | undefined]>;
733
- isEntityKind: PermissionRule<Entity, EntitiesSearchFilter, [kinds: string[]]>;
734
- isEntityOwner: PermissionRule<Entity, EntitiesSearchFilter, [claims: string[]]>;
755
+ hasAnnotation: PermissionRule<Entity, EntitiesSearchFilter, "catalog-entity", [annotation: string]>;
756
+ hasLabel: PermissionRule<Entity, EntitiesSearchFilter, "catalog-entity", [label: string]>;
757
+ hasMetadata: PermissionRule<Entity, EntitiesSearchFilter, "catalog-entity", [key: string, value?: string | undefined]>;
758
+ hasSpec: PermissionRule<Entity, EntitiesSearchFilter, "catalog-entity", [key: string, value?: string | undefined]>;
759
+ isEntityKind: PermissionRule<Entity, EntitiesSearchFilter, "catalog-entity", [kinds: string[]]>;
760
+ isEntityOwner: PermissionRule<Entity, EntitiesSearchFilter, "catalog-entity", [claims: string[]]>;
735
761
  };
736
762
 
737
763
  /**
@@ -9,7 +9,7 @@
9
9
  import { CatalogApi } from '@backstage/catalog-client';
10
10
  import { CatalogEntityDocument } from '@backstage/plugin-catalog-common';
11
11
  import { CompoundEntityRef } from '@backstage/catalog-model';
12
- import { ConditionalPolicyDecision } from '@backstage/plugin-permission-node';
12
+ import { ConditionalPolicyDecision } from '@backstage/plugin-permission-common';
13
13
  import { Conditions } from '@backstage/plugin-permission-node';
14
14
  import { Config } from '@backstage/config';
15
15
  import { DocumentCollatorFactory } from '@backstage/plugin-search-common';
@@ -17,15 +17,18 @@ import { Entity } from '@backstage/catalog-model';
17
17
  import { EntityPolicy } from '@backstage/catalog-model';
18
18
  import { GetEntitiesRequest } from '@backstage/catalog-client';
19
19
  import { JsonValue } from '@backstage/types';
20
+ import { LocationEntityV1alpha1 } from '@backstage/catalog-model';
20
21
  import { Logger } from 'winston';
21
22
  import { Permission } from '@backstage/plugin-permission-common';
22
23
  import { PermissionAuthorizer } from '@backstage/plugin-permission-common';
23
24
  import { PermissionCondition } from '@backstage/plugin-permission-common';
24
25
  import { PermissionCriteria } from '@backstage/plugin-permission-common';
26
+ import { PermissionEvaluator } from '@backstage/plugin-permission-common';
25
27
  import { PermissionRule } from '@backstage/plugin-permission-node';
26
28
  import { PluginDatabaseManager } from '@backstage/backend-common';
27
29
  import { PluginEndpointDiscovery } from '@backstage/backend-common';
28
30
  import { Readable } from 'stream';
31
+ import { ResourcePermission } from '@backstage/plugin-permission-common';
29
32
  import { Router } from 'express';
30
33
  import { ScmIntegrationRegistry } from '@backstage/integration';
31
34
  import { TokenManager } from '@backstage/backend-common';
@@ -263,14 +266,7 @@ export declare class CatalogBuilder {
263
266
  * @param parser - The custom parser
264
267
  */
265
268
  setEntityDataParser(parser: CatalogProcessorParser): CatalogBuilder;
266
- /**
267
- * Adds additional permission rules. Permission rules are used to evaluate
268
- * catalog resources against queries. See
269
- * {@link @backstage/plugin-permission-node#PermissionRule}.
270
- *
271
- * @param permissionRules - Additional permission rules
272
- */
273
- addPermissionRules(...permissionRules: PermissionRule<Entity, EntitiesSearchFilter, unknown[]>[]): void;
269
+ /* Excluded from this release type: addPermissionRules */
274
270
  /**
275
271
  * Wires up and returns all of the component parts of the catalog
276
272
  */
@@ -292,9 +288,11 @@ export declare type CatalogEnvironment = {
292
288
  database: PluginDatabaseManager;
293
289
  config: Config;
294
290
  reader: UrlReader;
295
- permissions: PermissionAuthorizer;
291
+ permissions: PermissionEvaluator | PermissionAuthorizer;
296
292
  };
297
293
 
294
+ /* Excluded from this release type: CatalogPermissionRule */
295
+
298
296
  /** @public */
299
297
  export declare interface CatalogProcessingEngine {
300
298
  start(): Promise<void>;
@@ -451,9 +449,9 @@ export declare class CodeOwnersProcessor implements CatalogProcessor {
451
449
  preProcessEntity(entity: Entity, location: LocationSpec): Promise<Entity>;
452
450
  }
453
451
 
454
- /* Excluded from this release type: createCatalogPermissionRule */
452
+ /* Excluded from this release type: createCatalogConditionalDecision */
455
453
 
456
- /* Excluded from this release type: createCatalogPolicyDecision */
454
+ /* Excluded from this release type: createCatalogPermissionRule */
457
455
 
458
456
  /**
459
457
  * Creates a function that returns a random processing interval between minSeconds and maxSeconds.
@@ -509,8 +507,6 @@ export declare class DefaultCatalogCollatorFactory implements DocumentCollatorFa
509
507
  private constructor();
510
508
  getCollator(): Promise<Readable>;
511
509
  private applyArgsToFormat;
512
- private isUserEntity;
513
- private getDocumentText;
514
510
  private execute;
515
511
  }
516
512
 
@@ -674,6 +670,12 @@ export declare type LocationSpec = {
674
670
  presence?: 'optional' | 'required';
675
671
  };
676
672
 
673
+ /** @public */
674
+ export declare function locationSpecToLocationEntity(opts: {
675
+ location: LocationSpec;
676
+ parentEntity?: Entity;
677
+ }): LocationEntityV1alpha1;
678
+
677
679
  /** @public */
678
680
  export declare function parseEntityYaml(data: Buffer, location: LocationSpec): Iterable<CatalogProcessorResult>;
679
681