@backstage-community/plugin-rbac-backend 6.2.5 → 6.3.0

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.
Files changed (31) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +41 -3
  3. package/dist/auditor/auditor.cjs.js +5 -0
  4. package/dist/auditor/auditor.cjs.js.map +1 -1
  5. package/dist/auditor/rest-interceptor.cjs.js +5 -0
  6. package/dist/auditor/rest-interceptor.cjs.js.map +1 -1
  7. package/dist/database/extra-permission-enabled-plugins-storage.cjs.js +21 -0
  8. package/dist/database/extra-permission-enabled-plugins-storage.cjs.js.map +1 -0
  9. package/dist/index.d.ts +5 -1
  10. package/dist/permissions/conditions.cjs.js +6 -5
  11. package/dist/permissions/conditions.cjs.js.map +1 -1
  12. package/dist/permissions/resource.cjs.js +12 -0
  13. package/dist/permissions/resource.cjs.js.map +1 -0
  14. package/dist/permissions/rules.cjs.js +3 -4
  15. package/dist/permissions/rules.cjs.js.map +1 -1
  16. package/dist/plugin.cjs.js +6 -3
  17. package/dist/plugin.cjs.js.map +1 -1
  18. package/dist/service/extendable-id-provider.cjs.js +32 -0
  19. package/dist/service/extendable-id-provider.cjs.js.map +1 -0
  20. package/dist/service/permission-definition-routes.cjs.js +104 -0
  21. package/dist/service/permission-definition-routes.cjs.js.map +1 -0
  22. package/dist/service/plugin-endpoints.cjs.js +5 -4
  23. package/dist/service/plugin-endpoints.cjs.js.map +1 -1
  24. package/dist/service/policies-rest-api.cjs.js +131 -125
  25. package/dist/service/policies-rest-api.cjs.js.map +1 -1
  26. package/dist/service/policy-builder.cjs.js +31 -15
  27. package/dist/service/policy-builder.cjs.js.map +1 -1
  28. package/dist/validation/plugin-validation.cjs.js +15 -0
  29. package/dist/validation/plugin-validation.cjs.js.map +1 -0
  30. package/migrations/20250509110032_migrations.js +29 -0
  31. package/package.json +4 -4
