@backstage-community/plugin-rbac-backend 6.2.1 → 6.2.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 +12 -0
- package/dist/admin-permissions/admin-creation.cjs.js +1 -0
- package/dist/admin-permissions/admin-creation.cjs.js.map +1 -1
- package/dist/database/conditional-storage.cjs.js +18 -10
- package/dist/database/conditional-storage.cjs.js.map +1 -1
- package/dist/database/role-metadata.cjs.js.map +1 -1
- package/dist/service/enforcer-delegate.cjs.js +48 -9
- package/dist/service/enforcer-delegate.cjs.js.map +1 -1
- package/dist/service/policies-rest-api.cjs.js +29 -113
- package/dist/service/policies-rest-api.cjs.js.map +1 -1
- package/dist/service/policy-builder.cjs.js +1 -0
- package/dist/service/policy-builder.cjs.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
### Dependencies
|
|
2
2
|
|
|
3
|
+
## 6.2.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 9436665: Reduce rbac-backend requests to credentials API.
|
|
8
|
+
|
|
9
|
+
## 6.2.2
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- c92a50c: Fixed a bug where updating a role name via the `PUT </api/permission/roles/:kind/:namespace/:name>` endpoint did not propagate changes to metadata, permissions and conditions, leaving them mapped to the old role name.
|
|
14
|
+
|
|
3
15
|
## 6.2.1
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin-creation.cjs.js","sources":["../../src/admin-permissions/admin-creation.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 type { Config } from '@backstage/config';\n\nimport { Knex } from 'knex';\n\nimport { ActionType, PermissionEvents, RoleEvents } from '../auditor/auditor';\n\nimport {\n RoleMetadataDao,\n RoleMetadataStorage,\n} from '../database/role-metadata';\nimport { removeTheDifference } from '../helper';\nimport { EnforcerDelegate } from '../service/enforcer-delegate';\nimport { validateEntityReference } from '../validation/policies-validation';\nimport { AuditorService } from '@backstage/backend-plugin-api';\n\nexport const ADMIN_ROLE_NAME = 'role:default/rbac_admin';\nexport const ADMIN_ROLE_AUTHOR = 'application configuration';\nconst DEF_ADMIN_ROLE_DESCRIPTION =\n 'The default permission policy for the admin role allows for the creation, deletion, updating, and reading of roles and permission policies.';\n\nconst getAdminRoleMetadata = (): RoleMetadataDao => {\n const currentDate: Date = new Date();\n return {\n source: 'configuration',\n roleEntityRef: ADMIN_ROLE_NAME,\n description: DEF_ADMIN_ROLE_DESCRIPTION,\n author: ADMIN_ROLE_AUTHOR,\n modifiedBy: ADMIN_ROLE_AUTHOR,\n lastModified: currentDate.toUTCString(),\n createdAt: currentDate.toUTCString(),\n };\n};\n\nexport const useAdminsFromConfig = async (\n admins: Config[],\n enf: EnforcerDelegate,\n auditor: AuditorService,\n roleMetadataStorage: RoleMetadataStorage,\n knex: Knex,\n) => {\n const addedGroupPolicies = new Map<string, string>();\n const newGroupPolicies = new Map<string, string>();\n\n for (const admin of admins) {\n const entityRef = admin.getString('name').toLocaleLowerCase('en-US');\n validateEntityReference(entityRef);\n\n addedGroupPolicies.set(entityRef, ADMIN_ROLE_NAME);\n\n if (!(await enf.hasGroupingPolicy(...[entityRef, ADMIN_ROLE_NAME]))) {\n newGroupPolicies.set(entityRef, ADMIN_ROLE_NAME);\n }\n }\n\n const adminRoleMeta =\n await roleMetadataStorage.findRoleMetadata(ADMIN_ROLE_NAME);\n const addedRoleMembers = Array.from<string[]>(newGroupPolicies.entries());\n const meta = {\n ...getAdminRoleMetadata(),\n members: addedRoleMembers.map(gp => gp[0]),\n };\n const auditorEvent = await auditor.createEvent({\n eventId: RoleEvents.ROLE_WRITE,\n severityLevel: 'medium',\n meta: {\n actionType: adminRoleMeta ? ActionType.UPDATE : ActionType.CREATE,\n source: meta.source,\n },\n });\n\n const trx = await knex.transaction();\n try {\n if (!adminRoleMeta) {\n // even if there are no user, we still create default role metadata for admins\n await roleMetadataStorage.createRoleMetadata(getAdminRoleMetadata(), trx);\n } else if (adminRoleMeta.source === 'legacy') {\n await roleMetadataStorage.updateRoleMetadata(\n getAdminRoleMetadata(),\n ADMIN_ROLE_NAME,\n trx,\n );\n }\n\n await enf.addGroupingPolicies(\n addedRoleMembers,\n getAdminRoleMetadata(),\n trx,\n );\n\n await trx.commit();\n await auditorEvent.success({\n meta,\n });\n } catch (error) {\n await trx.rollback(error);\n await auditorEvent.fail({\n error,\n meta,\n });\n throw error;\n }\n\n const configGroupPolicies = await enf.getFilteredGroupingPolicy(\n 1,\n ADMIN_ROLE_NAME,\n );\n\n await removeTheDifference(\n configGroupPolicies.map(gp => gp[0]),\n Array.from<string>(addedGroupPolicies.keys()),\n 'configuration',\n ADMIN_ROLE_NAME,\n enf,\n auditor,\n ADMIN_ROLE_AUTHOR,\n );\n};\n\nconst addAdminPermissions = async (\n policies: string[][],\n enf: EnforcerDelegate,\n auditor: AuditorService,\n) => {\n const policiesToAdd: string[][] = [];\n for (const policy of policies) {\n if (!(await enf.hasPolicy(...policy))) {\n policiesToAdd.push(policy);\n }\n }\n\n const auditorEvent = await auditor.createEvent({\n eventId: PermissionEvents.POLICY_WRITE,\n severityLevel: 'medium',\n meta: { actionType: ActionType.CREATE, source: 'configuration' },\n });\n\n try {\n await enf.addPolicies(policiesToAdd);\n await auditorEvent.success({\n meta: { policies: policiesToAdd },\n });\n } catch (error) {\n await auditorEvent.fail({\n error,\n meta: { policies: policiesToAdd },\n });\n }\n};\n\nconst removeOldCreateAdminPermissions = async (\n enf: EnforcerDelegate,\n auditor: AuditorService,\n) => {\n const policyEntityCreate = [\n 'role:default/rbac_admin',\n 'policy-entity',\n 'create',\n 'allow',\n ];\n if (await enf.hasPolicy(...policyEntityCreate)) {\n const auditorEvent = await auditor.createEvent({\n eventId: PermissionEvents.POLICY_WRITE,\n severityLevel: 'medium',\n meta: { actionType: ActionType.DELETE, source: 'configuration' },\n });\n\n try {\n await enf.removePolicy(policyEntityCreate);\n await auditorEvent.success({\n meta: { policy: policyEntityCreate },\n });\n } catch (error) {\n await auditorEvent.fail({\n error,\n meta: { policy: policyEntityCreate },\n });\n }\n }\n};\n\nexport const setAdminPermissions = async (\n enf: EnforcerDelegate,\n auditor: AuditorService,\n) => {\n // TODO: Temporary workaround to prevent breakages after the removal of the resource type `policy-entity` from the permission `policy.entity.create`\n await removeOldCreateAdminPermissions(enf, auditor);\n const adminPermissions = [\n [ADMIN_ROLE_NAME, 'policy-entity', 'read', 'allow'],\n [ADMIN_ROLE_NAME, 'policy.entity.create', 'create', 'allow'],\n [ADMIN_ROLE_NAME, 'policy-entity', 'delete', 'allow'],\n [ADMIN_ROLE_NAME, 'policy-entity', 'update', 'allow'],\n // Needed for the RBAC frontend plugin.\n [ADMIN_ROLE_NAME, 'catalog-entity', 'read', 'allow'],\n ];\n await addAdminPermissions(adminPermissions, enf, auditor);\n};\n"],"names":["auditor","validateEntityReference","RoleEvents","ActionType","removeTheDifference","PermissionEvents"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"admin-creation.cjs.js","sources":["../../src/admin-permissions/admin-creation.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 type { Config } from '@backstage/config';\n\nimport { Knex } from 'knex';\n\nimport { ActionType, PermissionEvents, RoleEvents } from '../auditor/auditor';\n\nimport {\n RoleMetadataDao,\n RoleMetadataStorage,\n} from '../database/role-metadata';\nimport { removeTheDifference } from '../helper';\nimport { EnforcerDelegate } from '../service/enforcer-delegate';\nimport { validateEntityReference } from '../validation/policies-validation';\nimport { AuditorService } from '@backstage/backend-plugin-api';\n\nexport const ADMIN_ROLE_NAME = 'role:default/rbac_admin';\nexport const ADMIN_ROLE_AUTHOR = 'application configuration';\nconst DEF_ADMIN_ROLE_DESCRIPTION =\n 'The default permission policy for the admin role allows for the creation, deletion, updating, and reading of roles and permission policies.';\n\nconst getAdminRoleMetadata = (): RoleMetadataDao => {\n const currentDate: Date = new Date();\n return {\n source: 'configuration',\n roleEntityRef: ADMIN_ROLE_NAME,\n description: DEF_ADMIN_ROLE_DESCRIPTION,\n author: ADMIN_ROLE_AUTHOR,\n modifiedBy: ADMIN_ROLE_AUTHOR,\n lastModified: currentDate.toUTCString(),\n createdAt: currentDate.toUTCString(),\n };\n};\n\nexport const useAdminsFromConfig = async (\n admins: Config[],\n enf: EnforcerDelegate,\n auditor: AuditorService,\n roleMetadataStorage: RoleMetadataStorage,\n knex: Knex,\n) => {\n const addedGroupPolicies = new Map<string, string>();\n const newGroupPolicies = new Map<string, string>();\n\n for (const admin of admins) {\n const entityRef = admin.getString('name').toLocaleLowerCase('en-US');\n validateEntityReference(entityRef);\n\n addedGroupPolicies.set(entityRef, ADMIN_ROLE_NAME);\n\n if (!(await enf.hasGroupingPolicy(...[entityRef, ADMIN_ROLE_NAME]))) {\n newGroupPolicies.set(entityRef, ADMIN_ROLE_NAME);\n }\n }\n\n const adminRoleMeta =\n await roleMetadataStorage.findRoleMetadata(ADMIN_ROLE_NAME);\n const addedRoleMembers = Array.from<string[]>(newGroupPolicies.entries());\n const meta = {\n ...getAdminRoleMetadata(),\n members: addedRoleMembers.map(gp => gp[0]),\n };\n const auditorEvent = await auditor.createEvent({\n eventId: RoleEvents.ROLE_WRITE,\n severityLevel: 'medium',\n meta: {\n actionType: adminRoleMeta ? ActionType.UPDATE : ActionType.CREATE,\n source: meta.source,\n },\n });\n\n const trx = await knex.transaction();\n try {\n if (!adminRoleMeta) {\n // even if there are no user, we still create default role metadata for admins\n await roleMetadataStorage.createRoleMetadata(getAdminRoleMetadata(), trx);\n } else if (adminRoleMeta.source === 'legacy') {\n await roleMetadataStorage.updateRoleMetadata(\n getAdminRoleMetadata(),\n ADMIN_ROLE_NAME,\n trx,\n );\n }\n\n await enf.addGroupingPolicies(\n addedRoleMembers,\n getAdminRoleMetadata(),\n undefined,\n trx,\n );\n\n await trx.commit();\n await auditorEvent.success({\n meta,\n });\n } catch (error) {\n await trx.rollback(error);\n await auditorEvent.fail({\n error,\n meta,\n });\n throw error;\n }\n\n const configGroupPolicies = await enf.getFilteredGroupingPolicy(\n 1,\n ADMIN_ROLE_NAME,\n );\n\n await removeTheDifference(\n configGroupPolicies.map(gp => gp[0]),\n Array.from<string>(addedGroupPolicies.keys()),\n 'configuration',\n ADMIN_ROLE_NAME,\n enf,\n auditor,\n ADMIN_ROLE_AUTHOR,\n );\n};\n\nconst addAdminPermissions = async (\n policies: string[][],\n enf: EnforcerDelegate,\n auditor: AuditorService,\n) => {\n const policiesToAdd: string[][] = [];\n for (const policy of policies) {\n if (!(await enf.hasPolicy(...policy))) {\n policiesToAdd.push(policy);\n }\n }\n\n const auditorEvent = await auditor.createEvent({\n eventId: PermissionEvents.POLICY_WRITE,\n severityLevel: 'medium',\n meta: { actionType: ActionType.CREATE, source: 'configuration' },\n });\n\n try {\n await enf.addPolicies(policiesToAdd);\n await auditorEvent.success({\n meta: { policies: policiesToAdd },\n });\n } catch (error) {\n await auditorEvent.fail({\n error,\n meta: { policies: policiesToAdd },\n });\n }\n};\n\nconst removeOldCreateAdminPermissions = async (\n enf: EnforcerDelegate,\n auditor: AuditorService,\n) => {\n const policyEntityCreate = [\n 'role:default/rbac_admin',\n 'policy-entity',\n 'create',\n 'allow',\n ];\n if (await enf.hasPolicy(...policyEntityCreate)) {\n const auditorEvent = await auditor.createEvent({\n eventId: PermissionEvents.POLICY_WRITE,\n severityLevel: 'medium',\n meta: { actionType: ActionType.DELETE, source: 'configuration' },\n });\n\n try {\n await enf.removePolicy(policyEntityCreate);\n await auditorEvent.success({\n meta: { policy: policyEntityCreate },\n });\n } catch (error) {\n await auditorEvent.fail({\n error,\n meta: { policy: policyEntityCreate },\n });\n }\n }\n};\n\nexport const setAdminPermissions = async (\n enf: EnforcerDelegate,\n auditor: AuditorService,\n) => {\n // TODO: Temporary workaround to prevent breakages after the removal of the resource type `policy-entity` from the permission `policy.entity.create`\n await removeOldCreateAdminPermissions(enf, auditor);\n const adminPermissions = [\n [ADMIN_ROLE_NAME, 'policy-entity', 'read', 'allow'],\n [ADMIN_ROLE_NAME, 'policy.entity.create', 'create', 'allow'],\n [ADMIN_ROLE_NAME, 'policy-entity', 'delete', 'allow'],\n [ADMIN_ROLE_NAME, 'policy-entity', 'update', 'allow'],\n // Needed for the RBAC frontend plugin.\n [ADMIN_ROLE_NAME, 'catalog-entity', 'read', 'allow'],\n ];\n await addAdminPermissions(adminPermissions, enf, auditor);\n};\n"],"names":["auditor","validateEntityReference","RoleEvents","ActionType","removeTheDifference","PermissionEvents"],"mappings":"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"}
|
|
@@ -7,8 +7,9 @@ class DataBaseConditionalStorage {
|
|
|
7
7
|
constructor(knex) {
|
|
8
8
|
this.knex = knex;
|
|
9
9
|
}
|
|
10
|
-
async filterConditions(roleEntityRef, pluginId, resourceType, actions, permissionNames) {
|
|
11
|
-
const
|
|
10
|
+
async filterConditions(roleEntityRef, pluginId, resourceType, actions, permissionNames, trx) {
|
|
11
|
+
const db = trx ?? this.knex;
|
|
12
|
+
const daoRaws = await db.table(CONDITIONAL_TABLE).where((builder) => {
|
|
12
13
|
if (pluginId) {
|
|
13
14
|
builder.where("pluginId", pluginId);
|
|
14
15
|
}
|
|
@@ -57,11 +58,15 @@ class DataBaseConditionalStorage {
|
|
|
57
58
|
}
|
|
58
59
|
throw new Error(`Failed to create the condition.`);
|
|
59
60
|
}
|
|
60
|
-
async checkConflictedConditions(roleEntityRef, resourceType, pluginId, queryConditionActions, idToExclude) {
|
|
61
|
+
async checkConflictedConditions(roleEntityRef, resourceType, pluginId, queryConditionActions, idToExclude, trx) {
|
|
62
|
+
const db = trx ?? this.knex;
|
|
61
63
|
let conditionsForTheSameResource = await this.filterConditions(
|
|
62
64
|
roleEntityRef,
|
|
63
65
|
pluginId,
|
|
64
|
-
resourceType
|
|
66
|
+
resourceType,
|
|
67
|
+
undefined,
|
|
68
|
+
undefined,
|
|
69
|
+
db
|
|
65
70
|
);
|
|
66
71
|
conditionsForTheSameResource = conditionsForTheSameResource.filter(
|
|
67
72
|
(c) => c.id !== idToExclude
|
|
@@ -89,8 +94,9 @@ class DataBaseConditionalStorage {
|
|
|
89
94
|
}
|
|
90
95
|
}
|
|
91
96
|
}
|
|
92
|
-
async getCondition(id) {
|
|
93
|
-
const
|
|
97
|
+
async getCondition(id, trx) {
|
|
98
|
+
const db = trx ?? this.knex;
|
|
99
|
+
const daoRaw = await db.table(CONDITIONAL_TABLE).where("id", id).first();
|
|
94
100
|
if (daoRaw) {
|
|
95
101
|
return this.daoToConditionalDecision(daoRaw);
|
|
96
102
|
}
|
|
@@ -103,8 +109,9 @@ class DataBaseConditionalStorage {
|
|
|
103
109
|
}
|
|
104
110
|
await this.knex?.table(CONDITIONAL_TABLE).delete().whereIn("id", [id]);
|
|
105
111
|
}
|
|
106
|
-
async updateCondition(id, conditionalDecision) {
|
|
107
|
-
const
|
|
112
|
+
async updateCondition(id, conditionalDecision, trx) {
|
|
113
|
+
const db = trx ?? this.knex;
|
|
114
|
+
const condition = await this.getCondition(id, db);
|
|
108
115
|
if (!condition) {
|
|
109
116
|
throw new errors.NotFoundError(`Condition with id ${id} was not found`);
|
|
110
117
|
}
|
|
@@ -113,11 +120,12 @@ class DataBaseConditionalStorage {
|
|
|
113
120
|
conditionalDecision.resourceType,
|
|
114
121
|
conditionalDecision.pluginId,
|
|
115
122
|
conditionalDecision.permissionMapping.map((perm) => perm.action),
|
|
116
|
-
id
|
|
123
|
+
id,
|
|
124
|
+
db
|
|
117
125
|
);
|
|
118
126
|
const conditionRaw = this.toDAO(conditionalDecision);
|
|
119
127
|
conditionRaw.id = id;
|
|
120
|
-
const result = await
|
|
128
|
+
const result = await db.table(CONDITIONAL_TABLE).where("id", conditionRaw.id).update(conditionRaw).returning("id");
|
|
121
129
|
if (!result || result.length === 0) {
|
|
122
130
|
throw new Error(`Failed to update the condition with id: ${id}.`);
|
|
123
131
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conditional-storage.cjs.js","sources":["../../src/database/conditional-storage.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 { ConflictError, InputError, NotFoundError } from '@backstage/errors';\nimport { AuthorizeResult } from '@backstage/plugin-permission-common';\n\nimport { Knex } from 'knex';\n\nimport type {\n PermissionAction,\n PermissionInfo,\n RoleConditionalPolicyDecision,\n} from '@backstage-community/plugin-rbac-common';\n\nexport const CONDITIONAL_TABLE = 'role-condition-policies';\n\nexport interface ConditionalPolicyDecisionDAO {\n result: AuthorizeResult.CONDITIONAL;\n id?: number;\n roleEntityRef: string;\n permissions: string;\n pluginId: string;\n resourceType: string;\n conditionsJson: string;\n}\n\nexport interface ConditionalStorage {\n filterConditions(\n roleEntityRef?: string | string[],\n pluginId?: string,\n resourceType?: string,\n actions?: PermissionAction[],\n permissionNames?: string[],\n ): Promise<RoleConditionalPolicyDecision<PermissionInfo>[]>;\n createCondition(\n conditionalDecision: RoleConditionalPolicyDecision<PermissionInfo>,\n ): Promise<number>;\n checkConflictedConditions(\n roleEntityRef: string,\n resourceType: string,\n pluginId: string,\n queryPermissionNames: string[],\n idToExclude?: number,\n ): Promise<void>;\n getCondition(\n id: number,\n ): Promise<RoleConditionalPolicyDecision<PermissionInfo> | undefined>;\n deleteCondition(id: number): Promise<void>;\n updateCondition(\n id: number,\n conditionalDecision: RoleConditionalPolicyDecision<PermissionInfo>,\n ): Promise<void>;\n}\n\nexport class DataBaseConditionalStorage implements ConditionalStorage {\n public constructor(private readonly knex: Knex<any, any[]>) {}\n\n async filterConditions(\n roleEntityRef?: string | string[],\n pluginId?: string,\n resourceType?: string,\n actions?: PermissionAction[],\n permissionNames?: string[],\n ): Promise<RoleConditionalPolicyDecision<PermissionInfo>[]> {\n const daoRaws = await this.knex.table(CONDITIONAL_TABLE).where(builder => {\n if (pluginId) {\n builder.where('pluginId', pluginId);\n }\n if (resourceType) {\n builder.where('resourceType', resourceType);\n }\n if (roleEntityRef) {\n if (Array.isArray(roleEntityRef)) {\n builder.whereIn('roleEntityRef', roleEntityRef);\n } else {\n builder.where('roleEntityRef', roleEntityRef);\n }\n }\n });\n\n let conditions: RoleConditionalPolicyDecision<PermissionInfo>[] = [];\n if (daoRaws) {\n conditions = daoRaws.map(dao => this.daoToConditionalDecision(dao));\n }\n\n if (permissionNames && permissionNames.length > 0) {\n conditions = conditions.filter(condition => {\n return permissionNames.every(permissionName =>\n condition.permissionMapping\n .map(permInfo => permInfo.name)\n .includes(permissionName),\n );\n });\n }\n\n if (actions && actions.length > 0) {\n conditions = conditions.filter(condition => {\n return actions.every(action =>\n condition.permissionMapping\n .map(permInfo => permInfo.action)\n .includes(action),\n );\n });\n }\n\n return conditions;\n }\n\n async createCondition(\n conditionalDecision: RoleConditionalPolicyDecision<PermissionInfo>,\n ): Promise<number> {\n await this.checkConflictedConditions(\n conditionalDecision.roleEntityRef,\n conditionalDecision.resourceType,\n conditionalDecision.pluginId,\n conditionalDecision.permissionMapping.map(permInfo => permInfo.action),\n );\n\n const conditionRaw = this.toDAO(conditionalDecision);\n const result = await this.knex\n .table(CONDITIONAL_TABLE)\n .insert<ConditionalPolicyDecisionDAO>(conditionRaw)\n .returning('id');\n if (result && result?.length > 0) {\n return result[0].id;\n }\n\n throw new Error(`Failed to create the condition.`);\n }\n\n async checkConflictedConditions(\n roleEntityRef: string,\n resourceType: string,\n pluginId: string,\n queryConditionActions: PermissionAction[],\n idToExclude?: number,\n ): Promise<void> {\n let conditionsForTheSameResource = await this.filterConditions(\n roleEntityRef,\n pluginId,\n resourceType,\n );\n conditionsForTheSameResource = conditionsForTheSameResource.filter(\n c => c.id !== idToExclude,\n );\n\n if (conditionsForTheSameResource) {\n const conflictedCondition = conditionsForTheSameResource.find(\n condition => {\n const conditionActions = condition.permissionMapping.map(\n permInfo => permInfo.action,\n );\n return queryConditionActions.some(action =>\n conditionActions.includes(action),\n );\n },\n );\n\n if (conflictedCondition) {\n const conflictedActions = queryConditionActions.filter(action =>\n conflictedCondition.permissionMapping.some(p => p.action === action),\n );\n throw new ConflictError(\n `Found condition with conflicted permission action '${JSON.stringify(\n conflictedActions,\n )}'. Role could have multiple ` +\n `conditions for the same resource type '${conflictedCondition.resourceType}', but with different permission action sets.`,\n );\n }\n }\n }\n\n async getCondition(\n id: number,\n ): Promise<RoleConditionalPolicyDecision<PermissionInfo> | undefined> {\n const daoRaw = await this.knex\n .table(CONDITIONAL_TABLE)\n .where('id', id)\n .first();\n\n if (daoRaw) {\n return this.daoToConditionalDecision(daoRaw);\n }\n return undefined;\n }\n\n async deleteCondition(id: number): Promise<void> {\n const condition = await this.getCondition(id);\n if (!condition) {\n throw new NotFoundError(`Condition with id ${id} was not found`);\n }\n await this.knex?.table(CONDITIONAL_TABLE).delete().whereIn('id', [id]);\n }\n\n async updateCondition(\n id: number,\n conditionalDecision: RoleConditionalPolicyDecision<PermissionInfo>,\n ): Promise<void> {\n const condition = await this.getCondition(id);\n if (!condition) {\n throw new NotFoundError(`Condition with id ${id} was not found`);\n }\n\n await this.checkConflictedConditions(\n conditionalDecision.roleEntityRef,\n conditionalDecision.resourceType,\n conditionalDecision.pluginId,\n conditionalDecision.permissionMapping.map(perm => perm.action),\n id,\n );\n\n const conditionRaw = this.toDAO(conditionalDecision);\n conditionRaw.id = id;\n const result = await this.knex\n .table(CONDITIONAL_TABLE)\n .where('id', conditionRaw.id)\n .update<ConditionalPolicyDecisionDAO>(conditionRaw)\n .returning('id');\n\n if (!result || result.length === 0) {\n throw new Error(`Failed to update the condition with id: ${id}.`);\n }\n }\n\n private toDAO(\n conditionalDecision: RoleConditionalPolicyDecision<PermissionInfo>,\n ): ConditionalPolicyDecisionDAO {\n const {\n result,\n pluginId,\n resourceType,\n conditions,\n roleEntityRef,\n permissionMapping,\n } = conditionalDecision;\n const conditionsJson = JSON.stringify(conditions);\n return {\n result,\n pluginId,\n resourceType,\n conditionsJson,\n roleEntityRef,\n permissions: JSON.stringify(permissionMapping),\n };\n }\n\n private daoToConditionalDecision(\n dao: ConditionalPolicyDecisionDAO,\n ): RoleConditionalPolicyDecision<PermissionInfo> {\n if (!dao.id) {\n throw new InputError(`Missed id in the dao object: ${dao}`);\n }\n const {\n id,\n result,\n pluginId,\n resourceType,\n conditionsJson,\n roleEntityRef,\n permissions,\n } = dao;\n\n const conditions = JSON.parse(conditionsJson);\n return {\n id,\n result,\n pluginId,\n resourceType,\n conditions,\n roleEntityRef,\n permissionMapping: JSON.parse(permissions),\n };\n }\n}\n"],"names":["ConflictError","NotFoundError","InputError"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"conditional-storage.cjs.js","sources":["../../src/database/conditional-storage.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 { ConflictError, InputError, NotFoundError } from '@backstage/errors';\nimport { AuthorizeResult } from '@backstage/plugin-permission-common';\n\nimport { Knex } from 'knex';\n\nimport type {\n PermissionAction,\n PermissionInfo,\n RoleConditionalPolicyDecision,\n} from '@backstage-community/plugin-rbac-common';\n\nexport const CONDITIONAL_TABLE = 'role-condition-policies';\n\nexport interface ConditionalPolicyDecisionDAO {\n result: AuthorizeResult.CONDITIONAL;\n id?: number;\n roleEntityRef: string;\n permissions: string;\n pluginId: string;\n resourceType: string;\n conditionsJson: string;\n}\n\nexport interface ConditionalStorage {\n filterConditions(\n roleEntityRef?: string | string[],\n pluginId?: string,\n resourceType?: string,\n actions?: PermissionAction[],\n permissionNames?: string[],\n trx?: Knex.Transaction | Knex,\n ): Promise<RoleConditionalPolicyDecision<PermissionInfo>[]>;\n createCondition(\n conditionalDecision: RoleConditionalPolicyDecision<PermissionInfo>,\n ): Promise<number>;\n checkConflictedConditions(\n roleEntityRef: string,\n resourceType: string,\n pluginId: string,\n queryPermissionNames: string[],\n idToExclude?: number,\n ): Promise<void>;\n getCondition(\n id: number,\n trx?: Knex.Transaction | Knex,\n ): Promise<RoleConditionalPolicyDecision<PermissionInfo> | undefined>;\n deleteCondition(id: number): Promise<void>;\n updateCondition(\n id: number,\n conditionalDecision: RoleConditionalPolicyDecision<PermissionInfo>,\n trx?: Knex.Transaction,\n ): Promise<void>;\n}\n\nexport class DataBaseConditionalStorage implements ConditionalStorage {\n public constructor(private readonly knex: Knex<any, any[]>) {}\n\n async filterConditions(\n roleEntityRef?: string | string[],\n pluginId?: string,\n resourceType?: string,\n actions?: PermissionAction[],\n permissionNames?: string[],\n trx?: Knex.Transaction | Knex,\n ): Promise<RoleConditionalPolicyDecision<PermissionInfo>[]> {\n const db = trx ?? this.knex;\n const daoRaws = await db.table(CONDITIONAL_TABLE).where(builder => {\n if (pluginId) {\n builder.where('pluginId', pluginId);\n }\n if (resourceType) {\n builder.where('resourceType', resourceType);\n }\n if (roleEntityRef) {\n if (Array.isArray(roleEntityRef)) {\n builder.whereIn('roleEntityRef', roleEntityRef);\n } else {\n builder.where('roleEntityRef', roleEntityRef);\n }\n }\n });\n\n let conditions: RoleConditionalPolicyDecision<PermissionInfo>[] = [];\n if (daoRaws) {\n conditions = daoRaws.map(dao => this.daoToConditionalDecision(dao));\n }\n\n if (permissionNames && permissionNames.length > 0) {\n conditions = conditions.filter(condition => {\n return permissionNames.every(permissionName =>\n condition.permissionMapping\n .map(permInfo => permInfo.name)\n .includes(permissionName),\n );\n });\n }\n\n if (actions && actions.length > 0) {\n conditions = conditions.filter(condition => {\n return actions.every(action =>\n condition.permissionMapping\n .map(permInfo => permInfo.action)\n .includes(action),\n );\n });\n }\n\n return conditions;\n }\n\n async createCondition(\n conditionalDecision: RoleConditionalPolicyDecision<PermissionInfo>,\n ): Promise<number> {\n await this.checkConflictedConditions(\n conditionalDecision.roleEntityRef,\n conditionalDecision.resourceType,\n conditionalDecision.pluginId,\n conditionalDecision.permissionMapping.map(permInfo => permInfo.action),\n );\n\n const conditionRaw = this.toDAO(conditionalDecision);\n const result = await this.knex\n .table(CONDITIONAL_TABLE)\n .insert<ConditionalPolicyDecisionDAO>(conditionRaw)\n .returning('id');\n if (result && result?.length > 0) {\n return result[0].id;\n }\n\n throw new Error(`Failed to create the condition.`);\n }\n\n async checkConflictedConditions(\n roleEntityRef: string,\n resourceType: string,\n pluginId: string,\n queryConditionActions: PermissionAction[],\n idToExclude?: number,\n trx?: Knex.Transaction | Knex,\n ): Promise<void> {\n const db = trx ?? this.knex;\n let conditionsForTheSameResource = await this.filterConditions(\n roleEntityRef,\n pluginId,\n resourceType,\n undefined,\n undefined,\n db,\n );\n conditionsForTheSameResource = conditionsForTheSameResource.filter(\n c => c.id !== idToExclude,\n );\n\n if (conditionsForTheSameResource) {\n const conflictedCondition = conditionsForTheSameResource.find(\n condition => {\n const conditionActions = condition.permissionMapping.map(\n permInfo => permInfo.action,\n );\n return queryConditionActions.some(action =>\n conditionActions.includes(action),\n );\n },\n );\n\n if (conflictedCondition) {\n const conflictedActions = queryConditionActions.filter(action =>\n conflictedCondition.permissionMapping.some(p => p.action === action),\n );\n throw new ConflictError(\n `Found condition with conflicted permission action '${JSON.stringify(\n conflictedActions,\n )}'. Role could have multiple ` +\n `conditions for the same resource type '${conflictedCondition.resourceType}', but with different permission action sets.`,\n );\n }\n }\n }\n\n async getCondition(\n id: number,\n trx?: Knex.Transaction | Knex,\n ): Promise<RoleConditionalPolicyDecision<PermissionInfo> | undefined> {\n const db = trx ?? this.knex;\n const daoRaw = await db.table(CONDITIONAL_TABLE).where('id', id).first();\n\n if (daoRaw) {\n return this.daoToConditionalDecision(daoRaw);\n }\n return undefined;\n }\n\n async deleteCondition(id: number): Promise<void> {\n const condition = await this.getCondition(id);\n if (!condition) {\n throw new NotFoundError(`Condition with id ${id} was not found`);\n }\n await this.knex?.table(CONDITIONAL_TABLE).delete().whereIn('id', [id]);\n }\n\n async updateCondition(\n id: number,\n conditionalDecision: RoleConditionalPolicyDecision<PermissionInfo>,\n trx?: Knex.Transaction,\n ): Promise<void> {\n const db = trx ?? this.knex;\n const condition = await this.getCondition(id, db);\n if (!condition) {\n throw new NotFoundError(`Condition with id ${id} was not found`);\n }\n\n await this.checkConflictedConditions(\n conditionalDecision.roleEntityRef,\n conditionalDecision.resourceType,\n conditionalDecision.pluginId,\n conditionalDecision.permissionMapping.map(perm => perm.action),\n id,\n db,\n );\n\n const conditionRaw = this.toDAO(conditionalDecision);\n conditionRaw.id = id;\n const result = await db\n .table(CONDITIONAL_TABLE)\n .where('id', conditionRaw.id)\n .update<ConditionalPolicyDecisionDAO>(conditionRaw)\n .returning('id');\n\n if (!result || result.length === 0) {\n throw new Error(`Failed to update the condition with id: ${id}.`);\n }\n }\n\n private toDAO(\n conditionalDecision: RoleConditionalPolicyDecision<PermissionInfo>,\n ): ConditionalPolicyDecisionDAO {\n const {\n result,\n pluginId,\n resourceType,\n conditions,\n roleEntityRef,\n permissionMapping,\n } = conditionalDecision;\n const conditionsJson = JSON.stringify(conditions);\n return {\n result,\n pluginId,\n resourceType,\n conditionsJson,\n roleEntityRef,\n permissions: JSON.stringify(permissionMapping),\n };\n }\n\n private daoToConditionalDecision(\n dao: ConditionalPolicyDecisionDAO,\n ): RoleConditionalPolicyDecision<PermissionInfo> {\n if (!dao.id) {\n throw new InputError(`Missed id in the dao object: ${dao}`);\n }\n const {\n id,\n result,\n pluginId,\n resourceType,\n conditionsJson,\n roleEntityRef,\n permissions,\n } = dao;\n\n const conditions = JSON.parse(conditionsJson);\n return {\n id,\n result,\n pluginId,\n resourceType,\n conditions,\n roleEntityRef,\n permissionMapping: JSON.parse(permissions),\n };\n }\n}\n"],"names":["ConflictError","NotFoundError","InputError"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"role-metadata.cjs.js","sources":["../../src/database/role-metadata.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 { ConflictError, InputError, NotFoundError } from '@backstage/errors';\n\nimport { Knex } from 'knex';\n\nimport type {\n RoleMetadata,\n Source,\n} from '@backstage-community/plugin-rbac-common';\n\nimport { deepSortedEqual } from '../helper';\nimport { RBACFilters } from '../permissions';\nimport { matches } from '../helper';\n\nexport const ROLE_METADATA_TABLE = 'role-metadata';\n\nexport interface RoleMetadataDao extends RoleMetadata {\n id?: number;\n roleEntityRef: string;\n source: Source;\n modifiedBy: string;\n}\n\nexport interface RoleMetadataStorage {\n filterRoleMetadata(source?: Source): Promise<RoleMetadataDao[]>;\n filterForOwnerRoleMetadata(filter?: RBACFilters): Promise<RoleMetadataDao[]>;\n findRoleMetadata(\n roleEntityRef: string,\n trx?: Knex.Transaction,\n ): Promise<RoleMetadataDao | undefined>;\n createRoleMetadata(\n roleMetadata: RoleMetadataDao,\n trx: Knex.Transaction,\n ): Promise<number>;\n updateRoleMetadata(\n roleMetadata: RoleMetadataDao,\n oldRoleEntityRef: string,\n externalTrx?: Knex.Transaction,\n ): Promise<void>;\n removeRoleMetadata(\n roleEntityRef: string,\n trx: Knex.Transaction,\n ): Promise<void>;\n}\n\nexport class DataBaseRoleMetadataStorage implements RoleMetadataStorage {\n constructor(private readonly knex: Knex<any, any[]>) {}\n\n async filterRoleMetadata(source?: Source): Promise<RoleMetadataDao[]> {\n return await this.knex.table(ROLE_METADATA_TABLE).where(builder => {\n if (source) {\n builder.where('source', source);\n }\n });\n }\n\n async filterForOwnerRoleMetadata(\n filter?: RBACFilters,\n ): Promise<RoleMetadataDao[]> {\n const roleMetadata: RoleMetadataDao[] =\n await this.knex.table(ROLE_METADATA_TABLE);\n\n if (filter) {\n return roleMetadata.filter(role => {\n return matches(role as RoleMetadata, filter);\n });\n }\n\n return roleMetadata;\n }\n\n async findRoleMetadata(\n roleEntityRef: string,\n trx
|
|
1
|
+
{"version":3,"file":"role-metadata.cjs.js","sources":["../../src/database/role-metadata.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 { ConflictError, InputError, NotFoundError } from '@backstage/errors';\n\nimport { Knex } from 'knex';\n\nimport type {\n RoleMetadata,\n Source,\n} from '@backstage-community/plugin-rbac-common';\n\nimport { deepSortedEqual } from '../helper';\nimport { RBACFilters } from '../permissions';\nimport { matches } from '../helper';\n\nexport const ROLE_METADATA_TABLE = 'role-metadata';\n\nexport interface RoleMetadataDao extends RoleMetadata {\n id?: number;\n roleEntityRef: string;\n source: Source;\n modifiedBy: string;\n}\n\nexport interface RoleMetadataStorage {\n filterRoleMetadata(source?: Source): Promise<RoleMetadataDao[]>;\n filterForOwnerRoleMetadata(filter?: RBACFilters): Promise<RoleMetadataDao[]>;\n findRoleMetadata(\n roleEntityRef: string,\n trx?: Knex.Transaction,\n ): Promise<RoleMetadataDao | undefined>;\n createRoleMetadata(\n roleMetadata: RoleMetadataDao,\n trx: Knex.Transaction,\n ): Promise<number>;\n updateRoleMetadata(\n roleMetadata: RoleMetadataDao,\n oldRoleEntityRef: string,\n externalTrx?: Knex.Transaction,\n ): Promise<void>;\n removeRoleMetadata(\n roleEntityRef: string,\n trx: Knex.Transaction,\n ): Promise<void>;\n}\n\nexport class DataBaseRoleMetadataStorage implements RoleMetadataStorage {\n constructor(private readonly knex: Knex<any, any[]>) {}\n\n async filterRoleMetadata(source?: Source): Promise<RoleMetadataDao[]> {\n return await this.knex.table(ROLE_METADATA_TABLE).where(builder => {\n if (source) {\n builder.where('source', source);\n }\n });\n }\n\n async filterForOwnerRoleMetadata(\n filter?: RBACFilters,\n ): Promise<RoleMetadataDao[]> {\n const roleMetadata: RoleMetadataDao[] =\n await this.knex.table(ROLE_METADATA_TABLE);\n\n if (filter) {\n return roleMetadata.filter(role => {\n return matches(role as RoleMetadata, filter);\n });\n }\n\n return roleMetadata;\n }\n\n async findRoleMetadata(\n roleEntityRef: string,\n trx?: Knex.Transaction,\n ): Promise<RoleMetadataDao | undefined> {\n const db = trx || this.knex;\n return await db\n .table(ROLE_METADATA_TABLE)\n .where('roleEntityRef', roleEntityRef)\n // roleEntityRef should be unique.\n .first();\n }\n\n async createRoleMetadata(\n metadata: RoleMetadataDao,\n trx: Knex.Transaction,\n ): Promise<number> {\n if (await this.findRoleMetadata(metadata.roleEntityRef, trx)) {\n throw new ConflictError(\n `A metadata for role ${metadata.roleEntityRef} has already been stored`,\n );\n }\n\n const result = await trx<RoleMetadataDao>(ROLE_METADATA_TABLE)\n .insert(metadata)\n .returning<[{ id: number }]>('id');\n if (result && result?.length > 0) {\n return result[0].id;\n }\n\n throw new Error(\n `Failed to create the role metadata: '${JSON.stringify(metadata)}'.`,\n );\n }\n\n async updateRoleMetadata(\n newRoleMetadata: RoleMetadataDao,\n oldRoleEntityRef: string,\n externalTrx?: Knex.Transaction,\n ): Promise<void> {\n const trx = externalTrx ?? (await this.knex.transaction());\n const currentMetadataDao = await this.findRoleMetadata(\n oldRoleEntityRef,\n trx,\n );\n\n if (!currentMetadataDao) {\n throw new NotFoundError(\n `A metadata for role '${oldRoleEntityRef}' was not found`,\n );\n }\n\n if (\n currentMetadataDao.source !== 'legacy' &&\n currentMetadataDao.source !== newRoleMetadata.source\n ) {\n throw new InputError(`The RoleMetadata.source field is 'read-only'.`);\n }\n\n if (deepSortedEqual(currentMetadataDao, newRoleMetadata)) {\n return;\n }\n\n const result = await trx<RoleMetadataDao>(ROLE_METADATA_TABLE)\n .where('id', currentMetadataDao.id)\n .update(newRoleMetadata)\n .returning('id');\n\n if (!externalTrx) {\n await trx.commit();\n }\n\n if (!result || result.length === 0) {\n throw new Error(\n `Failed to update the role metadata '${JSON.stringify(\n currentMetadataDao,\n )}' with new value: '${JSON.stringify(newRoleMetadata)}'.`,\n );\n }\n }\n\n async removeRoleMetadata(\n roleEntityRef: string,\n trx: Knex.Transaction,\n ): Promise<void> {\n const metadataDao = await this.findRoleMetadata(roleEntityRef, trx);\n if (!metadataDao) {\n throw new NotFoundError(\n `A metadata for role '${roleEntityRef}' was not found`,\n );\n }\n\n await trx<RoleMetadataDao>(ROLE_METADATA_TABLE)\n .delete()\n .whereIn('id', [metadataDao.id!]);\n }\n}\n\nexport function daoToMetadata(dao: RoleMetadataDao): RoleMetadata {\n return {\n source: dao.source,\n description: dao.description,\n owner: dao.owner,\n author: dao.author,\n modifiedBy: dao.modifiedBy,\n createdAt: dao.createdAt,\n lastModified: dao.lastModified,\n };\n}\n"],"names":["matches","ConflictError","NotFoundError","InputError","deepSortedEqual"],"mappings":"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"}
|
|
@@ -13,9 +13,10 @@ var EventEmitter__default = /*#__PURE__*/_interopDefaultCompat(EventEmitter);
|
|
|
13
13
|
|
|
14
14
|
class EnforcerDelegate {
|
|
15
15
|
// Queue to track edit operations
|
|
16
|
-
constructor(enforcer, auditor, roleMetadataStorage, knex) {
|
|
16
|
+
constructor(enforcer, auditor, conditionalStorage, roleMetadataStorage, knex) {
|
|
17
17
|
this.enforcer = enforcer;
|
|
18
18
|
this.auditor = auditor;
|
|
19
|
+
this.conditionalStorage = conditionalStorage;
|
|
19
20
|
this.roleMetadataStorage = roleMetadataStorage;
|
|
20
21
|
this.knex = knex;
|
|
21
22
|
}
|
|
@@ -242,7 +243,7 @@ class EnforcerDelegate {
|
|
|
242
243
|
})();
|
|
243
244
|
await this.execOperation(addGroupingPolicyOperation);
|
|
244
245
|
}
|
|
245
|
-
async addGroupingPolicies(policies, roleMetadata, externalTrx) {
|
|
246
|
+
async addGroupingPolicies(policies, roleMetadata, oldRoleEntityRef, externalTrx) {
|
|
246
247
|
if (this.loadPolicyPromise) {
|
|
247
248
|
await this.loadPolicyPromise;
|
|
248
249
|
} else {
|
|
@@ -255,13 +256,13 @@ class EnforcerDelegate {
|
|
|
255
256
|
const trx = externalTrx ?? await this.knex.transaction();
|
|
256
257
|
try {
|
|
257
258
|
const currentRoleMetadata = await this.roleMetadataStorage.findRoleMetadata(
|
|
258
|
-
roleMetadata.roleEntityRef,
|
|
259
|
+
oldRoleEntityRef ?? roleMetadata.roleEntityRef,
|
|
259
260
|
trx
|
|
260
261
|
);
|
|
261
262
|
if (currentRoleMetadata) {
|
|
262
263
|
await this.roleMetadataStorage.updateRoleMetadata(
|
|
263
264
|
helper.mergeRoleMetadata(currentRoleMetadata, roleMetadata),
|
|
264
|
-
roleMetadata.roleEntityRef,
|
|
265
|
+
oldRoleEntityRef ?? roleMetadata.roleEntityRef,
|
|
265
266
|
trx
|
|
266
267
|
);
|
|
267
268
|
} else {
|
|
@@ -303,21 +304,59 @@ class EnforcerDelegate {
|
|
|
303
304
|
throw new Error(`Role metadata ${oldRoleName} was not found`);
|
|
304
305
|
}
|
|
305
306
|
await this.removeGroupingPolicies(oldRole, currentMetadata, true, trx);
|
|
306
|
-
await this.addGroupingPolicies(
|
|
307
|
+
await this.addGroupingPolicies(
|
|
308
|
+
newRole,
|
|
309
|
+
newRoleMetadata,
|
|
310
|
+
currentMetadata.roleEntityRef,
|
|
311
|
+
trx
|
|
312
|
+
);
|
|
313
|
+
if (newRoleMetadata.roleEntityRef !== currentMetadata.roleEntityRef) {
|
|
314
|
+
const oldPolicies = await this.enforcer.getFilteredPolicy(
|
|
315
|
+
0,
|
|
316
|
+
currentMetadata.roleEntityRef
|
|
317
|
+
);
|
|
318
|
+
const updatedPolicies = oldPolicies.map((oldPolicy) => [
|
|
319
|
+
newRoleMetadata.roleEntityRef,
|
|
320
|
+
...oldPolicy.slice(1)
|
|
321
|
+
]);
|
|
322
|
+
await this.updatePolicies(oldPolicies, updatedPolicies, trx);
|
|
323
|
+
const oldConditions = await this.conditionalStorage.filterConditions(
|
|
324
|
+
currentMetadata.roleEntityRef,
|
|
325
|
+
void 0,
|
|
326
|
+
void 0,
|
|
327
|
+
void 0,
|
|
328
|
+
void 0,
|
|
329
|
+
trx
|
|
330
|
+
);
|
|
331
|
+
for (const condition of oldConditions) {
|
|
332
|
+
await this.conditionalStorage.updateCondition(
|
|
333
|
+
condition.id,
|
|
334
|
+
{
|
|
335
|
+
...condition,
|
|
336
|
+
roleEntityRef: newRoleMetadata.roleEntityRef
|
|
337
|
+
},
|
|
338
|
+
trx
|
|
339
|
+
);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
307
342
|
await trx.commit();
|
|
308
343
|
} catch (err) {
|
|
309
344
|
await trx.rollback(err);
|
|
310
345
|
throw err;
|
|
311
346
|
}
|
|
312
347
|
}
|
|
313
|
-
async updatePolicies(oldPolicies, newPolicies) {
|
|
314
|
-
const trx = await this.knex.transaction();
|
|
348
|
+
async updatePolicies(oldPolicies, newPolicies, externalTrx) {
|
|
349
|
+
const trx = externalTrx ?? await this.knex.transaction();
|
|
315
350
|
try {
|
|
316
351
|
await this.removePolicies(oldPolicies, trx);
|
|
317
352
|
await this.addPolicies(newPolicies, trx);
|
|
318
|
-
|
|
353
|
+
if (!externalTrx) {
|
|
354
|
+
await trx.commit();
|
|
355
|
+
}
|
|
319
356
|
} catch (err) {
|
|
320
|
-
|
|
357
|
+
if (!externalTrx) {
|
|
358
|
+
await trx.rollback(err);
|
|
359
|
+
}
|
|
321
360
|
throw err;
|
|
322
361
|
}
|
|
323
362
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"enforcer-delegate.cjs.js","sources":["../../src/service/enforcer-delegate.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 { Enforcer, FilteredAdapter, newModelFromString } from 'casbin';\nimport { Knex } from 'knex';\n\nimport EventEmitter from 'events';\n\nimport { ADMIN_ROLE_NAME } from '../admin-permissions/admin-creation';\nimport {\n RoleMetadataDao,\n RoleMetadataStorage,\n} from '../database/role-metadata';\nimport { mergeRoleMetadata, policiesToString, policyToString } from '../helper';\nimport { MODEL } from './permission-model';\nimport { PoliciesData } from '../auditor/auditor';\nimport { AuditorService } from '@backstage/backend-plugin-api';\n\nexport type RoleEvents = 'roleAdded';\nexport interface RoleEventEmitter<T extends RoleEvents> {\n on(event: T, listener: (roleEntityRef: string | string[]) => void): this;\n}\n\ntype EventMap = {\n [event in RoleEvents]: any[];\n};\n\nexport class EnforcerDelegate implements RoleEventEmitter<RoleEvents> {\n private readonly roleEventEmitter = new EventEmitter<EventMap>();\n\n private loadPolicyPromise: Promise<void> | null = null;\n private editOperationsQueue: Promise<any>[] = []; // Queue to track edit operations\n\n constructor(\n private readonly enforcer: Enforcer,\n private readonly auditor: AuditorService,\n private readonly roleMetadataStorage: RoleMetadataStorage,\n private readonly knex: Knex,\n ) {}\n\n async loadPolicy(): Promise<void> {\n if (this.loadPolicyPromise) {\n // If a load operation is already in progress, return the cached promise\n return this.loadPolicyPromise;\n }\n\n this.loadPolicyPromise = (async () => {\n try {\n await this.waitForEditOperationsToFinish();\n\n await this.enforcer.loadPolicy();\n } catch (error) {\n const auditorEvent = await this.auditor.createEvent({\n eventId: PoliciesData.PERMISSIONS_READ,\n severityLevel: 'medium',\n });\n await auditorEvent.fail({ error });\n } finally {\n this.loadPolicyPromise = null;\n }\n })();\n\n return this.loadPolicyPromise;\n }\n\n private async waitForEditOperationsToFinish(): Promise<void> {\n await Promise.all(this.editOperationsQueue);\n }\n\n async execOperation<T>(operation: Promise<T>): Promise<T> {\n this.editOperationsQueue.push(operation);\n\n let result;\n try {\n result = await operation;\n } catch (err) {\n throw err;\n } finally {\n const index = this.editOperationsQueue.indexOf(operation);\n if (index !== -1) {\n this.editOperationsQueue.splice(index, 1);\n }\n }\n\n return result;\n }\n\n on(event: RoleEvents, listener: (role: string) => void): this {\n this.roleEventEmitter.on(event, listener);\n return this;\n }\n\n async hasPolicy(...policy: string[]): Promise<boolean> {\n const tempModel = newModelFromString(MODEL);\n await (this.enforcer.getAdapter() as FilteredAdapter).loadFilteredPolicy(\n tempModel,\n [\n {\n ptype: 'p',\n v0: policy[0],\n v1: policy[1],\n v2: policy[2],\n v3: policy[3],\n },\n ],\n );\n return tempModel.hasPolicy('p', 'p', policy);\n }\n\n async hasGroupingPolicy(...policy: string[]): Promise<boolean> {\n const tempModel = newModelFromString(MODEL);\n await (this.enforcer.getAdapter() as FilteredAdapter).loadFilteredPolicy(\n tempModel,\n [\n {\n ptype: 'g',\n v0: policy[0],\n v1: policy[1],\n },\n ],\n );\n return tempModel.hasPolicy('g', 'g', policy);\n }\n\n async getPolicy(): Promise<string[][]> {\n const tempModel = newModelFromString(MODEL);\n await (this.enforcer.getAdapter() as FilteredAdapter).loadFilteredPolicy(\n tempModel,\n [{ ptype: 'p' }],\n );\n return await tempModel.getPolicy('p', 'p');\n }\n\n async getGroupingPolicy(): Promise<string[][]> {\n const tempModel = newModelFromString(MODEL);\n await (this.enforcer.getAdapter() as FilteredAdapter).loadFilteredPolicy(\n tempModel,\n [{ ptype: 'g' }],\n );\n return await tempModel.getPolicy('g', 'g');\n }\n\n async getRolesForUser(userEntityRef: string): Promise<string[]> {\n return await this.enforcer.getRolesForUser(userEntityRef);\n }\n\n async getFilteredPolicy(\n fieldIndex: number,\n ...filter: string[]\n ): Promise<string[][]> {\n const tempModel = newModelFromString(MODEL);\n\n const filterObj: Record<string, string> = { ptype: 'p' };\n for (let i = 0; i < filter.length; i++) {\n if (filter[i]) {\n filterObj[`v${i + fieldIndex}`] = filter[i];\n }\n }\n\n await (this.enforcer.getAdapter() as FilteredAdapter).loadFilteredPolicy(\n tempModel,\n [filterObj],\n );\n\n return await tempModel.getPolicy('p', 'p');\n }\n\n async getFilteredGroupingPolicy(\n fieldIndex: number,\n ...filter: string[]\n ): Promise<string[][]> {\n const tempModel = newModelFromString(MODEL);\n\n const filterObj: Record<string, string> = { ptype: 'g' };\n for (let i = 0; i < filter.length; i++) {\n if (filter[i]) {\n filterObj[`v${i + fieldIndex}`] = filter[i];\n }\n }\n\n await (this.enforcer.getAdapter() as FilteredAdapter).loadFilteredPolicy(\n tempModel,\n [filterObj],\n );\n\n return await tempModel.getPolicy('g', 'g');\n }\n\n async addPolicy(\n policy: string[],\n externalTrx?: Knex.Transaction,\n ): Promise<void> {\n const trx = externalTrx ?? (await this.knex.transaction());\n\n if (await this.hasPolicy(...policy)) {\n return;\n }\n try {\n const ok = await this.enforcer.addPolicy(...policy);\n if (!ok) {\n throw new Error(`failed to create policy ${policyToString(policy)}`);\n }\n if (!externalTrx) {\n await trx.commit();\n }\n } catch (err) {\n if (!externalTrx) {\n await trx.rollback(err);\n }\n throw err;\n }\n }\n\n async addPolicies(\n policies: string[][],\n externalTrx?: Knex.Transaction,\n ): Promise<void> {\n if (this.loadPolicyPromise) {\n await this.loadPolicyPromise;\n } else {\n await this.loadPolicy();\n }\n\n const addPoliciesOperation = (async () => {\n if (policies.length === 0) {\n return;\n }\n\n const trx = externalTrx || (await this.knex.transaction());\n\n try {\n const ok = await this.enforcer.addPolicies(policies);\n if (!ok) {\n throw new Error(\n `Failed to store policies ${policiesToString(policies)}`,\n );\n }\n if (!externalTrx) {\n await trx.commit();\n }\n } catch (err) {\n if (!externalTrx) {\n await trx.rollback(err);\n }\n throw err;\n }\n })();\n await this.execOperation(addPoliciesOperation);\n }\n\n async addGroupingPolicy(\n policy: string[],\n roleMetadata: RoleMetadataDao,\n externalTrx?: Knex.Transaction,\n ): Promise<void> {\n if (this.loadPolicyPromise) {\n await this.loadPolicyPromise;\n } else {\n await this.loadPolicy();\n }\n\n const addGroupingPolicyOperation = (async () => {\n const trx = externalTrx ?? (await this.knex.transaction());\n const entityRef = roleMetadata.roleEntityRef;\n\n if (await this.hasGroupingPolicy(...policy)) {\n return;\n }\n try {\n let currentMetadata;\n if (entityRef.startsWith(`role:`)) {\n currentMetadata = await this.roleMetadataStorage.findRoleMetadata(\n entityRef,\n trx,\n );\n }\n\n if (currentMetadata) {\n await this.roleMetadataStorage.updateRoleMetadata(\n mergeRoleMetadata(currentMetadata, roleMetadata),\n entityRef,\n trx,\n );\n } else {\n const currentDate: Date = new Date();\n roleMetadata.createdAt = currentDate.toUTCString();\n roleMetadata.lastModified = currentDate.toUTCString();\n await this.roleMetadataStorage.createRoleMetadata(roleMetadata, trx);\n }\n\n const ok = await this.enforcer.addGroupingPolicy(...policy);\n if (!ok) {\n throw new Error(`failed to create policy ${policyToString(policy)}`);\n }\n if (!externalTrx) {\n await trx.commit();\n }\n if (!currentMetadata) {\n this.roleEventEmitter.emit('roleAdded', roleMetadata.roleEntityRef);\n }\n } catch (err) {\n if (!externalTrx) {\n await trx.rollback(err);\n }\n throw err;\n }\n })();\n await this.execOperation(addGroupingPolicyOperation);\n }\n\n async addGroupingPolicies(\n policies: string[][],\n roleMetadata: RoleMetadataDao,\n externalTrx?: Knex.Transaction,\n ): Promise<void> {\n if (this.loadPolicyPromise) {\n await this.loadPolicyPromise;\n } else {\n await this.loadPolicy();\n }\n\n const addGroupingPoliciesOperation = (async () => {\n if (policies.length === 0) {\n return;\n }\n\n const trx = externalTrx ?? (await this.knex.transaction());\n\n try {\n const currentRoleMetadata =\n await this.roleMetadataStorage.findRoleMetadata(\n roleMetadata.roleEntityRef,\n trx,\n );\n if (currentRoleMetadata) {\n await this.roleMetadataStorage.updateRoleMetadata(\n mergeRoleMetadata(currentRoleMetadata, roleMetadata),\n roleMetadata.roleEntityRef,\n trx,\n );\n } else {\n const currentDate: Date = new Date();\n roleMetadata.createdAt = currentDate.toUTCString();\n roleMetadata.lastModified = currentDate.toUTCString();\n await this.roleMetadataStorage.createRoleMetadata(roleMetadata, trx);\n }\n\n const ok = await this.enforcer.addGroupingPolicies(policies);\n if (!ok) {\n throw new Error(\n `Failed to store policies ${policiesToString(policies)}`,\n );\n }\n\n if (!externalTrx) {\n await trx.commit();\n }\n if (!currentRoleMetadata) {\n this.roleEventEmitter.emit('roleAdded', roleMetadata.roleEntityRef);\n }\n } catch (err) {\n if (!externalTrx) {\n await trx.rollback(err);\n }\n throw err;\n }\n })();\n await this.execOperation(addGroupingPoliciesOperation);\n }\n\n async updateGroupingPolicies(\n oldRole: string[][],\n newRole: string[][],\n newRoleMetadata: RoleMetadataDao,\n ): Promise<void> {\n const oldRoleName = oldRole.at(0)?.at(1)!;\n\n const trx = await this.knex.transaction();\n try {\n const currentMetadata = await this.roleMetadataStorage.findRoleMetadata(\n oldRoleName,\n trx,\n );\n if (!currentMetadata) {\n throw new Error(`Role metadata ${oldRoleName} was not found`);\n }\n\n await this.removeGroupingPolicies(oldRole, currentMetadata, true, trx);\n await this.addGroupingPolicies(newRole, newRoleMetadata, trx);\n await trx.commit();\n } catch (err) {\n await trx.rollback(err);\n throw err;\n }\n }\n\n async updatePolicies(\n oldPolicies: string[][],\n newPolicies: string[][],\n ): Promise<void> {\n const trx = await this.knex.transaction();\n\n try {\n await this.removePolicies(oldPolicies, trx);\n await this.addPolicies(newPolicies, trx);\n await trx.commit();\n } catch (err) {\n await trx.rollback(err);\n throw err;\n }\n }\n\n async removePolicy(policy: string[], externalTrx?: Knex.Transaction) {\n if (this.loadPolicyPromise) {\n await this.loadPolicyPromise;\n } else {\n await this.loadPolicy();\n }\n\n const removePolicyOperation = (async () => {\n const trx = externalTrx ?? (await this.knex.transaction());\n\n try {\n const ok = await this.enforcer.removePolicy(...policy);\n if (!ok) {\n throw new Error(`fail to delete policy ${policy}`);\n }\n if (!externalTrx) {\n await trx.commit();\n }\n } catch (err) {\n if (!externalTrx) {\n await trx.rollback(err);\n }\n throw err;\n }\n })();\n await this.execOperation(removePolicyOperation);\n }\n\n async removePolicies(\n policies: string[][],\n externalTrx?: Knex.Transaction,\n ): Promise<void> {\n if (this.loadPolicyPromise) {\n await this.loadPolicyPromise;\n } else {\n await this.loadPolicy();\n }\n\n const removePoliciesOperation = (async () => {\n const trx = externalTrx ?? (await this.knex.transaction());\n\n try {\n const ok = await this.enforcer.removePolicies(policies);\n if (!ok) {\n throw new Error(\n `Failed to delete policies ${policiesToString(policies)}`,\n );\n }\n\n if (!externalTrx) {\n await trx.commit();\n }\n } catch (err) {\n if (!externalTrx) {\n await trx.rollback(err);\n }\n throw err;\n }\n })();\n await this.execOperation(removePoliciesOperation);\n }\n\n async removeGroupingPolicy(\n policy: string[],\n roleMetadata: RoleMetadataDao,\n isUpdate?: boolean,\n externalTrx?: Knex.Transaction,\n ): Promise<void> {\n if (this.loadPolicyPromise) {\n await this.loadPolicyPromise;\n } else {\n await this.loadPolicy();\n }\n\n const removeGroupingPolicyOperation = (async () => {\n const trx = externalTrx ?? (await this.knex.transaction());\n const roleEntity = policy[1];\n\n try {\n const ok = await this.enforcer.removeGroupingPolicy(...policy);\n if (!ok) {\n throw new Error(`Failed to delete policy ${policyToString(policy)}`);\n }\n\n if (!isUpdate) {\n const currentRoleMetadata =\n await this.roleMetadataStorage.findRoleMetadata(roleEntity, trx);\n const remainingGroupPolicies = await this.getFilteredGroupingPolicy(\n 1,\n roleEntity,\n );\n if (\n currentRoleMetadata &&\n remainingGroupPolicies.length === 0 &&\n roleEntity !== ADMIN_ROLE_NAME\n ) {\n await this.roleMetadataStorage.removeRoleMetadata(roleEntity, trx);\n } else if (currentRoleMetadata) {\n await this.roleMetadataStorage.updateRoleMetadata(\n mergeRoleMetadata(currentRoleMetadata, roleMetadata),\n roleEntity,\n trx,\n );\n }\n }\n\n if (!externalTrx) {\n await trx.commit();\n }\n } catch (err) {\n if (!externalTrx) {\n await trx.rollback(err);\n }\n throw err;\n }\n })();\n await this.execOperation(removeGroupingPolicyOperation);\n }\n\n async removeGroupingPolicies(\n policies: string[][],\n roleMetadata: RoleMetadataDao,\n isUpdate?: boolean,\n externalTrx?: Knex.Transaction,\n ): Promise<void> {\n if (this.loadPolicyPromise) {\n await this.loadPolicyPromise;\n } else {\n await this.loadPolicy();\n }\n\n const removeGroupingPolicyOperation = (async () => {\n const trx = externalTrx ?? (await this.knex.transaction());\n const roleEntity = roleMetadata.roleEntityRef;\n\n try {\n const ok = await this.enforcer.removeGroupingPolicies(policies);\n if (!ok) {\n throw new Error(\n `Failed to delete grouping policies: ${policiesToString(policies)}`,\n );\n }\n\n if (!isUpdate) {\n const currentRoleMetadata =\n await this.roleMetadataStorage.findRoleMetadata(roleEntity, trx);\n const remainingGroupPolicies = await this.getFilteredGroupingPolicy(\n 1,\n roleEntity,\n );\n\n if (\n currentRoleMetadata &&\n remainingGroupPolicies.length === 0 &&\n roleEntity !== ADMIN_ROLE_NAME\n ) {\n await this.roleMetadataStorage.removeRoleMetadata(roleEntity, trx);\n } else if (currentRoleMetadata) {\n await this.roleMetadataStorage.updateRoleMetadata(\n mergeRoleMetadata(currentRoleMetadata, roleMetadata),\n roleEntity,\n trx,\n );\n }\n }\n\n if (!externalTrx) {\n await trx.commit();\n }\n } catch (err) {\n if (!externalTrx) {\n await trx.rollback(err);\n }\n throw err;\n }\n })();\n await this.execOperation(removeGroupingPolicyOperation);\n }\n\n /**\n * enforce aims to enforce a particular permission policy based on the user that it receives.\n * Under the hood, enforce uses the `enforce` method from the enforcer`.\n *\n * Before enforcement, a filter is set up to reduce the number of permission policies that will\n * be loaded in.\n * This will reduce the amount of checks that need to be made to determine if a user is authorize\n * to perform an action\n *\n * A temporary enforcer will also be used while enforcing.\n * This is to ensure that the filter does not interact with the base enforcer.\n * The temporary enforcer has lazy loading of the permission policies enabled to reduce the amount\n * of time it takes to initialize the temporary enforcer.\n * The justification for lazy loading is because permission policies are already present in the\n * role manager / database and it will be filtered and loaded whenever `getFilteredPolicy` is called\n * and permissions / roles are applied to the temp enforcer\n * @param entityRef The user to enforce\n * @param resourceType The resource type / name of the permission policy\n * @param action The action of the permission policy\n * @param roles Any roles that the user is directly or indirectly attached to.\n * Used for filtering permission policies.\n * @returns True if the user is allowed based on the particular permission\n */\n async enforce(\n entityRef: string,\n resourceType: string,\n action: string,\n roles: string[],\n ): Promise<boolean> {\n const model = newModelFromString(MODEL);\n let policies: string[][] = [];\n if (roles.length > 0) {\n for (const role of roles) {\n const filteredPolicy = await this.getFilteredPolicy(\n 0,\n role,\n resourceType,\n action,\n );\n policies.push(...filteredPolicy);\n }\n } else {\n const enforcePolicies = await this.getFilteredPolicy(\n 1,\n resourceType,\n action,\n );\n policies = enforcePolicies.filter(\n policy =>\n policy[0].startsWith('user:') || policy[0].startsWith('group:'),\n );\n }\n\n const roleManager = this.enforcer.getRoleManager();\n const tempEnforcer = new Enforcer();\n\n model.addPolicies('p', 'p', policies);\n\n await tempEnforcer.initWithModelAndAdapter(model);\n tempEnforcer.setRoleManager(roleManager);\n await tempEnforcer.buildRoleLinks();\n\n return await tempEnforcer.enforce(entityRef, resourceType, action);\n }\n\n async getImplicitPermissionsForUser(user: string): Promise<string[][]> {\n if (this.loadPolicyPromise) {\n await this.loadPolicyPromise;\n } else {\n await this.loadPolicy();\n }\n\n const getPermissionsForUserOperation = (async () => {\n return this.enforcer.getImplicitPermissionsForUser(user);\n })();\n\n return await this.execOperation(getPermissionsForUserOperation);\n }\n\n async getAllRoles(): Promise<string[]> {\n if (this.loadPolicyPromise) {\n await this.loadPolicyPromise;\n } else {\n await this.loadPolicy();\n }\n\n const getRolesOperation = (async () => {\n return this.enforcer.getAllRoles();\n })();\n\n return await this.execOperation(getRolesOperation);\n }\n}\n"],"names":["EventEmitter","PoliciesData","newModelFromString","MODEL","policyToString","policiesToString","mergeRoleMetadata","ADMIN_ROLE_NAME","Enforcer"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"enforcer-delegate.cjs.js","sources":["../../src/service/enforcer-delegate.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 { Enforcer, FilteredAdapter, newModelFromString } from 'casbin';\nimport { Knex } from 'knex';\n\nimport EventEmitter from 'events';\n\nimport { ADMIN_ROLE_NAME } from '../admin-permissions/admin-creation';\nimport {\n RoleMetadataDao,\n RoleMetadataStorage,\n} from '../database/role-metadata';\nimport { mergeRoleMetadata, policiesToString, policyToString } from '../helper';\nimport { MODEL } from './permission-model';\nimport { PoliciesData } from '../auditor/auditor';\nimport { AuditorService } from '@backstage/backend-plugin-api';\nimport { ConditionalStorage } from '../database/conditional-storage';\n\nexport type RoleEvents = 'roleAdded';\nexport interface RoleEventEmitter<T extends RoleEvents> {\n on(event: T, listener: (roleEntityRef: string | string[]) => void): this;\n}\n\ntype EventMap = {\n [event in RoleEvents]: any[];\n};\n\nexport class EnforcerDelegate implements RoleEventEmitter<RoleEvents> {\n private readonly roleEventEmitter = new EventEmitter<EventMap>();\n\n private loadPolicyPromise: Promise<void> | null = null;\n private editOperationsQueue: Promise<any>[] = []; // Queue to track edit operations\n\n constructor(\n private readonly enforcer: Enforcer,\n private readonly auditor: AuditorService,\n private readonly conditionalStorage: ConditionalStorage,\n private readonly roleMetadataStorage: RoleMetadataStorage,\n private readonly knex: Knex,\n ) {}\n\n async loadPolicy(): Promise<void> {\n if (this.loadPolicyPromise) {\n // If a load operation is already in progress, return the cached promise\n return this.loadPolicyPromise;\n }\n\n this.loadPolicyPromise = (async () => {\n try {\n await this.waitForEditOperationsToFinish();\n\n await this.enforcer.loadPolicy();\n } catch (error) {\n const auditorEvent = await this.auditor.createEvent({\n eventId: PoliciesData.PERMISSIONS_READ,\n severityLevel: 'medium',\n });\n await auditorEvent.fail({ error });\n } finally {\n this.loadPolicyPromise = null;\n }\n })();\n\n return this.loadPolicyPromise;\n }\n\n private async waitForEditOperationsToFinish(): Promise<void> {\n await Promise.all(this.editOperationsQueue);\n }\n\n async execOperation<T>(operation: Promise<T>): Promise<T> {\n this.editOperationsQueue.push(operation);\n\n let result;\n try {\n result = await operation;\n } catch (err) {\n throw err;\n } finally {\n const index = this.editOperationsQueue.indexOf(operation);\n if (index !== -1) {\n this.editOperationsQueue.splice(index, 1);\n }\n }\n\n return result;\n }\n\n on(event: RoleEvents, listener: (role: string) => void): this {\n this.roleEventEmitter.on(event, listener);\n return this;\n }\n\n async hasPolicy(...policy: string[]): Promise<boolean> {\n const tempModel = newModelFromString(MODEL);\n await (this.enforcer.getAdapter() as FilteredAdapter).loadFilteredPolicy(\n tempModel,\n [\n {\n ptype: 'p',\n v0: policy[0],\n v1: policy[1],\n v2: policy[2],\n v3: policy[3],\n },\n ],\n );\n return tempModel.hasPolicy('p', 'p', policy);\n }\n\n async hasGroupingPolicy(...policy: string[]): Promise<boolean> {\n const tempModel = newModelFromString(MODEL);\n await (this.enforcer.getAdapter() as FilteredAdapter).loadFilteredPolicy(\n tempModel,\n [\n {\n ptype: 'g',\n v0: policy[0],\n v1: policy[1],\n },\n ],\n );\n return tempModel.hasPolicy('g', 'g', policy);\n }\n\n async getPolicy(): Promise<string[][]> {\n const tempModel = newModelFromString(MODEL);\n await (this.enforcer.getAdapter() as FilteredAdapter).loadFilteredPolicy(\n tempModel,\n [{ ptype: 'p' }],\n );\n return await tempModel.getPolicy('p', 'p');\n }\n\n async getGroupingPolicy(): Promise<string[][]> {\n const tempModel = newModelFromString(MODEL);\n await (this.enforcer.getAdapter() as FilteredAdapter).loadFilteredPolicy(\n tempModel,\n [{ ptype: 'g' }],\n );\n return await tempModel.getPolicy('g', 'g');\n }\n\n async getRolesForUser(userEntityRef: string): Promise<string[]> {\n return await this.enforcer.getRolesForUser(userEntityRef);\n }\n\n async getFilteredPolicy(\n fieldIndex: number,\n ...filter: string[]\n ): Promise<string[][]> {\n const tempModel = newModelFromString(MODEL);\n\n const filterObj: Record<string, string> = { ptype: 'p' };\n for (let i = 0; i < filter.length; i++) {\n if (filter[i]) {\n filterObj[`v${i + fieldIndex}`] = filter[i];\n }\n }\n\n await (this.enforcer.getAdapter() as FilteredAdapter).loadFilteredPolicy(\n tempModel,\n [filterObj],\n );\n\n return await tempModel.getPolicy('p', 'p');\n }\n\n async getFilteredGroupingPolicy(\n fieldIndex: number,\n ...filter: string[]\n ): Promise<string[][]> {\n const tempModel = newModelFromString(MODEL);\n\n const filterObj: Record<string, string> = { ptype: 'g' };\n for (let i = 0; i < filter.length; i++) {\n if (filter[i]) {\n filterObj[`v${i + fieldIndex}`] = filter[i];\n }\n }\n\n await (this.enforcer.getAdapter() as FilteredAdapter).loadFilteredPolicy(\n tempModel,\n [filterObj],\n );\n\n return await tempModel.getPolicy('g', 'g');\n }\n\n async addPolicy(\n policy: string[],\n externalTrx?: Knex.Transaction,\n ): Promise<void> {\n const trx = externalTrx ?? (await this.knex.transaction());\n\n if (await this.hasPolicy(...policy)) {\n return;\n }\n try {\n const ok = await this.enforcer.addPolicy(...policy);\n if (!ok) {\n throw new Error(`failed to create policy ${policyToString(policy)}`);\n }\n if (!externalTrx) {\n await trx.commit();\n }\n } catch (err) {\n if (!externalTrx) {\n await trx.rollback(err);\n }\n throw err;\n }\n }\n\n async addPolicies(\n policies: string[][],\n externalTrx?: Knex.Transaction,\n ): Promise<void> {\n if (this.loadPolicyPromise) {\n await this.loadPolicyPromise;\n } else {\n await this.loadPolicy();\n }\n\n const addPoliciesOperation = (async () => {\n if (policies.length === 0) {\n return;\n }\n\n const trx = externalTrx || (await this.knex.transaction());\n\n try {\n const ok = await this.enforcer.addPolicies(policies);\n if (!ok) {\n throw new Error(\n `Failed to store policies ${policiesToString(policies)}`,\n );\n }\n if (!externalTrx) {\n await trx.commit();\n }\n } catch (err) {\n if (!externalTrx) {\n await trx.rollback(err);\n }\n throw err;\n }\n })();\n await this.execOperation(addPoliciesOperation);\n }\n\n async addGroupingPolicy(\n policy: string[],\n roleMetadata: RoleMetadataDao,\n externalTrx?: Knex.Transaction,\n ): Promise<void> {\n if (this.loadPolicyPromise) {\n await this.loadPolicyPromise;\n } else {\n await this.loadPolicy();\n }\n\n const addGroupingPolicyOperation = (async () => {\n const trx = externalTrx ?? (await this.knex.transaction());\n const entityRef = roleMetadata.roleEntityRef;\n\n if (await this.hasGroupingPolicy(...policy)) {\n return;\n }\n try {\n let currentMetadata;\n if (entityRef.startsWith(`role:`)) {\n currentMetadata = await this.roleMetadataStorage.findRoleMetadata(\n entityRef,\n trx,\n );\n }\n\n if (currentMetadata) {\n await this.roleMetadataStorage.updateRoleMetadata(\n mergeRoleMetadata(currentMetadata, roleMetadata),\n entityRef,\n trx,\n );\n } else {\n const currentDate: Date = new Date();\n roleMetadata.createdAt = currentDate.toUTCString();\n roleMetadata.lastModified = currentDate.toUTCString();\n await this.roleMetadataStorage.createRoleMetadata(roleMetadata, trx);\n }\n\n const ok = await this.enforcer.addGroupingPolicy(...policy);\n if (!ok) {\n throw new Error(`failed to create policy ${policyToString(policy)}`);\n }\n if (!externalTrx) {\n await trx.commit();\n }\n if (!currentMetadata) {\n this.roleEventEmitter.emit('roleAdded', roleMetadata.roleEntityRef);\n }\n } catch (err) {\n if (!externalTrx) {\n await trx.rollback(err);\n }\n throw err;\n }\n })();\n await this.execOperation(addGroupingPolicyOperation);\n }\n\n async addGroupingPolicies(\n policies: string[][],\n roleMetadata: RoleMetadataDao,\n oldRoleEntityRef?: string,\n externalTrx?: Knex.Transaction,\n ): Promise<void> {\n if (this.loadPolicyPromise) {\n await this.loadPolicyPromise;\n } else {\n await this.loadPolicy();\n }\n\n const addGroupingPoliciesOperation = (async () => {\n if (policies.length === 0) {\n return;\n }\n\n const trx = externalTrx ?? (await this.knex.transaction());\n\n try {\n const currentRoleMetadata =\n await this.roleMetadataStorage.findRoleMetadata(\n oldRoleEntityRef ?? roleMetadata.roleEntityRef,\n trx,\n );\n if (currentRoleMetadata) {\n await this.roleMetadataStorage.updateRoleMetadata(\n mergeRoleMetadata(currentRoleMetadata, roleMetadata),\n oldRoleEntityRef ?? roleMetadata.roleEntityRef,\n trx,\n );\n } else {\n const currentDate: Date = new Date();\n roleMetadata.createdAt = currentDate.toUTCString();\n roleMetadata.lastModified = currentDate.toUTCString();\n await this.roleMetadataStorage.createRoleMetadata(roleMetadata, trx);\n }\n\n const ok = await this.enforcer.addGroupingPolicies(policies);\n if (!ok) {\n throw new Error(\n `Failed to store policies ${policiesToString(policies)}`,\n );\n }\n\n if (!externalTrx) {\n await trx.commit();\n }\n if (!currentRoleMetadata) {\n this.roleEventEmitter.emit('roleAdded', roleMetadata.roleEntityRef);\n }\n } catch (err) {\n if (!externalTrx) {\n await trx.rollback(err);\n }\n throw err;\n }\n })();\n await this.execOperation(addGroupingPoliciesOperation);\n }\n\n async updateGroupingPolicies(\n oldRole: string[][],\n newRole: string[][],\n newRoleMetadata: RoleMetadataDao,\n ): Promise<void> {\n const oldRoleName = oldRole.at(0)?.at(1)!;\n\n const trx = await this.knex.transaction();\n try {\n const currentMetadata = await this.roleMetadataStorage.findRoleMetadata(\n oldRoleName,\n trx,\n );\n if (!currentMetadata) {\n throw new Error(`Role metadata ${oldRoleName} was not found`);\n }\n\n await this.removeGroupingPolicies(oldRole, currentMetadata, true, trx);\n await this.addGroupingPolicies(\n newRole,\n newRoleMetadata,\n currentMetadata.roleEntityRef,\n trx,\n );\n\n // Role name changed -> update roleEntityRef in policies\n if (newRoleMetadata.roleEntityRef !== currentMetadata.roleEntityRef) {\n const oldPolicies = await this.enforcer.getFilteredPolicy(\n 0,\n currentMetadata.roleEntityRef,\n );\n const updatedPolicies = oldPolicies.map(oldPolicy => [\n newRoleMetadata.roleEntityRef,\n ...oldPolicy.slice(1),\n ]);\n await this.updatePolicies(oldPolicies, updatedPolicies, trx);\n\n const oldConditions = await this.conditionalStorage.filterConditions(\n currentMetadata.roleEntityRef,\n undefined,\n undefined,\n undefined,\n undefined,\n trx,\n );\n for (const condition of oldConditions) {\n await this.conditionalStorage.updateCondition(\n condition.id,\n {\n ...condition,\n roleEntityRef: newRoleMetadata.roleEntityRef,\n },\n trx,\n );\n }\n }\n\n await trx.commit();\n } catch (err) {\n await trx.rollback(err);\n throw err;\n }\n }\n\n async updatePolicies(\n oldPolicies: string[][],\n newPolicies: string[][],\n externalTrx?: Knex.Transaction,\n ): Promise<void> {\n const trx = externalTrx ?? (await this.knex.transaction());\n\n try {\n await this.removePolicies(oldPolicies, trx);\n await this.addPolicies(newPolicies, trx);\n if (!externalTrx) {\n await trx.commit();\n }\n } catch (err) {\n if (!externalTrx) {\n await trx.rollback(err);\n }\n throw err;\n }\n }\n\n async removePolicy(policy: string[], externalTrx?: Knex.Transaction) {\n if (this.loadPolicyPromise) {\n await this.loadPolicyPromise;\n } else {\n await this.loadPolicy();\n }\n\n const removePolicyOperation = (async () => {\n const trx = externalTrx ?? (await this.knex.transaction());\n\n try {\n const ok = await this.enforcer.removePolicy(...policy);\n if (!ok) {\n throw new Error(`fail to delete policy ${policy}`);\n }\n if (!externalTrx) {\n await trx.commit();\n }\n } catch (err) {\n if (!externalTrx) {\n await trx.rollback(err);\n }\n throw err;\n }\n })();\n await this.execOperation(removePolicyOperation);\n }\n\n async removePolicies(\n policies: string[][],\n externalTrx?: Knex.Transaction,\n ): Promise<void> {\n if (this.loadPolicyPromise) {\n await this.loadPolicyPromise;\n } else {\n await this.loadPolicy();\n }\n\n const removePoliciesOperation = (async () => {\n const trx = externalTrx ?? (await this.knex.transaction());\n\n try {\n const ok = await this.enforcer.removePolicies(policies);\n if (!ok) {\n throw new Error(\n `Failed to delete policies ${policiesToString(policies)}`,\n );\n }\n\n if (!externalTrx) {\n await trx.commit();\n }\n } catch (err) {\n if (!externalTrx) {\n await trx.rollback(err);\n }\n throw err;\n }\n })();\n await this.execOperation(removePoliciesOperation);\n }\n\n async removeGroupingPolicy(\n policy: string[],\n roleMetadata: RoleMetadataDao,\n isUpdate?: boolean,\n externalTrx?: Knex.Transaction,\n ): Promise<void> {\n if (this.loadPolicyPromise) {\n await this.loadPolicyPromise;\n } else {\n await this.loadPolicy();\n }\n\n const removeGroupingPolicyOperation = (async () => {\n const trx = externalTrx ?? (await this.knex.transaction());\n const roleEntity = policy[1];\n\n try {\n const ok = await this.enforcer.removeGroupingPolicy(...policy);\n if (!ok) {\n throw new Error(`Failed to delete policy ${policyToString(policy)}`);\n }\n\n if (!isUpdate) {\n const currentRoleMetadata =\n await this.roleMetadataStorage.findRoleMetadata(roleEntity, trx);\n const remainingGroupPolicies = await this.getFilteredGroupingPolicy(\n 1,\n roleEntity,\n );\n if (\n currentRoleMetadata &&\n remainingGroupPolicies.length === 0 &&\n roleEntity !== ADMIN_ROLE_NAME\n ) {\n await this.roleMetadataStorage.removeRoleMetadata(roleEntity, trx);\n } else if (currentRoleMetadata) {\n await this.roleMetadataStorage.updateRoleMetadata(\n mergeRoleMetadata(currentRoleMetadata, roleMetadata),\n roleEntity,\n trx,\n );\n }\n }\n\n if (!externalTrx) {\n await trx.commit();\n }\n } catch (err) {\n if (!externalTrx) {\n await trx.rollback(err);\n }\n throw err;\n }\n })();\n await this.execOperation(removeGroupingPolicyOperation);\n }\n\n async removeGroupingPolicies(\n policies: string[][],\n roleMetadata: RoleMetadataDao,\n isUpdate?: boolean,\n externalTrx?: Knex.Transaction,\n ): Promise<void> {\n if (this.loadPolicyPromise) {\n await this.loadPolicyPromise;\n } else {\n await this.loadPolicy();\n }\n\n const removeGroupingPolicyOperation = (async () => {\n const trx = externalTrx ?? (await this.knex.transaction());\n const roleEntity = roleMetadata.roleEntityRef;\n\n try {\n const ok = await this.enforcer.removeGroupingPolicies(policies);\n if (!ok) {\n throw new Error(\n `Failed to delete grouping policies: ${policiesToString(policies)}`,\n );\n }\n\n if (!isUpdate) {\n const currentRoleMetadata =\n await this.roleMetadataStorage.findRoleMetadata(roleEntity, trx);\n const remainingGroupPolicies = await this.getFilteredGroupingPolicy(\n 1,\n roleEntity,\n );\n\n if (\n currentRoleMetadata &&\n remainingGroupPolicies.length === 0 &&\n roleEntity !== ADMIN_ROLE_NAME\n ) {\n await this.roleMetadataStorage.removeRoleMetadata(roleEntity, trx);\n } else if (currentRoleMetadata) {\n await this.roleMetadataStorage.updateRoleMetadata(\n mergeRoleMetadata(currentRoleMetadata, roleMetadata),\n roleEntity,\n trx,\n );\n }\n }\n\n if (!externalTrx) {\n await trx.commit();\n }\n } catch (err) {\n if (!externalTrx) {\n await trx.rollback(err);\n }\n throw err;\n }\n })();\n await this.execOperation(removeGroupingPolicyOperation);\n }\n\n /**\n * enforce aims to enforce a particular permission policy based on the user that it receives.\n * Under the hood, enforce uses the `enforce` method from the enforcer`.\n *\n * Before enforcement, a filter is set up to reduce the number of permission policies that will\n * be loaded in.\n * This will reduce the amount of checks that need to be made to determine if a user is authorize\n * to perform an action\n *\n * A temporary enforcer will also be used while enforcing.\n * This is to ensure that the filter does not interact with the base enforcer.\n * The temporary enforcer has lazy loading of the permission policies enabled to reduce the amount\n * of time it takes to initialize the temporary enforcer.\n * The justification for lazy loading is because permission policies are already present in the\n * role manager / database and it will be filtered and loaded whenever `getFilteredPolicy` is called\n * and permissions / roles are applied to the temp enforcer\n * @param entityRef The user to enforce\n * @param resourceType The resource type / name of the permission policy\n * @param action The action of the permission policy\n * @param roles Any roles that the user is directly or indirectly attached to.\n * Used for filtering permission policies.\n * @returns True if the user is allowed based on the particular permission\n */\n async enforce(\n entityRef: string,\n resourceType: string,\n action: string,\n roles: string[],\n ): Promise<boolean> {\n const model = newModelFromString(MODEL);\n let policies: string[][] = [];\n if (roles.length > 0) {\n for (const role of roles) {\n const filteredPolicy = await this.getFilteredPolicy(\n 0,\n role,\n resourceType,\n action,\n );\n policies.push(...filteredPolicy);\n }\n } else {\n const enforcePolicies = await this.getFilteredPolicy(\n 1,\n resourceType,\n action,\n );\n policies = enforcePolicies.filter(\n policy =>\n policy[0].startsWith('user:') || policy[0].startsWith('group:'),\n );\n }\n\n const roleManager = this.enforcer.getRoleManager();\n const tempEnforcer = new Enforcer();\n\n model.addPolicies('p', 'p', policies);\n\n await tempEnforcer.initWithModelAndAdapter(model);\n tempEnforcer.setRoleManager(roleManager);\n await tempEnforcer.buildRoleLinks();\n\n return await tempEnforcer.enforce(entityRef, resourceType, action);\n }\n\n async getImplicitPermissionsForUser(user: string): Promise<string[][]> {\n if (this.loadPolicyPromise) {\n await this.loadPolicyPromise;\n } else {\n await this.loadPolicy();\n }\n\n const getPermissionsForUserOperation = (async () => {\n return this.enforcer.getImplicitPermissionsForUser(user);\n })();\n\n return await this.execOperation(getPermissionsForUserOperation);\n }\n\n async getAllRoles(): Promise<string[]> {\n if (this.loadPolicyPromise) {\n await this.loadPolicyPromise;\n } else {\n await this.loadPolicy();\n }\n\n const getRolesOperation = (async () => {\n return this.enforcer.getAllRoles();\n })();\n\n return await this.execOperation(getRolesOperation);\n }\n}\n"],"names":["EventEmitter","PoliciesData","newModelFromString","MODEL","policyToString","policiesToString","mergeRoleMetadata","ADMIN_ROLE_NAME","Enforcer"],"mappings":"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"}
|