@@ -1 +1 @@
1
- {"version":3,"file":"plugin-endpoints.cjs.js","sources":["../../src/service/plugin-endpoints.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n FetchUrlReader,\n ReaderFactory,\n UrlReaders,\n} from '@backstage/backend-defaults/urlReader';\nimport type {\n AuthService,\n DiscoveryService,\n LoggerService,\n UrlReaderService,\n} from '@backstage/backend-plugin-api';\nimport type { Config } from '@backstage/config';\nimport { isError } from '@backstage/errors';\nimport {\n isResourcePermission,\n Permission,\n} from '@backstage/plugin-permission-common';\nimport type {\n MetadataResponse,\n MetadataResponseSerializedRule,\n} from '@backstage/plugin-permission-node';\n\nimport {\n policyEntityPermissions,\n type PluginPermissionMetaData,\n type PolicyDetails,\n} from '@backstage-community/plugin-rbac-common';\nimport type { PluginIdProvider } from '@backstage-community/plugin-rbac-node';\nimport { rbacRules } from '../permissions';\n\ntype PluginMetadataResponse = {\n pluginId: string;\n metaDataResponse: MetadataResponse;\n};\n\nexport type PluginMetadataResponseSerializedRule = {\n pluginId: string;\n rules: MetadataResponseSerializedRule[];\n};\n\nconst rbacPermissionMetadata: MetadataResponse = {\n permissions: policyEntityPermissions,\n rules: [rbacRules],\n};\n\nexport class PluginPermissionMetadataCollector {\n private readonly pluginIds: string[];\n private readonly discovery: DiscoveryService;\n private readonly logger: LoggerService;\n private readonly urlReader: UrlReaderService;\n\n constructor({\n deps,\n optional,\n }: {\n deps: {\n discovery: DiscoveryService;\n pluginIdProvider: PluginIdProvider;\n logger: LoggerService;\n config: Config;\n };\n optional?: {\n urlReader?: UrlReaderService;\n };\n }) {\n const { discovery, pluginIdProvider, logger, config } = deps;\n this.pluginIds = pluginIdProvider.getPluginIds();\n this.discovery = discovery;\n this.logger = logger;\n this.urlReader =\n optional?.urlReader ??\n UrlReaders.default({\n config,\n logger,\n factories: [PluginPermissionMetadataCollector.permissionFactory],\n });\n }\n\n async getPluginConditionRules(\n auth: AuthService,\n ): Promise<PluginMetadataResponseSerializedRule[]> {\n const pluginMetadata = await this.getPluginMetaData(auth);\n\n return pluginMetadata\n .filter(metadata => metadata.metaDataResponse.rules.length > 0)\n .map(metadata => {\n return {\n pluginId: metadata.pluginId,\n rules: metadata.metaDataResponse.rules,\n };\n });\n }\n\n async getPluginPolicies(\n auth: AuthService,\n ): Promise<PluginPermissionMetaData[]> {\n const pluginMetadata = await this.getPluginMetaData(auth);\n\n return pluginMetadata\n .filter(metadata => metadata.metaDataResponse.permissions !== undefined)\n .map(metadata => {\n return {\n pluginId: metadata.pluginId,\n policies: permissionsToCasbinPolicies(\n metadata.metaDataResponse.permissions!,\n ),\n };\n });\n }\n\n private static permissionFactory: ReaderFactory = () => {\n return [{ reader: new FetchUrlReader(), predicate: (_url: URL) => true }];\n };\n\n private async getPluginMetaData(\n auth: AuthService,\n ): Promise<PluginMetadataResponse[]> {\n let pluginResponses: PluginMetadataResponse[] = [];\n\n for (const pluginId of this.pluginIds) {\n try {\n const { token } = await auth.getPluginRequestToken({\n onBehalfOf: await auth.getOwnServiceCredentials(),\n targetPluginId: pluginId,\n });\n\n const permMetaData = await this.getMetadataByPluginId(pluginId, token);\n if (permMetaData) {\n pluginResponses = [\n ...pluginResponses,\n {\n metaDataResponse: permMetaData,\n pluginId,\n },\n ];\n }\n } catch (error) {\n this.logger.error(\n `Failed to retrieve permission metadata for ${pluginId}. ${error}`,\n );\n }\n }\n\n return pluginResponses;\n }\n\n async getMetadataByPluginId(\n pluginId: string,\n token: string | undefined,\n ): Promise<MetadataResponse | undefined> {\n let permMetaData: MetadataResponse | undefined;\n\n // Work around: This is needed for start up whenever a conditional policy for the plugin permission in the yaml file\n // will make a check to the well known endpoint\n // However, our plugin has not completely started and as such will throw a 503 error\n // TODO: see if we are able to remove this after we migrate to the permission registry\n if (pluginId === 'permission') {\n return rbacPermissionMetadata;\n }\n\n try {\n const baseEndpoint = await this.discovery.getBaseUrl(pluginId);\n const wellKnownURL = `${baseEndpoint}/.well-known/backstage/permissions/metadata`;\n\n const permResp = await this.urlReader.readUrl(wellKnownURL, { token });\n const permMetaDataRaw = (await permResp.buffer()).toString();\n\n try {\n permMetaData = JSON.parse(permMetaDataRaw);\n } catch (err) {\n // workaround for https://issues.redhat.com/browse/RHIDP-1456\n return undefined;\n }\n } catch (err) {\n if (isError(err) && err.name === 'NotFoundError') {\n this.logger.warn(\n `No permission metadata found for ${pluginId}. ${err}`,\n );\n return undefined;\n }\n this.logger.error(\n `Failed to retrieve permission metadata for ${pluginId}. ${err}`,\n );\n }\n return permMetaData;\n }\n}\n\nfunction permissionsToCasbinPolicies(\n permissions: Permission[],\n): PolicyDetails[] {\n const policies: PolicyDetails[] = [];\n for (const permission of permissions) {\n if (isResourcePermission(permission)) {\n policies.push({\n resourceType: permission.resourceType,\n name: permission.name,\n policy: permission.attributes.action || 'use',\n });\n } else {\n policies.push({\n name: permission.name,\n policy: permission.attributes.action || 'use',\n });\n }\n }\n\n return policies;\n}\n"],"names":["policyEntityPermissions","rbacRules","UrlReaders","FetchUrlReader","isError","isResourcePermission"],"mappings":"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"}
1
+ {"version":3,"file":"plugin-endpoints.cjs.js","sources":["../../src/service/plugin-endpoints.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n FetchUrlReader,\n ReaderFactory,\n UrlReaders,\n} from '@backstage/backend-defaults/urlReader';\nimport type {\n AuthService,\n DiscoveryService,\n LoggerService,\n UrlReaderService,\n} from '@backstage/backend-plugin-api';\nimport type { Config } from '@backstage/config';\nimport { isError } from '@backstage/errors';\nimport {\n isResourcePermission,\n Permission,\n} from '@backstage/plugin-permission-common';\nimport type {\n MetadataResponse,\n MetadataResponseSerializedRule,\n} from '@backstage/plugin-permission-node';\n\nimport {\n policyEntityPermissions,\n type PluginPermissionMetaData,\n type PolicyDetails,\n} from '@backstage-community/plugin-rbac-common';\nimport { rbacRules } from '../permissions';\nimport { ExtendablePluginIdProvider } from './extendable-id-provider';\n\ntype PluginMetadataResponse = {\n pluginId: string;\n metaDataResponse: MetadataResponse;\n};\n\nexport type PluginMetadataResponseSerializedRule = {\n pluginId: string;\n rules: MetadataResponseSerializedRule[];\n};\n\nconst rbacPermissionMetadata: MetadataResponse = {\n permissions: policyEntityPermissions,\n rules: [rbacRules],\n};\n\nexport class PluginPermissionMetadataCollector {\n private readonly pluginIdProvider: ExtendablePluginIdProvider;\n private readonly discovery: DiscoveryService;\n private readonly logger: LoggerService;\n private readonly urlReader: UrlReaderService;\n\n constructor({\n deps,\n optional,\n }: {\n deps: {\n discovery: DiscoveryService;\n pluginIdProvider: ExtendablePluginIdProvider;\n logger: LoggerService;\n config: Config;\n };\n optional?: {\n urlReader?: UrlReaderService;\n };\n }) {\n const { discovery, logger, config, pluginIdProvider } = deps;\n this.discovery = discovery;\n this.pluginIdProvider = pluginIdProvider;\n this.logger = logger;\n this.urlReader =\n optional?.urlReader ??\n UrlReaders.default({\n config,\n logger,\n factories: [PluginPermissionMetadataCollector.permissionFactory],\n });\n }\n\n async getPluginConditionRules(\n auth: AuthService,\n ): Promise<PluginMetadataResponseSerializedRule[]> {\n const pluginMetadata = await this.getPluginMetaData(auth);\n\n return pluginMetadata\n .filter(metadata => metadata.metaDataResponse.rules.length > 0)\n .map(metadata => {\n return {\n pluginId: metadata.pluginId,\n rules: metadata.metaDataResponse.rules,\n };\n });\n }\n\n async getPluginPolicies(\n auth: AuthService,\n ): Promise<PluginPermissionMetaData[]> {\n const pluginMetadata = await this.getPluginMetaData(auth);\n\n return pluginMetadata\n .filter(metadata => metadata.metaDataResponse.permissions !== undefined)\n .map(metadata => {\n return {\n pluginId: metadata.pluginId,\n policies: permissionsToCasbinPolicies(\n metadata.metaDataResponse.permissions!,\n ),\n };\n });\n }\n\n private static permissionFactory: ReaderFactory = () => {\n return [{ reader: new FetchUrlReader(), predicate: (_url: URL) => true }];\n };\n\n private async getPluginMetaData(\n auth: AuthService,\n ): Promise<PluginMetadataResponse[]> {\n let pluginResponses: PluginMetadataResponse[] = [];\n\n const pluginIds = await this.pluginIdProvider.getPluginIds();\n for (const pluginId of pluginIds) {\n try {\n const { token } = await auth.getPluginRequestToken({\n onBehalfOf: await auth.getOwnServiceCredentials(),\n targetPluginId: pluginId,\n });\n\n const permMetaData = await this.getMetadataByPluginId(pluginId, token);\n if (permMetaData) {\n pluginResponses = [\n ...pluginResponses,\n {\n metaDataResponse: permMetaData,\n pluginId,\n },\n ];\n }\n } catch (error) {\n this.logger.error(\n `Failed to retrieve permission metadata for ${pluginId}. ${error}`,\n );\n }\n }\n\n return pluginResponses;\n }\n\n async getMetadataByPluginId(\n pluginId: string,\n token: string | undefined,\n ): Promise<MetadataResponse | undefined> {\n let permMetaData: MetadataResponse | undefined;\n\n // Work around: This is needed for start up whenever a conditional policy for the plugin permission in the yaml file\n // will make a check to the well known endpoint\n // However, our plugin has not completely started and as such will throw a 503 error\n // TODO: see if we are able to remove this after we migrate to the permission registry\n if (pluginId === 'permission') {\n return rbacPermissionMetadata;\n }\n\n try {\n const baseEndpoint = await this.discovery.getBaseUrl(pluginId);\n const wellKnownURL = `${baseEndpoint}/.well-known/backstage/permissions/metadata`;\n\n const permResp = await this.urlReader.readUrl(wellKnownURL, { token });\n const permMetaDataRaw = (await permResp.buffer()).toString();\n\n try {\n permMetaData = JSON.parse(permMetaDataRaw);\n } catch (err) {\n // workaround for https://issues.redhat.com/browse/RHIDP-1456\n return undefined;\n }\n } catch (err) {\n if (isError(err) && err.name === 'NotFoundError') {\n this.logger.warn(\n `No permission metadata found for ${pluginId}. ${err}`,\n );\n return undefined;\n }\n this.logger.error(\n `Failed to retrieve permission metadata for ${pluginId}. ${err}`,\n );\n }\n return permMetaData;\n }\n}\n\nfunction permissionsToCasbinPolicies(\n permissions: Permission[],\n): PolicyDetails[] {\n const policies: PolicyDetails[] = [];\n for (const permission of permissions) {\n if (isResourcePermission(permission)) {\n policies.push({\n resourceType: permission.resourceType,\n name: permission.name,\n policy: permission.attributes.action || 'use',\n });\n } else {\n policies.push({\n name: permission.name,\n policy: permission.attributes.action || 'use',\n });\n }\n }\n\n return policies;\n}\n"],"names":["policyEntityPermissions","rbacRules","UrlReaders","FetchUrlReader","isError","isResourcePermission"],"mappings":"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"}
@@ -3,7 +3,6 @@
3
3
  var errors = require('@backstage/errors');
4
4
  var pluginPermissionBackend = require('@backstage/plugin-permission-backend');
5
5
  var pluginPermissionCommon = require('@backstage/plugin-permission-common');
6
- var pluginPermissionNode = require('@backstage/plugin-permission-node');
7
6
  var lodash = require('lodash');
8
7
  var pluginRbacCommon = require('@backstage-community/plugin-rbac-common');
9
8
  var restInterceptor = require('../auditor/rest-interceptor.cjs.js');
@@ -12,76 +11,73 @@ var helper = require('../helper.cjs.js');
12
11
  var conditionValidation = require('../validation/condition-validation.cjs.js');
13
12
  var policiesValidation = require('../validation/policies-validation.cjs.js');
14
13
  var conditions = require('../permissions/conditions.cjs.js');
15
- var rules = require('../permissions/rules.cjs.js');
14
+ require('../permissions/rules.cjs.js');
15
+ var permissionDefinitionRoutes = require('./permission-definition-routes.cjs.js');
16
16
 
17
+ async function authorizeConditional(request, permission, deps) {
18
+ const { auth, httpAuth, permissions } = deps;
19
+ const credentials = await httpAuth.credentials(request, {
20
+ allow: ["user", "service"]
21
+ });
22
+ if (auth.isPrincipal(credentials, "service") && permission !== pluginRbacCommon.policyEntityReadPermission) {
23
+ throw new errors.NotAllowedError(
24
+ `Only credential principal with type 'user' permitted to modify permissions`
25
+ );
26
+ }
27
+ let decision;
28
+ if (permission.type === "resource") {
29
+ decision = (await permissions.authorizeConditional([{ permission }], {
30
+ credentials
31
+ }))[0];
32
+ } else {
33
+ decision = (await permissions.authorize([{ permission }], {
34
+ credentials
35
+ }))[0];
36
+ }
37
+ if (decision.result === pluginPermissionCommon.AuthorizeResult.DENY) {
38
+ throw new errors.NotAllowedError();
39
+ }
40
+ return { decision, credentials };
41
+ }
17
42
  class PoliciesServer {
18
- constructor(permissions, options, enforcer, conditionalStorage, pluginPermMetaData, roleMetadata, auditor, rbacProviders) {
19
- this.permissions = permissions;
43
+ constructor(options, enforcer, conditionalStorage, pluginPermMetaData, roleMetadata, extraPluginsIdStorage, pluginIdProvider, rbacProviders) {
20
44
  this.options = options;
21
45
  this.enforcer = enforcer;
22
46
  this.conditionalStorage = conditionalStorage;
23
47
  this.pluginPermMetaData = pluginPermMetaData;
24
48
  this.roleMetadata = roleMetadata;
25
- this.auditor = auditor;
49
+ this.extraPluginsIdStorage = extraPluginsIdStorage;
50
+ this.pluginIdProvider = pluginIdProvider;
26
51
  this.rbacProviders = rbacProviders;
27
52
  }
28
- async authorizeConditional(request, permission) {
29
- const credentials = await this.options.httpAuth.credentials(request, {
30
- allow: ["user", "service"]
31
- });
32
- if (this.options.auth.isPrincipal(credentials, "service") && permission !== pluginRbacCommon.policyEntityReadPermission) {
33
- throw new errors.NotAllowedError(
34
- `Only credential principal with type 'user' permitted to modify permissions`
35
- );
36
- }
37
- let decision;
38
- if (permission.type === "resource") {
39
- decision = (await this.permissions.authorizeConditional([{ permission }], {
40
- credentials
41
- }))[0];
42
- } else {
43
- decision = (await this.permissions.authorize([{ permission }], {
44
- credentials
45
- }))[0];
46
- }
47
- if (decision.result === pluginPermissionCommon.AuthorizeResult.DENY) {
48
- throw new errors.NotAllowedError();
49
- }
50
- return { decision, credentials };
51
- }
52
53
  async serve() {
53
54
  const router = await pluginPermissionBackend.createRouter(this.options);
54
- const { logger } = this.options;
55
- const policyPermissionsIntegrationRouter = pluginPermissionNode.createPermissionIntegrationRouter({
56
- resourceType: pluginRbacCommon.RESOURCE_TYPE_POLICY_ENTITY,
57
- getResources: (resourceRefs) => Promise.all(
58
- resourceRefs.map((ref) => {
59
- return this.roleMetadata.findRoleMetadata(ref);
60
- })
61
- ),
62
- permissions: pluginRbacCommon.policyEntityPermissions,
63
- rules: Object.values(rules.rules)
64
- });
65
- router.use(policyPermissionsIntegrationRouter);
55
+ const { logger, auditor, auth, permissionsRegistry } = this.options;
66
56
  const isPluginEnabled = this.options.config.getOptionalBoolean("permission.enabled");
67
57
  if (!isPluginEnabled) {
68
58
  return router;
69
59
  }
60
+ const transformConditions = conditions.conditionTransformerFunc(permissionsRegistry);
70
61
  router.get("/", async (request, response) => {
71
- await this.authorizeConditional(request, pluginRbacCommon.policyEntityReadPermission);
62
+ await authorizeConditional(
63
+ request,
64
+ pluginRbacCommon.policyEntityReadPermission,
65
+ this.options
66
+ );
72
67
  response.send({ status: "Authorized" });
73
68
  });
74
69
  router.get(
75
70
  "/policies",
76
- restInterceptor.logAuditorEvent(this.auditor),
71
+ restInterceptor.logAuditorEvent(auditor),
77
72
  async (request, response) => {
78
73
  let conditionsFilter;
79
- const { decision } = await this.authorizeConditional(
74
+ const { decision } = await authorizeConditional(
80
75
  request,
81
- pluginRbacCommon.policyEntityReadPermission
76
+ pluginRbacCommon.policyEntityReadPermission,
77
+ this.options
82
78
  );
83
79
  if (decision.result === pluginPermissionCommon.AuthorizeResult.CONDITIONAL) {
84
- conditionsFilter = conditions.transformConditions(decision.conditions);
80
+ conditionsFilter = transformConditions(decision.conditions);
85
81
  }
86
82
  const roleMetadata = await this.roleMetadata.filterForOwnerRoleMetadata(conditionsFilter);
87
83
  let policies = [];
@@ -119,15 +115,16 @@ class PoliciesServer {
119
115
  );
120
116
  router.get(
121
117
  "/policies/:kind/:namespace/:name",
122
- restInterceptor.logAuditorEvent(this.auditor),
118
+ restInterceptor.logAuditorEvent(auditor),
123
119
  async (request, response) => {
124
120
  let conditionsFilter;
125
- const { decision } = await this.authorizeConditional(
121
+ const { decision } = await authorizeConditional(
126
122
  request,
127
- pluginRbacCommon.policyEntityReadPermission
123
+ pluginRbacCommon.policyEntityReadPermission,
124
+ this.options
128
125
  );
129
126
  if (decision.result === pluginPermissionCommon.AuthorizeResult.CONDITIONAL) {
130
- conditionsFilter = conditions.transformConditions(decision.conditions);
127
+ conditionsFilter = transformConditions(decision.conditions);
131
128
  }
132
129
  const roleMetadata = await this.roleMetadata.filterForOwnerRoleMetadata(conditionsFilter);
133
130
  const matchedRoleName = roleMetadata.flatMap((role) => {
@@ -153,15 +150,16 @@ class PoliciesServer {
153
150
  );
154
151
  router.delete(
155
152
  "/policies/:kind/:namespace/:name",
156
- restInterceptor.logAuditorEvent(this.auditor),
153
+ restInterceptor.logAuditorEvent(auditor),
157
154
  async (request, response) => {
158
155
  let conditionsFilter;
159
- const { decision } = await this.authorizeConditional(
156
+ const { decision } = await authorizeConditional(
160
157
  request,
161
- pluginRbacCommon.policyEntityDeletePermission
158
+ pluginRbacCommon.policyEntityDeletePermission,
159
+ this.options
162
160
  );
163
161
  if (decision.result === pluginPermissionCommon.AuthorizeResult.CONDITIONAL) {
164
- conditionsFilter = conditions.transformConditions(decision.conditions);
162
+ conditionsFilter = transformConditions(decision.conditions);
165
163
  }
166
164
  const entityRef = this.getEntityReference(request);
167
165
  const policyRaw = request.body;
@@ -184,9 +182,13 @@ class PoliciesServer {
184
182
  );
185
183
  router.post(
186
184
  "/policies",
187
- restInterceptor.logAuditorEvent(this.auditor),
185
+ restInterceptor.logAuditorEvent(auditor),
188
186
  async (request, response) => {
189
- await this.authorizeConditional(request, pluginRbacCommon.policyEntityCreatePermission);
187
+ await authorizeConditional(
188
+ request,
189
+ pluginRbacCommon.policyEntityCreatePermission,
190
+ this.options
191
+ );
190
192
  const policyRaw = request.body;
191
193
  if (lodash.isEmpty(policyRaw)) {
192
194
  throw new errors.InputError(`permission policy must be present`);
@@ -208,15 +210,16 @@ class PoliciesServer {
208
210
  );
209
211
  router.put(
210
212
  "/policies/:kind/:namespace/:name",
211
- restInterceptor.logAuditorEvent(this.auditor),
213
+ restInterceptor.logAuditorEvent(auditor),
212
214
  async (request, response) => {
213
215
  let conditionsFilter;
214
- const { decision } = await this.authorizeConditional(
216
+ const { decision } = await authorizeConditional(
215
217
  request,
216
- pluginRbacCommon.policyEntityUpdatePermission
218
+ pluginRbacCommon.policyEntityUpdatePermission,
219
+ this.options
217
220
  );
218
221
  if (decision.result === pluginPermissionCommon.AuthorizeResult.CONDITIONAL) {
219
- conditionsFilter = conditions.transformConditions(decision.conditions);
222
+ conditionsFilter = transformConditions(decision.conditions);
220
223
  }
221
224
  const entityRef = this.getEntityReference(request);
222
225
  const oldPolicyRaw = request.body.oldPolicy;
@@ -269,15 +272,16 @@ class PoliciesServer {
269
272
  );
270
273
  router.get(
271
274
  "/roles",
272
- restInterceptor.logAuditorEvent(this.auditor),
275
+ restInterceptor.logAuditorEvent(auditor),
273
276
  async (request, response) => {
274
277
  let conditionsFilter;
275
- const { decision } = await this.authorizeConditional(
278
+ const { decision } = await authorizeConditional(
276
279
  request,
277
- pluginRbacCommon.policyEntityReadPermission
280
+ pluginRbacCommon.policyEntityReadPermission,
281
+ this.options
278
282
  );
279
283
  if (decision.result === pluginPermissionCommon.AuthorizeResult.CONDITIONAL) {
280
- conditionsFilter = conditions.transformConditions(decision.conditions);
284
+ conditionsFilter = transformConditions(decision.conditions);
281
285
  }
282
286
  const roles = await this.enforcer.getGroupingPolicy();
283
287
  const body = await this.transformRoleArray(conditionsFilter, ...roles);
@@ -286,15 +290,16 @@ class PoliciesServer {
286
290
  );
287
291
  router.get(
288
292
  "/roles/:kind/:namespace/:name",
289
- restInterceptor.logAuditorEvent(this.auditor),
293
+ restInterceptor.logAuditorEvent(auditor),
290
294
  async (request, response) => {
291
295
  let conditionsFilter;
292
- const { decision } = await this.authorizeConditional(
296
+ const { decision } = await authorizeConditional(
293
297
  request,
294
- pluginRbacCommon.policyEntityReadPermission
298
+ pluginRbacCommon.policyEntityReadPermission,
299
+ this.options
295
300
  );
296
301
  if (decision.result === pluginPermissionCommon.AuthorizeResult.CONDITIONAL) {
297
- conditionsFilter = conditions.transformConditions(decision.conditions);
302
+ conditionsFilter = transformConditions(decision.conditions);
298
303
  }
299
304
  const roleEntityRef = this.getEntityReference(request, true);
300
305
  const role = await this.enforcer.getFilteredGroupingPolicy(
@@ -311,12 +316,13 @@ class PoliciesServer {
311
316
  );
312
317
  router.post(
313
318
  "/roles",
314
- restInterceptor.logAuditorEvent(this.auditor),
319
+ restInterceptor.logAuditorEvent(auditor),
315
320
  async (request, response) => {
316
321
  const uniqueItems = /* @__PURE__ */ new Set();
317
- const { credentials } = await this.authorizeConditional(
322
+ const { credentials } = await authorizeConditional(
318
323
  request,
319
- pluginRbacCommon.policyEntityCreatePermission
324
+ pluginRbacCommon.policyEntityCreatePermission,
325
+ this.options
320
326
  );
321
327
  const roleRaw = request.body;
322
328
  let err = policiesValidation.validateRole(roleRaw);
@@ -366,16 +372,17 @@ class PoliciesServer {
366
372
  );
367
373
  router.put(
368
374
  "/roles/:kind/:namespace/:name",
369
- restInterceptor.logAuditorEvent(this.auditor),
375
+ restInterceptor.logAuditorEvent(auditor),
370
376
  async (request, response) => {
371
377
  const uniqueItems = /* @__PURE__ */ new Set();
372
378
  let conditionsFilter;
373
- const { decision, credentials } = await this.authorizeConditional(
379
+ const { decision, credentials } = await authorizeConditional(
374
380
  request,
375
- pluginRbacCommon.policyEntityUpdatePermission
381
+ pluginRbacCommon.policyEntityUpdatePermission,
382
+ this.options
376
383
  );
377
384
  if (decision.result === pluginPermissionCommon.AuthorizeResult.CONDITIONAL) {
378
- conditionsFilter = conditions.transformConditions(decision.conditions);
385
+ conditionsFilter = transformConditions(decision.conditions);
379
386
  }
380
387
  const roleEntityRef = this.getEntityReference(request, true);
381
388
  const oldRoleRaw = request.body.oldRole;
@@ -492,15 +499,16 @@ class PoliciesServer {
492
499
  );
493
500
  router.delete(
494
501
  "/roles/:kind/:namespace/:name",
495
- restInterceptor.logAuditorEvent(this.auditor),
502
+ restInterceptor.logAuditorEvent(auditor),
496
503
  async (request, response) => {
497
504
  let conditionsFilter;
498
- const { decision, credentials } = await this.authorizeConditional(
505
+ const { decision, credentials } = await authorizeConditional(
499
506
  request,
500
- pluginRbacCommon.policyEntityDeletePermission
507
+ pluginRbacCommon.policyEntityDeletePermission,
508
+ this.options
501
509
  );
502
510
  if (decision.result === pluginPermissionCommon.AuthorizeResult.CONDITIONAL) {
503
- conditionsFilter = conditions.transformConditions(decision.conditions);
511
+ conditionsFilter = transformConditions(decision.conditions);
504
512
  }
505
513
  const roleEntityRef = this.getEntityReference(request, true);
506
514
  const currentMetadata = await this.roleMetadata.findRoleMetadata(roleEntityRef);
@@ -557,51 +565,30 @@ class PoliciesServer {
557
565
  response.status(204).end();
558
566
  }
559
567
  );
560
- router.get(
561
- "/plugins/policies",
562
- restInterceptor.logAuditorEvent(this.auditor),
563
- async (request, response) => {
564
- await this.authorizeConditional(request, pluginRbacCommon.policyEntityReadPermission);
565
- const body = await this.pluginPermMetaData.getPluginPolicies(
566
- this.options.auth
567
- );
568
- response.json(body);
569
- }
570
- );
571
- router.get(
572
- "/plugins/condition-rules",
573
- restInterceptor.logAuditorEvent(this.auditor),
574
- async (request, response) => {
575
- await this.authorizeConditional(request, pluginRbacCommon.policyEntityReadPermission);
576
- const body = await this.pluginPermMetaData.getPluginConditionRules(
577
- this.options.auth
578
- );
579
- response.json(body);
580
- }
581
- );
582
568
  router.get(
583
569
  "/roles/conditions",
584
- restInterceptor.logAuditorEvent(this.auditor),
570
+ restInterceptor.logAuditorEvent(auditor),
585
571
  async (request, response) => {
586
572
  let conditionsFilter;
587
- const { decision } = await this.authorizeConditional(
573
+ const { decision } = await authorizeConditional(
588
574
  request,
589
- pluginRbacCommon.policyEntityReadPermission
575
+ pluginRbacCommon.policyEntityReadPermission,
576
+ this.options
590
577
  );
591
578
  if (decision.result === pluginPermissionCommon.AuthorizeResult.CONDITIONAL) {
592
- conditionsFilter = conditions.transformConditions(decision.conditions);
579
+ conditionsFilter = transformConditions(decision.conditions);
593
580
  }
594
581
  const roleMetadata = await this.roleMetadata.filterForOwnerRoleMetadata(conditionsFilter);
595
582
  const matchedRoleName = roleMetadata.flatMap((role) => {
596
583
  return role.roleEntityRef;
597
584
  });
598
- const conditions$1 = await this.conditionalStorage.filterConditions(
585
+ const conditions = await this.conditionalStorage.filterConditions(
599
586
  this.getFirstQuery(request.query.roleEntityRef),
600
587
  this.getFirstQuery(request.query.pluginId),
601
588
  this.getFirstQuery(request.query.resourceType),
602
589
  this.getActionQueries(request.query.actions)
603
590
  );
604
- const body = conditions$1.map((condition) => {
591
+ const body = conditions.map((condition) => {
605
592
  return {
606
593
  ...condition,
607
594
  permissionMapping: condition.permissionMapping.map(
@@ -616,15 +603,19 @@ class PoliciesServer {
616
603
  );
617
604
  router.post(
618
605
  "/roles/conditions",
619
- restInterceptor.logAuditorEvent(this.auditor),
606
+ restInterceptor.logAuditorEvent(auditor),
620
607
  async (request, response) => {
621
- await this.authorizeConditional(request, pluginRbacCommon.policyEntityCreatePermission);
608
+ await authorizeConditional(
609
+ request,
610
+ pluginRbacCommon.policyEntityCreatePermission,
611
+ this.options
612
+ );
622
613
  const roleConditionPolicy = request.body;
623
614
  conditionValidation.validateRoleCondition(roleConditionPolicy);
624
615
  const conditionToCreate = await helper.processConditionMapping(
625
616
  roleConditionPolicy,
626
617
  this.pluginPermMetaData,
627
- this.options.auth
618
+ auth
628
619
  );
629
620
  const id = await this.conditionalStorage.createCondition(conditionToCreate);
630
621
  const body = { id };
@@ -634,12 +625,13 @@ class PoliciesServer {
634
625
  );
635
626
  router.get(
636
627
  "/roles/conditions/:id",
637
- restInterceptor.logAuditorEvent(this.auditor),
628
+ restInterceptor.logAuditorEvent(auditor),
638
629
  async (request, response) => {
639
630
  let conditionsFilter;
640
- const { decision } = await this.authorizeConditional(
631
+ const { decision } = await authorizeConditional(
641
632
  request,
642
- pluginRbacCommon.policyEntityReadPermission
633
+ pluginRbacCommon.policyEntityReadPermission,
634
+ this.options
643
635
  );
644
636
  const id = parseInt(request.params.id, 10);
645
637
  if (isNaN(id)) {
@@ -650,7 +642,7 @@ class PoliciesServer {
650
642
  throw new errors.NotFoundError();
651
643
  }
652
644
  if (decision.result === pluginPermissionCommon.AuthorizeResult.CONDITIONAL) {
653
- conditionsFilter = conditions.transformConditions(decision.conditions);
645
+ conditionsFilter = transformConditions(decision.conditions);
654
646
  }
655
647
  const roleMetadata = await this.roleMetadata.filterForOwnerRoleMetadata(conditionsFilter);
656
648
  const matchedRoleName = roleMetadata.flatMap((role) => {
@@ -667,15 +659,16 @@ class PoliciesServer {
667
659
  );
668
660
  router.delete(
669
661
  "/roles/conditions/:id",
670
- restInterceptor.logAuditorEvent(this.auditor),
662
+ restInterceptor.logAuditorEvent(auditor),
671
663
  async (request, response) => {
672
664
  let conditionsFilter;
673
- const { decision } = await this.authorizeConditional(
665
+ const { decision } = await authorizeConditional(
674
666
  request,
675
- pluginRbacCommon.policyEntityDeletePermission
667
+ pluginRbacCommon.policyEntityDeletePermission,
668
+ this.options
676
669
  );
677
670
  if (decision.result === pluginPermissionCommon.AuthorizeResult.CONDITIONAL) {
678
- conditionsFilter = conditions.transformConditions(decision.conditions);
671
+ conditionsFilter = transformConditions(decision.conditions);
679
672
  }
680
673
  const id = parseInt(request.params.id, 10);
681
674
  if (isNaN(id)) {
@@ -702,15 +695,16 @@ class PoliciesServer {
702
695
  );
703
696
  router.put(
704
697
  "/roles/conditions/:id",
705
- restInterceptor.logAuditorEvent(this.auditor),
698
+ restInterceptor.logAuditorEvent(auditor),
706
699
  async (request, response) => {
707
700
  let conditionsFilter;
708
- const { decision } = await this.authorizeConditional(
701
+ const { decision } = await authorizeConditional(
709
702
  request,
710
- pluginRbacCommon.policyEntityUpdatePermission
703
+ pluginRbacCommon.policyEntityUpdatePermission,
704
+ this.options
711
705
  );
712
706
  if (decision.result === pluginPermissionCommon.AuthorizeResult.CONDITIONAL) {
713
- conditionsFilter = conditions.transformConditions(decision.conditions);
707
+ conditionsFilter = transformConditions(decision.conditions);
714
708
  }
715
709
  const id = parseInt(request.params.id, 10);
716
710
  if (isNaN(id)) {
@@ -731,7 +725,7 @@ class PoliciesServer {
731
725
  const conditionToUpdate = await helper.processConditionMapping(
732
726
  roleConditionPolicy,
733
727
  this.pluginPermMetaData,
734
- this.options.auth
728
+ auth
735
729
  );
736
730
  await this.conditionalStorage.updateCondition(id, conditionToUpdate);
737
731
  response.locals.meta = { condition: roleConditionPolicy };
@@ -740,9 +734,13 @@ class PoliciesServer {
740
734
  );
741
735
  router.post(
742
736
  "/refresh/:id",
743
- restInterceptor.logAuditorEvent(this.auditor),
737
+ restInterceptor.logAuditorEvent(auditor),
744
738
  async (request, response) => {
745
- await this.authorizeConditional(request, pluginRbacCommon.policyEntityCreatePermission);
739
+ await authorizeConditional(
740
+ request,
741
+ pluginRbacCommon.policyEntityCreatePermission,
742
+ this.options
743
+ );
746
744
  if (!this.rbacProviders) {
747
745
  throw new errors.NotFoundError(`No RBAC providers were found`);
748
746
  }
@@ -759,6 +757,13 @@ class PoliciesServer {
759
757
  response.status(200).end();
760
758
  }
761
759
  );
760
+ permissionDefinitionRoutes.registerPermissionDefinitionRoutes(
761
+ router,
762
+ this.pluginPermMetaData,
763
+ this.pluginIdProvider,
764
+ this.extraPluginsIdStorage,
765
+ this.options
766
+ );
762
767
  router.use(restInterceptor.setAuditorError());
763
768
  return router;
764
769
  }
@@ -939,4 +944,5 @@ class PoliciesServer {
939
944
  }
940
945
 
941
946
  exports.PoliciesServer = PoliciesServer;
947
+ exports.authorizeConditional = authorizeConditional;
942
948
  //# sourceMappingURL=policies-rest-api.cjs.js.map