@backstage-community/plugin-rbac-backend 5.3.1 → 5.4.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.
@@ -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 { AuditLogger } from '@janus-idp/backstage-plugin-audit-log-node';\nimport {\n FETCH_NEWER_PERMISSIONS_STAGE,\n PoliciesData,\n} from '../audit-log/audit-logger';\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 semaphore: number = 0;\n private editOperationsQueue: Promise<any>[] = []; // Queue to track edit operations\n\n constructor(\n private readonly enforcer: Enforcer,\n private readonly auditLogger: AuditLogger,\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 // Increment semaphore to block edits during load\n this.semaphore++;\n\n this.loadPolicyPromise = (async () => {\n try {\n await this.waitForEditOperationsToFinish();\n\n await this.enforcer.loadPolicy();\n } catch (err) {\n this.auditLogger.auditLog({\n message: 'Failed to load newer policies from database',\n eventName: PoliciesData.FAILED_TO_FETCH_NEWER_PERMISSIONS,\n stage: FETCH_NEWER_PERMISSIONS_STAGE,\n status: 'failed',\n errors: [err],\n });\n } finally {\n this.semaphore--;\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 filterArgs: Record<string, string>[] = [];\n const filterObj: Record<string, string> = { ptype: 'p' };\n for (let i = 0; i < filter.length; i++) {\n filterObj[`v${i + fieldIndex}`] = filter[i];\n filterArgs.push(filterObj);\n }\n\n await (this.enforcer.getAdapter() as FilteredAdapter).loadFilteredPolicy(\n tempModel,\n filterArgs,\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 filterArgs: Record<string, string>[] = [];\n const filterObj: Record<string, string> = { ptype: 'g' };\n for (let i = 0; i < filter.length; i++) {\n filterObj[`v${i + fieldIndex}`] = filter[i];\n filterArgs.push(filterObj);\n }\n\n await (this.enforcer.getAdapter() as FilteredAdapter).loadFilteredPolicy(\n tempModel,\n filterArgs,\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 }\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 }\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 }\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 }\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 }\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 }\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 }\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 if (this.loadPolicyPromise) {\n await this.loadPolicyPromise;\n }\n\n const evaluatePermissionOperation = (async () => {\n const filter = [];\n if (roles.length > 0) {\n roles.forEach(role => {\n filter.push({ ptype: 'p', v0: role, v1: resourceType, v2: action });\n });\n } else {\n filter.push({ ptype: 'p', v1: resourceType, v2: action });\n }\n\n const adapt = this.enforcer.getAdapter();\n const roleManager = this.enforcer.getRoleManager();\n const tempEnforcer = new Enforcer();\n await tempEnforcer.initWithModelAndAdapter(\n newModelFromString(MODEL),\n adapt,\n true,\n );\n tempEnforcer.setRoleManager(roleManager);\n\n await tempEnforcer.loadFilteredPolicy(filter);\n\n return await tempEnforcer.enforce(entityRef, resourceType, action);\n })();\n\n return await this.execOperation(evaluatePermissionOperation);\n }\n\n async getImplicitPermissionsForUser(user: string): Promise<string[][]> {\n if (this.loadPolicyPromise) {\n await this.loadPolicyPromise;\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 }\n\n const getRolesOperation = (async () => {\n return this.enforcer.getAllRoles();\n })();\n\n return await this.execOperation(getRolesOperation);\n }\n}\n"],"names":["EventEmitter","PoliciesData","FETCH_NEWER_PERMISSIONS_STAGE","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 { AuditLogger } from '@janus-idp/backstage-plugin-audit-log-node';\nimport {\n FETCH_NEWER_PERMISSIONS_STAGE,\n PoliciesData,\n} from '../audit-log/audit-logger';\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 semaphore: number = 0;\n private editOperationsQueue: Promise<any>[] = []; // Queue to track edit operations\n\n constructor(\n private readonly enforcer: Enforcer,\n private readonly auditLogger: AuditLogger,\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 // Increment semaphore to block edits during load\n this.semaphore++;\n\n this.loadPolicyPromise = (async () => {\n try {\n await this.waitForEditOperationsToFinish();\n\n await this.enforcer.loadPolicy();\n } catch (err) {\n this.auditLogger.auditLog({\n message: 'Failed to load newer policies from database',\n eventName: PoliciesData.FAILED_TO_FETCH_NEWER_PERMISSIONS,\n stage: FETCH_NEWER_PERMISSIONS_STAGE,\n status: 'failed',\n errors: [err],\n });\n } finally {\n this.semaphore--;\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 filterArgs: Record<string, string>[] = [];\n const filterObj: Record<string, string> = { ptype: 'p' };\n for (let i = 0; i < filter.length; i++) {\n filterObj[`v${i + fieldIndex}`] = filter[i];\n filterArgs.push(filterObj);\n }\n\n await (this.enforcer.getAdapter() as FilteredAdapter).loadFilteredPolicy(\n tempModel,\n filterArgs,\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 filterArgs: Record<string, string>[] = [];\n const filterObj: Record<string, string> = { ptype: 'g' };\n for (let i = 0; i < filter.length; i++) {\n filterObj[`v${i + fieldIndex}`] = filter[i];\n filterArgs.push(filterObj);\n }\n\n await (this.enforcer.getAdapter() as FilteredAdapter).loadFilteredPolicy(\n tempModel,\n filterArgs,\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 }\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 }\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 }\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 }\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 }\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 }\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 }\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 if (this.loadPolicyPromise) {\n await this.loadPolicyPromise;\n }\n\n const evaluatePermissionOperation = (async () => {\n const filter = [];\n if (roles.length > 0) {\n roles.forEach(role => {\n filter.push({ ptype: 'p', v0: role, v1: resourceType, v2: action });\n });\n } else {\n filter.push({ ptype: 'p', v1: resourceType, v2: action });\n }\n\n const adapt = this.enforcer.getAdapter();\n const roleManager = this.enforcer.getRoleManager();\n const tempEnforcer = new Enforcer();\n await tempEnforcer.initWithModelAndAdapter(\n newModelFromString(MODEL),\n adapt,\n true,\n );\n tempEnforcer.setRoleManager(roleManager);\n\n await tempEnforcer.loadFilteredPolicy(filter);\n\n return await tempEnforcer.enforce(entityRef, resourceType, action);\n })();\n\n return await this.execOperation(evaluatePermissionOperation);\n }\n\n async getImplicitPermissionsForUser(user: string): Promise<string[][]> {\n if (this.loadPolicyPromise) {\n await this.loadPolicyPromise;\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 }\n\n const getRolesOperation = (async () => {\n return this.enforcer.getAllRoles();\n })();\n\n return await this.execOperation(getRolesOperation);\n }\n}\n"],"names":["EventEmitter","PoliciesData","FETCH_NEWER_PERMISSIONS_STAGE","newModelFromString","MODEL","policyToString","policiesToString","mergeRoleMetadata","ADMIN_ROLE_NAME","Enforcer"],"mappings":"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"}
@@ -34,7 +34,7 @@ class PluginPermissionMetadataCollector {
34
34
  }
35
35
  async getPluginPolicies(auth) {
36
36
  const pluginMetadata = await this.getPluginMetaData(auth);
37
- return pluginMetadata.filter((metadata) => metadata.metaDataResponse.permissions !== void 0).map((metadata) => {
37
+ return pluginMetadata.filter((metadata) => metadata.metaDataResponse.permissions !== undefined).map((metadata) => {
38
38
  return {
39
39
  pluginId: metadata.pluginId,
40
40
  policies: permissionsToCasbinPolicies(
@@ -89,7 +89,7 @@ class PluginPermissionMetadataCollector {
89
89
  this.logger.warn(
90
90
  `No permission metadata found for ${pluginId}. ${err}`
91
91
  );
92
- return void 0;
92
+ return undefined;
93
93
  }
94
94
  this.logger.error(
95
95
  `Failed to retrieve permission metadata for ${pluginId}. ${err}`
@@ -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 type {\n PluginPermissionMetaData,\n PolicyDetails,\n} from '@backstage-community/plugin-rbac-common';\nimport type { PluginIdProvider } from '@backstage-community/plugin-rbac-node';\n\ntype PluginMetadataResponse = {\n pluginId: string;\n metaDataResponse: MetadataResponse;\n};\n\nexport type PluginMetadataResponseSerializedRule = {\n pluginId: string;\n rules: MetadataResponseSerializedRule[];\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 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":["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 type {\n PluginPermissionMetaData,\n PolicyDetails,\n} from '@backstage-community/plugin-rbac-common';\nimport type { PluginIdProvider } from '@backstage-community/plugin-rbac-node';\n\ntype PluginMetadataResponse = {\n pluginId: string;\n metaDataResponse: MetadataResponse;\n};\n\nexport type PluginMetadataResponseSerializedRule = {\n pluginId: string;\n rules: MetadataResponseSerializedRule[];\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 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":["UrlReaders","FetchUrlReader","isError","isResourcePermission"],"mappings":"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"}
@@ -816,7 +816,7 @@ class PoliciesServer {
816
816
  const result = await Promise.all(
817
817
  Object.entries(combinedRoles).map(async ([role, value]) => {
818
818
  const metadataDao = await this.roleMetadata.findRoleMetadata(role);
819
- const metadata = metadataDao ? roleMetadata.daoToMetadata(metadataDao) : void 0;
819
+ const metadata = metadataDao ? roleMetadata.daoToMetadata(metadataDao) : undefined;
820
820
  return Promise.resolve({
821
821
  memberReferences: value,
822
822
  name: role,
@@ -848,7 +848,7 @@ class PoliciesServer {
848
848
  }
849
849
  getActionQueries(queryValue) {
850
850
  if (!queryValue) {
851
- return void 0;
851
+ return undefined;
852
852
  }
853
853
  if (Array.isArray(queryValue)) {
854
854
  const permissionNames = [];
@@ -1 +1 @@
1
- {"version":3,"file":"policies-rest-api.cjs.js","sources":["../../src/service/policies-rest-api.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 { PermissionsService } from '@backstage/backend-plugin-api';\nimport {\n ConflictError,\n InputError,\n NotAllowedError,\n NotFoundError,\n ServiceUnavailableError,\n} from '@backstage/errors';\nimport { createRouter } from '@backstage/plugin-permission-backend';\nimport {\n AuthorizeResult,\n PolicyDecision,\n ResourcePermission,\n} from '@backstage/plugin-permission-common';\nimport { createPermissionIntegrationRouter } from '@backstage/plugin-permission-node';\n\nimport type { AuditLogger } from '@janus-idp/backstage-plugin-audit-log-node';\nimport express from 'express';\nimport type { Request } from 'express-serve-static-core';\nimport { isEmpty, isEqual } from 'lodash';\nimport type { ParsedQs } from 'qs';\n\nimport {\n PermissionAction,\n policyEntityCreatePermission,\n policyEntityDeletePermission,\n policyEntityPermissions,\n policyEntityReadPermission,\n policyEntityUpdatePermission,\n RESOURCE_TYPE_POLICY_ENTITY,\n Role,\n RoleBasedPolicy,\n RoleConditionalPolicyDecision,\n} from '@backstage-community/plugin-rbac-common';\nimport type { RBACProvider } from '@backstage-community/plugin-rbac-node';\n\nimport {\n ConditionAuditInfo,\n ConditionEvents,\n ListConditionEvents,\n ListPluginPoliciesEvents,\n PermissionAuditInfo,\n PermissionEvents,\n RoleAuditInfo,\n RoleEvents,\n SEND_RESPONSE_STAGE,\n} from '../audit-log/audit-logger';\nimport { auditError as logAuditError } from '../audit-log/rest-errors-interceptor';\nimport { ConditionalStorage } from '../database/conditional-storage';\nimport {\n daoToMetadata,\n RoleMetadataDao,\n RoleMetadataStorage,\n} from '../database/role-metadata';\nimport {\n buildRoleSourceMap,\n deepSortedEqual,\n isPermissionAction,\n policyToString,\n processConditionMapping,\n} from '../helper';\nimport { validateRoleCondition } from '../validation/condition-validation';\nimport {\n validateEntityReference,\n validatePolicy,\n validateRole,\n validateSource,\n} from '../validation/policies-validation';\nimport { EnforcerDelegate } from './enforcer-delegate';\nimport { PluginPermissionMetadataCollector } from './plugin-endpoints';\nimport { RBACRouterOptions } from './policy-builder';\n\nexport class PoliciesServer {\n constructor(\n private readonly permissions: PermissionsService,\n private readonly options: RBACRouterOptions,\n private readonly enforcer: EnforcerDelegate,\n private readonly conditionalStorage: ConditionalStorage,\n private readonly pluginPermMetaData: PluginPermissionMetadataCollector,\n private readonly roleMetadata: RoleMetadataStorage,\n private readonly aLog: AuditLogger,\n private readonly rbacProviders?: RBACProvider[],\n ) {}\n\n private async authorize(\n request: Request,\n permission: ResourcePermission,\n ): Promise<PolicyDecision> {\n const credentials = await this.options.httpAuth.credentials(request, {\n allow: ['user', 'service'],\n });\n\n // allow service to service communication, but only with read permission\n if (\n this.options.auth.isPrincipal(credentials, 'service') &&\n permission !== policyEntityReadPermission\n ) {\n throw new NotAllowedError(\n `Only creadential principal with type 'user' permitted to modify permissions`,\n );\n }\n\n const decision = (\n await this.permissions.authorize(\n [{ permission: permission, resourceRef: permission.resourceType }],\n { credentials },\n )\n )[0];\n\n return decision;\n }\n\n async serve(): Promise<express.Router> {\n const router = await createRouter(this.options);\n\n const { httpAuth } = this.options;\n\n if (!httpAuth) {\n throw new ServiceUnavailableError(\n 'httpAuth not found, ensure the correct configuration for the RBAC plugin',\n );\n }\n\n const permissionsIntegrationRouter = createPermissionIntegrationRouter({\n resourceType: RESOURCE_TYPE_POLICY_ENTITY,\n permissions: policyEntityPermissions,\n });\n router.use(permissionsIntegrationRouter);\n\n const isPluginEnabled =\n this.options.config.getOptionalBoolean('permission.enabled');\n if (!isPluginEnabled) {\n return router;\n }\n\n router.get('/', async (request, response) => {\n const decision = await this.authorize(\n request,\n policyEntityReadPermission,\n );\n\n if (decision.result === AuthorizeResult.DENY) {\n throw new NotAllowedError(); // 403\n }\n response.send({ status: 'Authorized' });\n });\n\n // Policy CRUD\n\n router.get('/policies', async (request, response) => {\n const decision = await this.authorize(\n request,\n policyEntityReadPermission,\n );\n\n if (decision.result === AuthorizeResult.DENY) {\n throw new NotAllowedError(); // 403\n }\n\n let policies: string[][];\n if (this.isPolicyFilterEnabled(request)) {\n const entityRef = this.getFirstQuery(request.query.entityRef);\n const permission = this.getFirstQuery(request.query.permission);\n const policy = this.getFirstQuery(request.query.policy);\n const effect = this.getFirstQuery(request.query.effect);\n\n const filter: string[] = [entityRef, permission, policy, effect];\n policies = await this.enforcer.getFilteredPolicy(0, ...filter);\n } else {\n policies = await this.enforcer.getPolicy();\n }\n\n const body = await this.transformPolicyArray(...policies);\n\n await this.aLog.auditLog({\n message: `Return list permission policies`,\n eventName: PermissionEvents.GET_POLICY,\n stage: SEND_RESPONSE_STAGE,\n status: 'succeeded',\n request,\n response: { status: 200, body },\n });\n\n response.json(body);\n });\n\n router.get(\n '/policies/:kind/:namespace/:name',\n async (request, response) => {\n const decision = await this.authorize(\n request,\n policyEntityReadPermission,\n );\n\n if (decision.result === AuthorizeResult.DENY) {\n throw new NotAllowedError(); // 403\n }\n\n const entityRef = this.getEntityReference(request);\n\n const policy = await this.enforcer.getFilteredPolicy(0, entityRef);\n if (policy.length !== 0) {\n const body = await this.transformPolicyArray(...policy);\n\n await this.aLog.auditLog({\n message: `Return permission policy`,\n eventName: PermissionEvents.GET_POLICY,\n stage: SEND_RESPONSE_STAGE,\n status: 'succeeded',\n request,\n response: { status: 200, body },\n });\n\n response.json(body);\n } else {\n throw new NotFoundError(); // 404\n }\n },\n );\n\n router.delete(\n '/policies/:kind/:namespace/:name',\n async (request, response) => {\n const decision = await this.authorize(\n request,\n policyEntityDeletePermission,\n );\n\n if (decision.result === AuthorizeResult.DENY) {\n throw new NotAllowedError(); // 403\n }\n\n const entityRef = this.getEntityReference(request);\n\n const policyRaw: RoleBasedPolicy[] = request.body;\n if (isEmpty(policyRaw)) {\n throw new InputError(`permission policy must be present`); // 400\n }\n\n policyRaw.forEach(element => {\n element.entityReference = entityRef;\n });\n\n const processedPolicies = await this.processPolicies(policyRaw, true);\n\n await this.enforcer.removePolicies(processedPolicies);\n\n await this.aLog.auditLog<PermissionAuditInfo>({\n message: `Deleted permission policies`,\n eventName: PermissionEvents.DELETE_POLICY,\n metadata: { policies: processedPolicies, source: 'rest' },\n stage: SEND_RESPONSE_STAGE,\n status: 'succeeded',\n request,\n response: { status: 204 },\n });\n\n response.status(204).end();\n },\n );\n\n router.post('/policies', async (request, response) => {\n const decision = await this.authorize(\n request,\n policyEntityCreatePermission,\n );\n\n if (decision.result === AuthorizeResult.DENY) {\n throw new NotAllowedError(); // 403\n }\n\n const policyRaw: RoleBasedPolicy[] = request.body;\n\n if (isEmpty(policyRaw)) {\n throw new InputError(`permission policy must be present`); // 400\n }\n\n const processedPolicies = await this.processPolicies(policyRaw);\n\n const entityRef = processedPolicies[0][0];\n const roleMetadata = await this.roleMetadata.findRoleMetadata(entityRef);\n if (entityRef.startsWith('role:default') && !roleMetadata) {\n throw new Error(`Corresponding role ${entityRef} was not found`);\n }\n\n await this.enforcer.addPolicies(processedPolicies);\n\n await this.aLog.auditLog<PermissionAuditInfo>({\n message: `Created permission policies`,\n eventName: PermissionEvents.CREATE_POLICY,\n metadata: { policies: processedPolicies, source: 'rest' },\n stage: SEND_RESPONSE_STAGE,\n status: 'succeeded',\n request,\n response: { status: 201 },\n });\n\n response.status(201).end();\n });\n\n router.put(\n '/policies/:kind/:namespace/:name',\n async (request, response) => {\n const decision = await this.authorize(\n request,\n policyEntityUpdatePermission,\n );\n\n if (decision.result === AuthorizeResult.DENY) {\n throw new NotAllowedError(); // 403\n }\n\n const entityRef = this.getEntityReference(request);\n\n const oldPolicyRaw: RoleBasedPolicy[] = request.body.oldPolicy;\n if (isEmpty(oldPolicyRaw)) {\n throw new InputError(`'oldPolicy' object must be present`); // 400\n }\n const newPolicyRaw: RoleBasedPolicy[] = request.body.newPolicy;\n if (isEmpty(newPolicyRaw)) {\n throw new InputError(`'newPolicy' object must be present`); // 400\n }\n\n [...oldPolicyRaw, ...newPolicyRaw].forEach(element => {\n element.entityReference = entityRef;\n });\n\n const processedOldPolicy = await this.processPolicies(\n oldPolicyRaw,\n true,\n 'old policy',\n );\n\n oldPolicyRaw.sort((a, b) =>\n a.permission === b.permission\n ? this.nameSort(a.policy!, b.policy!)\n : this.nameSort(a.permission!, b.permission!),\n );\n\n newPolicyRaw.sort((a, b) =>\n a.permission === b.permission\n ? this.nameSort(a.policy!, b.policy!)\n : this.nameSort(a.permission!, b.permission!),\n );\n\n if (\n isEqual(oldPolicyRaw, newPolicyRaw) &&\n !oldPolicyRaw.some(isEmpty)\n ) {\n response.status(204).end();\n } else if (oldPolicyRaw.length > newPolicyRaw.length) {\n throw new InputError(\n `'oldPolicy' object has more permission policies compared to 'newPolicy' object`,\n );\n }\n\n const processedNewPolicy = await this.processPolicies(\n newPolicyRaw,\n false,\n 'new policy',\n );\n\n const roleMetadata =\n await this.roleMetadata.findRoleMetadata(entityRef);\n if (entityRef.startsWith('role:default') && !roleMetadata) {\n throw new Error(`Corresponding role ${entityRef} was not found`);\n }\n\n await this.enforcer.updatePolicies(\n processedOldPolicy,\n processedNewPolicy,\n );\n\n await this.aLog.auditLog<PermissionAuditInfo>({\n message: `Updated permission policies`,\n eventName: PermissionEvents.UPDATE_POLICY,\n metadata: { policies: processedNewPolicy, source: 'rest' },\n stage: SEND_RESPONSE_STAGE,\n status: 'succeeded',\n request,\n response: { status: 200 },\n });\n\n response.status(200).end();\n },\n );\n\n // Role CRUD\n\n router.get('/roles', async (request, response) => {\n const decision = await this.authorize(\n request,\n policyEntityReadPermission,\n );\n\n if (decision.result === AuthorizeResult.DENY) {\n throw new NotAllowedError(); // 403\n }\n\n const roles = await this.enforcer.getGroupingPolicy();\n\n const body = await this.transformRoleArray(...roles);\n\n await this.aLog.auditLog({\n message: `Return list roles`,\n eventName: RoleEvents.GET_ROLE,\n stage: SEND_RESPONSE_STAGE,\n status: 'succeeded',\n request,\n response: { status: 200, body },\n });\n\n response.json(body);\n });\n\n router.get('/roles/:kind/:namespace/:name', async (request, response) => {\n const decision = await this.authorize(\n request,\n policyEntityReadPermission,\n );\n\n if (decision.result === AuthorizeResult.DENY) {\n throw new NotAllowedError(); // 403\n }\n const roleEntityRef = this.getEntityReference(request, true);\n\n const role = await this.enforcer.getFilteredGroupingPolicy(\n 1,\n roleEntityRef,\n );\n\n if (role.length !== 0) {\n const body = await this.transformRoleArray(...role);\n\n await this.aLog.auditLog({\n message: `Return ${body[0].name}`,\n eventName: RoleEvents.GET_ROLE,\n stage: SEND_RESPONSE_STAGE,\n status: 'succeeded',\n request,\n response: { status: 200, body },\n });\n\n response.json(body);\n } else {\n throw new NotFoundError(); // 404\n }\n });\n\n router.post('/roles', async (request, response) => {\n const uniqueItems = new Set<string>();\n const decision = await this.authorize(\n request,\n policyEntityCreatePermission,\n );\n\n if (decision.result === AuthorizeResult.DENY) {\n throw new NotAllowedError(); // 403\n }\n const roleRaw: Role = request.body;\n let err = validateRole(roleRaw);\n if (err) {\n throw new InputError( // 400\n `Invalid role definition. Cause: ${err.message}`,\n );\n }\n this.transformMemberReferencesToLowercase(roleRaw);\n\n const rMetadata = await this.roleMetadata.findRoleMetadata(roleRaw.name);\n\n err = await validateSource('rest', rMetadata);\n if (err) {\n throw new NotAllowedError(`Unable to add role: ${err.message}`);\n }\n\n const roles = this.transformRoleToArray(roleRaw);\n\n for (const role of roles) {\n if (await this.enforcer.hasGroupingPolicy(...role)) {\n throw new ConflictError(); // 409\n }\n const roleString = JSON.stringify(role);\n\n if (uniqueItems.has(roleString)) {\n throw new ConflictError(\n `Duplicate role members found; ${role.at(0)}, ${role.at(\n 1,\n )} is a duplicate`,\n );\n } else {\n uniqueItems.add(roleString);\n }\n }\n\n const credentials = await httpAuth.credentials(request, {\n allow: ['user'],\n });\n const modifiedBy = credentials.principal.userEntityRef;\n const metadata: RoleMetadataDao = {\n roleEntityRef: roleRaw.name,\n source: 'rest',\n description: roleRaw.metadata?.description ?? '',\n author: modifiedBy,\n modifiedBy,\n };\n\n await this.enforcer.addGroupingPolicies(roles, metadata);\n\n await this.aLog.auditLog<RoleAuditInfo>({\n message: `Created ${metadata.roleEntityRef}`,\n eventName: RoleEvents.CREATE_ROLE,\n metadata: {\n ...metadata,\n members: roles.map(gp => gp[0]),\n },\n stage: SEND_RESPONSE_STAGE,\n status: 'succeeded',\n request,\n response: { status: 201 },\n });\n\n response.status(201).end();\n });\n\n router.put('/roles/:kind/:namespace/:name', async (request, response) => {\n const uniqueItems = new Set<string>();\n const decision = await this.authorize(\n request,\n policyEntityUpdatePermission,\n );\n\n if (decision.result === AuthorizeResult.DENY) {\n throw new NotAllowedError(); // 403\n }\n const roleEntityRef = this.getEntityReference(request, true);\n\n const oldRoleRaw: Role = request.body.oldRole;\n\n if (!oldRoleRaw) {\n throw new InputError(`'oldRole' object must be present`); // 400\n }\n const newRoleRaw: Role = request.body.newRole;\n if (!newRoleRaw) {\n throw new InputError(`'newRole' object must be present`); // 400\n }\n\n oldRoleRaw.name = roleEntityRef;\n let err = validateRole(oldRoleRaw);\n if (err) {\n throw new InputError( // 400\n `Invalid old role object. Cause: ${err.message}`,\n );\n }\n err = validateRole(newRoleRaw);\n if (err) {\n throw new InputError( // 400\n `Invalid new role object. Cause: ${err.message}`,\n );\n }\n this.transformMemberReferencesToLowercase(oldRoleRaw);\n this.transformMemberReferencesToLowercase(newRoleRaw);\n\n const oldRole = this.transformRoleToArray(oldRoleRaw);\n const newRole = this.transformRoleToArray(newRoleRaw);\n // todo shell we allow newRole with an empty array?...\n\n const credentials = await httpAuth.credentials(request, {\n allow: ['user'],\n });\n\n const newMetadata: RoleMetadataDao = {\n ...newRoleRaw.metadata,\n source: newRoleRaw.metadata?.source ?? 'rest',\n roleEntityRef: newRoleRaw.name,\n modifiedBy: credentials.principal.userEntityRef,\n };\n\n const oldMetadata =\n await this.roleMetadata.findRoleMetadata(roleEntityRef);\n if (!oldMetadata) {\n throw new NotFoundError(`Unable to find metadata for ${roleEntityRef}`);\n }\n\n err = await validateSource('rest', oldMetadata);\n if (err) {\n throw new NotAllowedError(`Unable to edit role: ${err.message}`);\n }\n\n if (\n isEqual(oldRole, newRole) &&\n deepSortedEqual(oldMetadata, newMetadata, [\n 'author',\n 'modifiedBy',\n 'createdAt',\n 'lastModified',\n ])\n ) {\n // no content: old role and new role are equal and their metadata too\n response.status(204).end();\n return;\n }\n\n for (const role of newRole) {\n const hasRole = oldRole.some(element => {\n return isEqual(element, role);\n });\n // if the role is already part of old role and is a grouping policy we want to skip returning a conflict error\n // to allow for other roles to be checked and added\n if (await this.enforcer.hasGroupingPolicy(...role)) {\n if (!hasRole) {\n throw new ConflictError(); // 409\n }\n }\n const roleString = JSON.stringify(role);\n\n if (uniqueItems.has(roleString)) {\n throw new ConflictError(\n `Duplicate role members found; ${role.at(0)}, ${role.at(\n 1,\n )} is a duplicate`,\n );\n } else {\n uniqueItems.add(roleString);\n }\n }\n\n uniqueItems.clear();\n for (const role of oldRole) {\n if (!(await this.enforcer.hasGroupingPolicy(...role))) {\n throw new NotFoundError(\n `Member reference: ${role[0]} was not found for role ${roleEntityRef}`,\n ); // 404\n }\n const roleString = JSON.stringify(role);\n\n if (uniqueItems.has(roleString)) {\n throw new ConflictError(\n `Duplicate role members found; ${role.at(0)}, ${role.at(\n 1,\n )} is a duplicate`,\n );\n } else {\n uniqueItems.add(roleString);\n }\n }\n\n await this.enforcer.updateGroupingPolicies(oldRole, newRole, newMetadata);\n\n let message = `Updated ${oldMetadata.roleEntityRef}.`;\n if (newMetadata.roleEntityRef !== oldMetadata.roleEntityRef) {\n message = `${message}. Role entity reference renamed to ${newMetadata.roleEntityRef}`;\n }\n await this.aLog.auditLog<RoleAuditInfo>({\n message,\n eventName: RoleEvents.UPDATE_ROLE,\n metadata: {\n ...newMetadata,\n members: newRole.map(gp => gp[0]),\n },\n stage: SEND_RESPONSE_STAGE,\n status: 'succeeded',\n request,\n response: { status: 200 },\n });\n\n response.status(200).end();\n });\n\n router.delete(\n '/roles/:kind/:namespace/:name',\n async (request, response) => {\n const decision = await this.authorize(\n request,\n policyEntityDeletePermission,\n );\n\n if (decision.result === AuthorizeResult.DENY) {\n throw new NotAllowedError(); // 403\n }\n\n const roleEntityRef = this.getEntityReference(request, true);\n\n let roleMembers = [];\n if (request.query.memberReferences) {\n const memberReference = this.getFirstQuery(\n request.query.memberReferences!,\n ).toLocaleLowerCase('en-US');\n const gp = await this.enforcer.getFilteredGroupingPolicy(\n 0,\n memberReference,\n roleEntityRef,\n );\n if (gp.length > 0) {\n roleMembers.push(gp[0]);\n } else {\n throw new NotFoundError(\n `role member '${memberReference}' was not found`,\n ); // 404\n }\n } else {\n roleMembers = await this.enforcer.getFilteredGroupingPolicy(\n 1,\n roleEntityRef,\n );\n }\n\n for (const role of roleMembers) {\n if (!(await this.enforcer.hasGroupingPolicy(...role))) {\n throw new NotFoundError(`role member '${role[0]}' was not found`);\n }\n }\n\n const currentMetadata =\n await this.roleMetadata.findRoleMetadata(roleEntityRef);\n const err = await validateSource('rest', currentMetadata);\n if (err) {\n throw new NotAllowedError(`Unable to delete role: ${err.message}`);\n }\n\n const credentials = await httpAuth.credentials(request, {\n allow: ['user'],\n });\n\n const metadata: RoleMetadataDao = {\n roleEntityRef,\n source: 'rest',\n modifiedBy: credentials.principal.userEntityRef,\n };\n\n await this.enforcer.removeGroupingPolicies(\n roleMembers,\n metadata,\n false,\n );\n\n await this.aLog.auditLog<RoleAuditInfo>({\n message: `Deleted ${metadata.roleEntityRef}`,\n eventName: RoleEvents.DELETE_ROLE,\n metadata: {\n ...metadata,\n members: roleMembers.map(gp => gp[0]),\n },\n stage: SEND_RESPONSE_STAGE,\n status: 'succeeded',\n request,\n response: { status: 204 },\n });\n\n response.status(204).end();\n },\n );\n\n router.get('/plugins/policies', async (request, response) => {\n const decision = await this.authorize(\n request,\n policyEntityReadPermission,\n );\n\n if (decision.result === AuthorizeResult.DENY) {\n throw new NotAllowedError(); // 403\n }\n\n const body = await this.pluginPermMetaData.getPluginPolicies(\n this.options.auth,\n );\n\n await this.aLog.auditLog({\n message: `Return list plugin policies`,\n eventName: ListPluginPoliciesEvents.GET_PLUGINS_POLICIES,\n stage: SEND_RESPONSE_STAGE,\n status: 'succeeded',\n request,\n response: { status: 200, body },\n });\n\n response.json(body);\n });\n\n router.get('/plugins/condition-rules', async (request, response) => {\n const decision = await this.authorize(\n request,\n policyEntityReadPermission,\n );\n\n if (decision.result === AuthorizeResult.DENY) {\n throw new NotAllowedError(); // 403\n }\n\n const body = await this.pluginPermMetaData.getPluginConditionRules(\n this.options.auth,\n );\n\n await this.aLog.auditLog({\n message: `Return list conditional rules and schemas`,\n eventName: ListConditionEvents.GET_CONDITION_RULES,\n stage: SEND_RESPONSE_STAGE,\n status: 'succeeded',\n request,\n response: { status: 200, body },\n });\n\n response.json(body);\n });\n\n router.get('/roles/conditions', async (request, response) => {\n const decision = await this.authorize(\n request,\n policyEntityReadPermission,\n );\n\n if (decision.result === AuthorizeResult.DENY) {\n throw new NotAllowedError(); // 403\n }\n\n const conditions = await this.conditionalStorage.filterConditions(\n this.getFirstQuery(request.query.roleEntityRef),\n this.getFirstQuery(request.query.pluginId),\n this.getFirstQuery(request.query.resourceType),\n this.getActionQueries(request.query.actions),\n );\n\n const body: RoleConditionalPolicyDecision<PermissionAction>[] =\n conditions.map(condition => {\n return {\n ...condition,\n permissionMapping: condition.permissionMapping.map(pm => pm.action),\n };\n });\n\n await this.aLog.auditLog({\n message: `Return list conditional permission policies`,\n eventName: ConditionEvents.GET_CONDITION,\n stage: SEND_RESPONSE_STAGE,\n status: 'succeeded',\n request,\n response: { status: 200, body },\n });\n\n response.json(body);\n });\n\n router.post('/roles/conditions', async (request, response) => {\n const decision = await this.authorize(\n request,\n policyEntityCreatePermission,\n );\n\n if (decision.result === AuthorizeResult.DENY) {\n throw new NotAllowedError(); // 403\n }\n\n const roleConditionPolicy: RoleConditionalPolicyDecision<PermissionAction> =\n request.body;\n validateRoleCondition(roleConditionPolicy);\n\n const conditionToCreate = await processConditionMapping(\n roleConditionPolicy,\n this.pluginPermMetaData,\n this.options.auth,\n );\n\n const id =\n await this.conditionalStorage.createCondition(conditionToCreate);\n\n const body = { id: id };\n\n await this.aLog.auditLog<ConditionAuditInfo>({\n message: `Created conditional permission policy`,\n eventName: ConditionEvents.CREATE_CONDITION,\n metadata: { condition: roleConditionPolicy },\n stage: SEND_RESPONSE_STAGE,\n status: 'succeeded',\n request,\n response: { status: 201, body },\n });\n\n response.status(201).json(body);\n });\n\n router.get('/roles/conditions/:id', async (request, response) => {\n const decision = await this.authorize(\n request,\n policyEntityReadPermission,\n );\n\n if (decision.result === AuthorizeResult.DENY) {\n throw new NotAllowedError(); // 403\n }\n\n const id: number = parseInt(request.params.id, 10);\n if (isNaN(id)) {\n throw new InputError('Id is not a valid number.');\n }\n\n const condition = await this.conditionalStorage.getCondition(id);\n if (!condition) {\n throw new NotFoundError();\n }\n\n const body: RoleConditionalPolicyDecision<PermissionAction> = {\n ...condition,\n permissionMapping: condition.permissionMapping.map(pm => pm.action),\n };\n\n await this.aLog.auditLog({\n message: `Return conditional permission policy by id`,\n eventName: ConditionEvents.GET_CONDITION,\n stage: SEND_RESPONSE_STAGE,\n status: 'succeeded',\n request,\n response: { status: 200, body },\n });\n\n response.json(body);\n });\n\n router.delete('/roles/conditions/:id', async (request, response) => {\n const decision = await this.authorize(\n request,\n policyEntityDeletePermission,\n );\n\n if (decision.result === AuthorizeResult.DENY) {\n throw new NotAllowedError(); // 403\n }\n\n const id: number = parseInt(request.params.id, 10);\n if (isNaN(id)) {\n throw new InputError('Id is not a valid number.');\n }\n\n const condition = await this.conditionalStorage.getCondition(id);\n if (!condition) {\n throw new NotFoundError(`Condition with id ${id} was not found`);\n }\n const conditionToDelete: RoleConditionalPolicyDecision<PermissionAction> =\n {\n ...condition,\n permissionMapping: condition.permissionMapping.map(pm => pm.action),\n };\n\n await this.conditionalStorage.deleteCondition(id);\n\n await this.aLog.auditLog<ConditionAuditInfo>({\n message: `Deleted conditional permission policy`,\n eventName: ConditionEvents.DELETE_CONDITION,\n metadata: { condition: conditionToDelete },\n stage: SEND_RESPONSE_STAGE,\n status: 'succeeded',\n request,\n response: { status: 204 },\n });\n\n response.status(204).end();\n });\n\n router.put('/roles/conditions/:id', async (request, response) => {\n const decision = await this.authorize(\n request,\n policyEntityUpdatePermission,\n );\n\n if (decision.result === AuthorizeResult.DENY) {\n throw new NotAllowedError(); // 403\n }\n\n const id: number = parseInt(request.params.id, 10);\n if (isNaN(id)) {\n throw new InputError('Id is not a valid number.');\n }\n\n const roleConditionPolicy: RoleConditionalPolicyDecision<PermissionAction> =\n request.body;\n\n validateRoleCondition(roleConditionPolicy);\n\n const conditionToUpdate = await processConditionMapping(\n roleConditionPolicy,\n this.pluginPermMetaData,\n this.options.auth,\n );\n\n await this.conditionalStorage.updateCondition(id, conditionToUpdate);\n\n await this.aLog.auditLog<ConditionAuditInfo>({\n message: `Updated conditional permission policy`,\n eventName: ConditionEvents.UPDATE_CONDITION,\n metadata: { condition: roleConditionPolicy },\n stage: SEND_RESPONSE_STAGE,\n status: 'succeeded',\n request,\n response: { status: 200 },\n });\n\n response.status(200).end();\n });\n\n router.post('/refresh/:id', async (request, response) => {\n const decision = await this.authorize(\n request,\n policyEntityCreatePermission,\n );\n\n if (decision.result === AuthorizeResult.DENY) {\n throw new NotAllowedError(); // 403\n }\n\n if (!this.rbacProviders) {\n throw new NotFoundError(`No RBAC providers were found`);\n }\n\n const idProvider = this.rbacProviders.find(provider => {\n const id = provider.getProviderName();\n return id === request.params.id;\n });\n\n if (!idProvider) {\n throw new NotFoundError(\n `The RBAC provider ${request.params.id} was not found`,\n );\n }\n\n await idProvider.refresh();\n response.status(200).end();\n });\n\n router.use(logAuditError(this.aLog));\n\n return router;\n }\n\n getEntityReference(request: Request, role?: boolean): string {\n const kind = request.params.kind;\n const namespace = request.params.namespace;\n const name = request.params.name;\n const entityRef = `${kind}:${namespace}/${name}`;\n\n const err = validateEntityReference(entityRef, role);\n if (err) {\n throw new InputError(err.message);\n }\n\n return entityRef;\n }\n\n async transformPolicyArray(\n ...policies: string[][]\n ): Promise<RoleBasedPolicy[]> {\n const roleToSourceMap = await buildRoleSourceMap(\n policies,\n this.roleMetadata,\n );\n\n const roleBasedPolices: RoleBasedPolicy[] = [];\n for (const p of policies) {\n const [entityReference, permission, policy, effect] = p;\n roleBasedPolices.push({\n entityReference,\n permission,\n policy,\n effect,\n metadata: { source: roleToSourceMap.get(entityReference)! },\n });\n }\n\n return roleBasedPolices;\n }\n\n async transformRoleArray(...roles: string[][]): Promise<Role[]> {\n const combinedRoles: { [key: string]: string[] } = {};\n\n roles.forEach(([value, role]) => {\n if (combinedRoles.hasOwnProperty(role)) {\n combinedRoles[role].push(value);\n } else {\n combinedRoles[role] = [value];\n }\n });\n\n const result: Role[] = await Promise.all(\n Object.entries(combinedRoles).map(async ([role, value]) => {\n const metadataDao = await this.roleMetadata.findRoleMetadata(role);\n const metadata = metadataDao ? daoToMetadata(metadataDao) : undefined;\n return Promise.resolve({\n memberReferences: value,\n name: role,\n metadata,\n });\n }),\n );\n return result;\n }\n\n transformPolicyToArray(policy: RoleBasedPolicy): string[] {\n return [\n policy.entityReference!,\n policy.permission!,\n policy.policy!,\n policy.effect!,\n ];\n }\n\n transformRoleToArray(role: Role): string[][] {\n const roles: string[][] = [];\n for (const entity of role.memberReferences) {\n roles.push([entity, role.name]);\n }\n return roles;\n }\n\n transformMemberReferencesToLowercase(role: Role) {\n role.memberReferences = role.memberReferences.map(member =>\n member.toLocaleLowerCase('en-US'),\n );\n }\n\n getActionQueries(\n queryValue: string | string[] | ParsedQs | ParsedQs[] | undefined,\n ): PermissionAction[] | undefined {\n if (!queryValue) {\n return undefined;\n }\n if (Array.isArray(queryValue)) {\n const permissionNames: PermissionAction[] = [];\n for (const permissionQuery of queryValue) {\n if (\n typeof permissionQuery === 'string' &&\n isPermissionAction(permissionQuery)\n ) {\n permissionNames.push(permissionQuery);\n } else {\n throw new InputError(\n `Invalid permission action query value: ${permissionQuery}. Permission name should be string.`,\n );\n }\n }\n return permissionNames;\n }\n\n if (typeof queryValue === 'string' && isPermissionAction(queryValue)) {\n return [queryValue];\n }\n throw new InputError(\n `Invalid permission action query value: ${queryValue}. Permission name should be string.`,\n );\n }\n\n getFirstQuery(\n queryValue: string | string[] | ParsedQs | ParsedQs[] | undefined,\n ): string {\n if (!queryValue) {\n return '';\n }\n if (Array.isArray(queryValue)) {\n if (typeof queryValue[0] === 'string') {\n return queryValue[0].toString();\n }\n throw new InputError(`This api doesn't support nested query`);\n }\n\n if (typeof queryValue === 'string') {\n return queryValue;\n }\n throw new InputError(`This api doesn't support nested query`);\n }\n\n isPolicyFilterEnabled(request: Request): boolean {\n return (\n !!request.query.entityRef ||\n !!request.query.permission ||\n !!request.query.policy ||\n !!request.query.effect\n );\n }\n\n async processPolicies(\n policyArray: RoleBasedPolicy[],\n isOld?: boolean,\n errorMessage?: string,\n ): Promise<string[][]> {\n const policies: string[][] = [];\n const uniqueItems = new Set<string>();\n for (const policy of policyArray) {\n let err = validatePolicy(policy);\n if (err) {\n throw new InputError(\n `Invalid ${errorMessage ?? 'policy'} definition. Cause: ${\n err.message\n }`,\n ); // 400\n }\n\n const metadata = await this.roleMetadata.findRoleMetadata(\n policy.entityReference!,\n );\n\n let action = errorMessage ? 'edit' : 'delete';\n action = isOld ? action : 'add';\n\n err = await validateSource('rest', metadata);\n if (err) {\n throw new NotAllowedError(\n `Unable to ${action} policy ${policy.entityReference},${policy.permission},${policy.policy},${policy.effect}: ${err.message}`,\n );\n }\n\n const transformedPolicy = this.transformPolicyToArray(policy);\n if (isOld && !(await this.enforcer.hasPolicy(...transformedPolicy))) {\n throw new NotFoundError(\n `Policy '${policyToString(transformedPolicy)}' not found`,\n ); // 404\n }\n\n if (!isOld && (await this.enforcer.hasPolicy(...transformedPolicy))) {\n throw new ConflictError(\n `Policy '${policyToString(\n transformedPolicy,\n )}' has been already stored`,\n ); // 409\n }\n\n // We want to ensure that there are not duplicate permission policies\n const rowString = JSON.stringify(transformedPolicy);\n if (uniqueItems.has(rowString)) {\n throw new ConflictError(\n `Duplicate polices found; ${policy.entityReference}, ${policy.permission}, ${policy.policy}, ${policy.effect} is a duplicate`,\n );\n } else {\n uniqueItems.add(rowString);\n policies.push(transformedPolicy);\n }\n }\n return policies;\n }\n\n nameSort(nameA: string, nameB: string): number {\n if (nameA.toLocaleUpperCase('en-US') < nameB.toLocaleUpperCase('en-US')) {\n return -1;\n }\n if (nameA.toLocaleUpperCase('en-US') > nameB.toLocaleUpperCase('en-US')) {\n return 1;\n }\n return 0;\n }\n}\n"],"names":["policyEntityReadPermission","NotAllowedError","createRouter","ServiceUnavailableError","createPermissionIntegrationRouter","RESOURCE_TYPE_POLICY_ENTITY","policyEntityPermissions","AuthorizeResult","PermissionEvents","SEND_RESPONSE_STAGE","NotFoundError","policyEntityDeletePermission","isEmpty","InputError","policyEntityCreatePermission","policyEntityUpdatePermission","isEqual","RoleEvents","validateRole","validateSource","ConflictError","deepSortedEqual","ListPluginPoliciesEvents","ListConditionEvents","ConditionEvents","validateRoleCondition","processConditionMapping","logAuditError","validateEntityReference","buildRoleSourceMap","daoToMetadata","isPermissionAction","validatePolicy","policyToString"],"mappings":"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"}
1
+ {"version":3,"file":"policies-rest-api.cjs.js","sources":["../../src/service/policies-rest-api.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 { PermissionsService } from '@backstage/backend-plugin-api';\nimport {\n ConflictError,\n InputError,\n NotAllowedError,\n NotFoundError,\n ServiceUnavailableError,\n} from '@backstage/errors';\nimport { createRouter } from '@backstage/plugin-permission-backend';\nimport {\n AuthorizeResult,\n PolicyDecision,\n ResourcePermission,\n} from '@backstage/plugin-permission-common';\nimport { createPermissionIntegrationRouter } from '@backstage/plugin-permission-node';\n\nimport type { AuditLogger } from '@janus-idp/backstage-plugin-audit-log-node';\nimport express from 'express';\nimport type { Request } from 'express-serve-static-core';\nimport { isEmpty, isEqual } from 'lodash';\nimport type { ParsedQs } from 'qs';\n\nimport {\n PermissionAction,\n policyEntityCreatePermission,\n policyEntityDeletePermission,\n policyEntityPermissions,\n policyEntityReadPermission,\n policyEntityUpdatePermission,\n RESOURCE_TYPE_POLICY_ENTITY,\n Role,\n RoleBasedPolicy,\n RoleConditionalPolicyDecision,\n} from '@backstage-community/plugin-rbac-common';\nimport type { RBACProvider } from '@backstage-community/plugin-rbac-node';\n\nimport {\n ConditionAuditInfo,\n ConditionEvents,\n ListConditionEvents,\n ListPluginPoliciesEvents,\n PermissionAuditInfo,\n PermissionEvents,\n RoleAuditInfo,\n RoleEvents,\n SEND_RESPONSE_STAGE,\n} from '../audit-log/audit-logger';\nimport { auditError as logAuditError } from '../audit-log/rest-errors-interceptor';\nimport { ConditionalStorage } from '../database/conditional-storage';\nimport {\n daoToMetadata,\n RoleMetadataDao,\n RoleMetadataStorage,\n} from '../database/role-metadata';\nimport {\n buildRoleSourceMap,\n deepSortedEqual,\n isPermissionAction,\n policyToString,\n processConditionMapping,\n} from '../helper';\nimport { validateRoleCondition } from '../validation/condition-validation';\nimport {\n validateEntityReference,\n validatePolicy,\n validateRole,\n validateSource,\n} from '../validation/policies-validation';\nimport { EnforcerDelegate } from './enforcer-delegate';\nimport { PluginPermissionMetadataCollector } from './plugin-endpoints';\nimport { RBACRouterOptions } from './policy-builder';\n\nexport class PoliciesServer {\n constructor(\n private readonly permissions: PermissionsService,\n private readonly options: RBACRouterOptions,\n private readonly enforcer: EnforcerDelegate,\n private readonly conditionalStorage: ConditionalStorage,\n private readonly pluginPermMetaData: PluginPermissionMetadataCollector,\n private readonly roleMetadata: RoleMetadataStorage,\n private readonly aLog: AuditLogger,\n private readonly rbacProviders?: RBACProvider[],\n ) {}\n\n private async authorize(\n request: Request,\n permission: ResourcePermission,\n ): Promise<PolicyDecision> {\n const credentials = await this.options.httpAuth.credentials(request, {\n allow: ['user', 'service'],\n });\n\n // allow service to service communication, but only with read permission\n if (\n this.options.auth.isPrincipal(credentials, 'service') &&\n permission !== policyEntityReadPermission\n ) {\n throw new NotAllowedError(\n `Only creadential principal with type 'user' permitted to modify permissions`,\n );\n }\n\n const decision = (\n await this.permissions.authorize(\n [{ permission: permission, resourceRef: permission.resourceType }],\n { credentials },\n )\n )[0];\n\n return decision;\n }\n\n async serve(): Promise<express.Router> {\n const router = await createRouter(this.options);\n\n const { httpAuth } = this.options;\n\n if (!httpAuth) {\n throw new ServiceUnavailableError(\n 'httpAuth not found, ensure the correct configuration for the RBAC plugin',\n );\n }\n\n const permissionsIntegrationRouter = createPermissionIntegrationRouter({\n resourceType: RESOURCE_TYPE_POLICY_ENTITY,\n permissions: policyEntityPermissions,\n });\n router.use(permissionsIntegrationRouter);\n\n const isPluginEnabled =\n this.options.config.getOptionalBoolean('permission.enabled');\n if (!isPluginEnabled) {\n return router;\n }\n\n router.get('/', async (request, response) => {\n const decision = await this.authorize(\n request,\n policyEntityReadPermission,\n );\n\n if (decision.result === AuthorizeResult.DENY) {\n throw new NotAllowedError(); // 403\n }\n response.send({ status: 'Authorized' });\n });\n\n // Policy CRUD\n\n router.get('/policies', async (request, response) => {\n const decision = await this.authorize(\n request,\n policyEntityReadPermission,\n );\n\n if (decision.result === AuthorizeResult.DENY) {\n throw new NotAllowedError(); // 403\n }\n\n let policies: string[][];\n if (this.isPolicyFilterEnabled(request)) {\n const entityRef = this.getFirstQuery(request.query.entityRef);\n const permission = this.getFirstQuery(request.query.permission);\n const policy = this.getFirstQuery(request.query.policy);\n const effect = this.getFirstQuery(request.query.effect);\n\n const filter: string[] = [entityRef, permission, policy, effect];\n policies = await this.enforcer.getFilteredPolicy(0, ...filter);\n } else {\n policies = await this.enforcer.getPolicy();\n }\n\n const body = await this.transformPolicyArray(...policies);\n\n await this.aLog.auditLog({\n message: `Return list permission policies`,\n eventName: PermissionEvents.GET_POLICY,\n stage: SEND_RESPONSE_STAGE,\n status: 'succeeded',\n request,\n response: { status: 200, body },\n });\n\n response.json(body);\n });\n\n router.get(\n '/policies/:kind/:namespace/:name',\n async (request, response) => {\n const decision = await this.authorize(\n request,\n policyEntityReadPermission,\n );\n\n if (decision.result === AuthorizeResult.DENY) {\n throw new NotAllowedError(); // 403\n }\n\n const entityRef = this.getEntityReference(request);\n\n const policy = await this.enforcer.getFilteredPolicy(0, entityRef);\n if (policy.length !== 0) {\n const body = await this.transformPolicyArray(...policy);\n\n await this.aLog.auditLog({\n message: `Return permission policy`,\n eventName: PermissionEvents.GET_POLICY,\n stage: SEND_RESPONSE_STAGE,\n status: 'succeeded',\n request,\n response: { status: 200, body },\n });\n\n response.json(body);\n } else {\n throw new NotFoundError(); // 404\n }\n },\n );\n\n router.delete(\n '/policies/:kind/:namespace/:name',\n async (request, response) => {\n const decision = await this.authorize(\n request,\n policyEntityDeletePermission,\n );\n\n if (decision.result === AuthorizeResult.DENY) {\n throw new NotAllowedError(); // 403\n }\n\n const entityRef = this.getEntityReference(request);\n\n const policyRaw: RoleBasedPolicy[] = request.body;\n if (isEmpty(policyRaw)) {\n throw new InputError(`permission policy must be present`); // 400\n }\n\n policyRaw.forEach(element => {\n element.entityReference = entityRef;\n });\n\n const processedPolicies = await this.processPolicies(policyRaw, true);\n\n await this.enforcer.removePolicies(processedPolicies);\n\n await this.aLog.auditLog<PermissionAuditInfo>({\n message: `Deleted permission policies`,\n eventName: PermissionEvents.DELETE_POLICY,\n metadata: { policies: processedPolicies, source: 'rest' },\n stage: SEND_RESPONSE_STAGE,\n status: 'succeeded',\n request,\n response: { status: 204 },\n });\n\n response.status(204).end();\n },\n );\n\n router.post('/policies', async (request, response) => {\n const decision = await this.authorize(\n request,\n policyEntityCreatePermission,\n );\n\n if (decision.result === AuthorizeResult.DENY) {\n throw new NotAllowedError(); // 403\n }\n\n const policyRaw: RoleBasedPolicy[] = request.body;\n\n if (isEmpty(policyRaw)) {\n throw new InputError(`permission policy must be present`); // 400\n }\n\n const processedPolicies = await this.processPolicies(policyRaw);\n\n const entityRef = processedPolicies[0][0];\n const roleMetadata = await this.roleMetadata.findRoleMetadata(entityRef);\n if (entityRef.startsWith('role:default') && !roleMetadata) {\n throw new Error(`Corresponding role ${entityRef} was not found`);\n }\n\n await this.enforcer.addPolicies(processedPolicies);\n\n await this.aLog.auditLog<PermissionAuditInfo>({\n message: `Created permission policies`,\n eventName: PermissionEvents.CREATE_POLICY,\n metadata: { policies: processedPolicies, source: 'rest' },\n stage: SEND_RESPONSE_STAGE,\n status: 'succeeded',\n request,\n response: { status: 201 },\n });\n\n response.status(201).end();\n });\n\n router.put(\n '/policies/:kind/:namespace/:name',\n async (request, response) => {\n const decision = await this.authorize(\n request,\n policyEntityUpdatePermission,\n );\n\n if (decision.result === AuthorizeResult.DENY) {\n throw new NotAllowedError(); // 403\n }\n\n const entityRef = this.getEntityReference(request);\n\n const oldPolicyRaw: RoleBasedPolicy[] = request.body.oldPolicy;\n if (isEmpty(oldPolicyRaw)) {\n throw new InputError(`'oldPolicy' object must be present`); // 400\n }\n const newPolicyRaw: RoleBasedPolicy[] = request.body.newPolicy;\n if (isEmpty(newPolicyRaw)) {\n throw new InputError(`'newPolicy' object must be present`); // 400\n }\n\n [...oldPolicyRaw, ...newPolicyRaw].forEach(element => {\n element.entityReference = entityRef;\n });\n\n const processedOldPolicy = await this.processPolicies(\n oldPolicyRaw,\n true,\n 'old policy',\n );\n\n oldPolicyRaw.sort((a, b) =>\n a.permission === b.permission\n ? this.nameSort(a.policy!, b.policy!)\n : this.nameSort(a.permission!, b.permission!),\n );\n\n newPolicyRaw.sort((a, b) =>\n a.permission === b.permission\n ? this.nameSort(a.policy!, b.policy!)\n : this.nameSort(a.permission!, b.permission!),\n );\n\n if (\n isEqual(oldPolicyRaw, newPolicyRaw) &&\n !oldPolicyRaw.some(isEmpty)\n ) {\n response.status(204).end();\n } else if (oldPolicyRaw.length > newPolicyRaw.length) {\n throw new InputError(\n `'oldPolicy' object has more permission policies compared to 'newPolicy' object`,\n );\n }\n\n const processedNewPolicy = await this.processPolicies(\n newPolicyRaw,\n false,\n 'new policy',\n );\n\n const roleMetadata =\n await this.roleMetadata.findRoleMetadata(entityRef);\n if (entityRef.startsWith('role:default') && !roleMetadata) {\n throw new Error(`Corresponding role ${entityRef} was not found`);\n }\n\n await this.enforcer.updatePolicies(\n processedOldPolicy,\n processedNewPolicy,\n );\n\n await this.aLog.auditLog<PermissionAuditInfo>({\n message: `Updated permission policies`,\n eventName: PermissionEvents.UPDATE_POLICY,\n metadata: { policies: processedNewPolicy, source: 'rest' },\n stage: SEND_RESPONSE_STAGE,\n status: 'succeeded',\n request,\n response: { status: 200 },\n });\n\n response.status(200).end();\n },\n );\n\n // Role CRUD\n\n router.get('/roles', async (request, response) => {\n const decision = await this.authorize(\n request,\n policyEntityReadPermission,\n );\n\n if (decision.result === AuthorizeResult.DENY) {\n throw new NotAllowedError(); // 403\n }\n\n const roles = await this.enforcer.getGroupingPolicy();\n\n const body = await this.transformRoleArray(...roles);\n\n await this.aLog.auditLog({\n message: `Return list roles`,\n eventName: RoleEvents.GET_ROLE,\n stage: SEND_RESPONSE_STAGE,\n status: 'succeeded',\n request,\n response: { status: 200, body },\n });\n\n response.json(body);\n });\n\n router.get('/roles/:kind/:namespace/:name', async (request, response) => {\n const decision = await this.authorize(\n request,\n policyEntityReadPermission,\n );\n\n if (decision.result === AuthorizeResult.DENY) {\n throw new NotAllowedError(); // 403\n }\n const roleEntityRef = this.getEntityReference(request, true);\n\n const role = await this.enforcer.getFilteredGroupingPolicy(\n 1,\n roleEntityRef,\n );\n\n if (role.length !== 0) {\n const body = await this.transformRoleArray(...role);\n\n await this.aLog.auditLog({\n message: `Return ${body[0].name}`,\n eventName: RoleEvents.GET_ROLE,\n stage: SEND_RESPONSE_STAGE,\n status: 'succeeded',\n request,\n response: { status: 200, body },\n });\n\n response.json(body);\n } else {\n throw new NotFoundError(); // 404\n }\n });\n\n router.post('/roles', async (request, response) => {\n const uniqueItems = new Set<string>();\n const decision = await this.authorize(\n request,\n policyEntityCreatePermission,\n );\n\n if (decision.result === AuthorizeResult.DENY) {\n throw new NotAllowedError(); // 403\n }\n const roleRaw: Role = request.body;\n let err = validateRole(roleRaw);\n if (err) {\n throw new InputError( // 400\n `Invalid role definition. Cause: ${err.message}`,\n );\n }\n this.transformMemberReferencesToLowercase(roleRaw);\n\n const rMetadata = await this.roleMetadata.findRoleMetadata(roleRaw.name);\n\n err = await validateSource('rest', rMetadata);\n if (err) {\n throw new NotAllowedError(`Unable to add role: ${err.message}`);\n }\n\n const roles = this.transformRoleToArray(roleRaw);\n\n for (const role of roles) {\n if (await this.enforcer.hasGroupingPolicy(...role)) {\n throw new ConflictError(); // 409\n }\n const roleString = JSON.stringify(role);\n\n if (uniqueItems.has(roleString)) {\n throw new ConflictError(\n `Duplicate role members found; ${role.at(0)}, ${role.at(\n 1,\n )} is a duplicate`,\n );\n } else {\n uniqueItems.add(roleString);\n }\n }\n\n const credentials = await httpAuth.credentials(request, {\n allow: ['user'],\n });\n const modifiedBy = credentials.principal.userEntityRef;\n const metadata: RoleMetadataDao = {\n roleEntityRef: roleRaw.name,\n source: 'rest',\n description: roleRaw.metadata?.description ?? '',\n author: modifiedBy,\n modifiedBy,\n };\n\n await this.enforcer.addGroupingPolicies(roles, metadata);\n\n await this.aLog.auditLog<RoleAuditInfo>({\n message: `Created ${metadata.roleEntityRef}`,\n eventName: RoleEvents.CREATE_ROLE,\n metadata: {\n ...metadata,\n members: roles.map(gp => gp[0]),\n },\n stage: SEND_RESPONSE_STAGE,\n status: 'succeeded',\n request,\n response: { status: 201 },\n });\n\n response.status(201).end();\n });\n\n router.put('/roles/:kind/:namespace/:name', async (request, response) => {\n const uniqueItems = new Set<string>();\n const decision = await this.authorize(\n request,\n policyEntityUpdatePermission,\n );\n\n if (decision.result === AuthorizeResult.DENY) {\n throw new NotAllowedError(); // 403\n }\n const roleEntityRef = this.getEntityReference(request, true);\n\n const oldRoleRaw: Role = request.body.oldRole;\n\n if (!oldRoleRaw) {\n throw new InputError(`'oldRole' object must be present`); // 400\n }\n const newRoleRaw: Role = request.body.newRole;\n if (!newRoleRaw) {\n throw new InputError(`'newRole' object must be present`); // 400\n }\n\n oldRoleRaw.name = roleEntityRef;\n let err = validateRole(oldRoleRaw);\n if (err) {\n throw new InputError( // 400\n `Invalid old role object. Cause: ${err.message}`,\n );\n }\n err = validateRole(newRoleRaw);\n if (err) {\n throw new InputError( // 400\n `Invalid new role object. Cause: ${err.message}`,\n );\n }\n this.transformMemberReferencesToLowercase(oldRoleRaw);\n this.transformMemberReferencesToLowercase(newRoleRaw);\n\n const oldRole = this.transformRoleToArray(oldRoleRaw);\n const newRole = this.transformRoleToArray(newRoleRaw);\n // todo shell we allow newRole with an empty array?...\n\n const credentials = await httpAuth.credentials(request, {\n allow: ['user'],\n });\n\n const newMetadata: RoleMetadataDao = {\n ...newRoleRaw.metadata,\n source: newRoleRaw.metadata?.source ?? 'rest',\n roleEntityRef: newRoleRaw.name,\n modifiedBy: credentials.principal.userEntityRef,\n };\n\n const oldMetadata =\n await this.roleMetadata.findRoleMetadata(roleEntityRef);\n if (!oldMetadata) {\n throw new NotFoundError(`Unable to find metadata for ${roleEntityRef}`);\n }\n\n err = await validateSource('rest', oldMetadata);\n if (err) {\n throw new NotAllowedError(`Unable to edit role: ${err.message}`);\n }\n\n if (\n isEqual(oldRole, newRole) &&\n deepSortedEqual(oldMetadata, newMetadata, [\n 'author',\n 'modifiedBy',\n 'createdAt',\n 'lastModified',\n ])\n ) {\n // no content: old role and new role are equal and their metadata too\n response.status(204).end();\n return;\n }\n\n for (const role of newRole) {\n const hasRole = oldRole.some(element => {\n return isEqual(element, role);\n });\n // if the role is already part of old role and is a grouping policy we want to skip returning a conflict error\n // to allow for other roles to be checked and added\n if (await this.enforcer.hasGroupingPolicy(...role)) {\n if (!hasRole) {\n throw new ConflictError(); // 409\n }\n }\n const roleString = JSON.stringify(role);\n\n if (uniqueItems.has(roleString)) {\n throw new ConflictError(\n `Duplicate role members found; ${role.at(0)}, ${role.at(\n 1,\n )} is a duplicate`,\n );\n } else {\n uniqueItems.add(roleString);\n }\n }\n\n uniqueItems.clear();\n for (const role of oldRole) {\n if (!(await this.enforcer.hasGroupingPolicy(...role))) {\n throw new NotFoundError(\n `Member reference: ${role[0]} was not found for role ${roleEntityRef}`,\n ); // 404\n }\n const roleString = JSON.stringify(role);\n\n if (uniqueItems.has(roleString)) {\n throw new ConflictError(\n `Duplicate role members found; ${role.at(0)}, ${role.at(\n 1,\n )} is a duplicate`,\n );\n } else {\n uniqueItems.add(roleString);\n }\n }\n\n await this.enforcer.updateGroupingPolicies(oldRole, newRole, newMetadata);\n\n let message = `Updated ${oldMetadata.roleEntityRef}.`;\n if (newMetadata.roleEntityRef !== oldMetadata.roleEntityRef) {\n message = `${message}. Role entity reference renamed to ${newMetadata.roleEntityRef}`;\n }\n await this.aLog.auditLog<RoleAuditInfo>({\n message,\n eventName: RoleEvents.UPDATE_ROLE,\n metadata: {\n ...newMetadata,\n members: newRole.map(gp => gp[0]),\n },\n stage: SEND_RESPONSE_STAGE,\n status: 'succeeded',\n request,\n response: { status: 200 },\n });\n\n response.status(200).end();\n });\n\n router.delete(\n '/roles/:kind/:namespace/:name',\n async (request, response) => {\n const decision = await this.authorize(\n request,\n policyEntityDeletePermission,\n );\n\n if (decision.result === AuthorizeResult.DENY) {\n throw new NotAllowedError(); // 403\n }\n\n const roleEntityRef = this.getEntityReference(request, true);\n\n let roleMembers = [];\n if (request.query.memberReferences) {\n const memberReference = this.getFirstQuery(\n request.query.memberReferences!,\n ).toLocaleLowerCase('en-US');\n const gp = await this.enforcer.getFilteredGroupingPolicy(\n 0,\n memberReference,\n roleEntityRef,\n );\n if (gp.length > 0) {\n roleMembers.push(gp[0]);\n } else {\n throw new NotFoundError(\n `role member '${memberReference}' was not found`,\n ); // 404\n }\n } else {\n roleMembers = await this.enforcer.getFilteredGroupingPolicy(\n 1,\n roleEntityRef,\n );\n }\n\n for (const role of roleMembers) {\n if (!(await this.enforcer.hasGroupingPolicy(...role))) {\n throw new NotFoundError(`role member '${role[0]}' was not found`);\n }\n }\n\n const currentMetadata =\n await this.roleMetadata.findRoleMetadata(roleEntityRef);\n const err = await validateSource('rest', currentMetadata);\n if (err) {\n throw new NotAllowedError(`Unable to delete role: ${err.message}`);\n }\n\n const credentials = await httpAuth.credentials(request, {\n allow: ['user'],\n });\n\n const metadata: RoleMetadataDao = {\n roleEntityRef,\n source: 'rest',\n modifiedBy: credentials.principal.userEntityRef,\n };\n\n await this.enforcer.removeGroupingPolicies(\n roleMembers,\n metadata,\n false,\n );\n\n await this.aLog.auditLog<RoleAuditInfo>({\n message: `Deleted ${metadata.roleEntityRef}`,\n eventName: RoleEvents.DELETE_ROLE,\n metadata: {\n ...metadata,\n members: roleMembers.map(gp => gp[0]),\n },\n stage: SEND_RESPONSE_STAGE,\n status: 'succeeded',\n request,\n response: { status: 204 },\n });\n\n response.status(204).end();\n },\n );\n\n router.get('/plugins/policies', async (request, response) => {\n const decision = await this.authorize(\n request,\n policyEntityReadPermission,\n );\n\n if (decision.result === AuthorizeResult.DENY) {\n throw new NotAllowedError(); // 403\n }\n\n const body = await this.pluginPermMetaData.getPluginPolicies(\n this.options.auth,\n );\n\n await this.aLog.auditLog({\n message: `Return list plugin policies`,\n eventName: ListPluginPoliciesEvents.GET_PLUGINS_POLICIES,\n stage: SEND_RESPONSE_STAGE,\n status: 'succeeded',\n request,\n response: { status: 200, body },\n });\n\n response.json(body);\n });\n\n router.get('/plugins/condition-rules', async (request, response) => {\n const decision = await this.authorize(\n request,\n policyEntityReadPermission,\n );\n\n if (decision.result === AuthorizeResult.DENY) {\n throw new NotAllowedError(); // 403\n }\n\n const body = await this.pluginPermMetaData.getPluginConditionRules(\n this.options.auth,\n );\n\n await this.aLog.auditLog({\n message: `Return list conditional rules and schemas`,\n eventName: ListConditionEvents.GET_CONDITION_RULES,\n stage: SEND_RESPONSE_STAGE,\n status: 'succeeded',\n request,\n response: { status: 200, body },\n });\n\n response.json(body);\n });\n\n router.get('/roles/conditions', async (request, response) => {\n const decision = await this.authorize(\n request,\n policyEntityReadPermission,\n );\n\n if (decision.result === AuthorizeResult.DENY) {\n throw new NotAllowedError(); // 403\n }\n\n const conditions = await this.conditionalStorage.filterConditions(\n this.getFirstQuery(request.query.roleEntityRef),\n this.getFirstQuery(request.query.pluginId),\n this.getFirstQuery(request.query.resourceType),\n this.getActionQueries(request.query.actions),\n );\n\n const body: RoleConditionalPolicyDecision<PermissionAction>[] =\n conditions.map(condition => {\n return {\n ...condition,\n permissionMapping: condition.permissionMapping.map(pm => pm.action),\n };\n });\n\n await this.aLog.auditLog({\n message: `Return list conditional permission policies`,\n eventName: ConditionEvents.GET_CONDITION,\n stage: SEND_RESPONSE_STAGE,\n status: 'succeeded',\n request,\n response: { status: 200, body },\n });\n\n response.json(body);\n });\n\n router.post('/roles/conditions', async (request, response) => {\n const decision = await this.authorize(\n request,\n policyEntityCreatePermission,\n );\n\n if (decision.result === AuthorizeResult.DENY) {\n throw new NotAllowedError(); // 403\n }\n\n const roleConditionPolicy: RoleConditionalPolicyDecision<PermissionAction> =\n request.body;\n validateRoleCondition(roleConditionPolicy);\n\n const conditionToCreate = await processConditionMapping(\n roleConditionPolicy,\n this.pluginPermMetaData,\n this.options.auth,\n );\n\n const id =\n await this.conditionalStorage.createCondition(conditionToCreate);\n\n const body = { id: id };\n\n await this.aLog.auditLog<ConditionAuditInfo>({\n message: `Created conditional permission policy`,\n eventName: ConditionEvents.CREATE_CONDITION,\n metadata: { condition: roleConditionPolicy },\n stage: SEND_RESPONSE_STAGE,\n status: 'succeeded',\n request,\n response: { status: 201, body },\n });\n\n response.status(201).json(body);\n });\n\n router.get('/roles/conditions/:id', async (request, response) => {\n const decision = await this.authorize(\n request,\n policyEntityReadPermission,\n );\n\n if (decision.result === AuthorizeResult.DENY) {\n throw new NotAllowedError(); // 403\n }\n\n const id: number = parseInt(request.params.id, 10);\n if (isNaN(id)) {\n throw new InputError('Id is not a valid number.');\n }\n\n const condition = await this.conditionalStorage.getCondition(id);\n if (!condition) {\n throw new NotFoundError();\n }\n\n const body: RoleConditionalPolicyDecision<PermissionAction> = {\n ...condition,\n permissionMapping: condition.permissionMapping.map(pm => pm.action),\n };\n\n await this.aLog.auditLog({\n message: `Return conditional permission policy by id`,\n eventName: ConditionEvents.GET_CONDITION,\n stage: SEND_RESPONSE_STAGE,\n status: 'succeeded',\n request,\n response: { status: 200, body },\n });\n\n response.json(body);\n });\n\n router.delete('/roles/conditions/:id', async (request, response) => {\n const decision = await this.authorize(\n request,\n policyEntityDeletePermission,\n );\n\n if (decision.result === AuthorizeResult.DENY) {\n throw new NotAllowedError(); // 403\n }\n\n const id: number = parseInt(request.params.id, 10);\n if (isNaN(id)) {\n throw new InputError('Id is not a valid number.');\n }\n\n const condition = await this.conditionalStorage.getCondition(id);\n if (!condition) {\n throw new NotFoundError(`Condition with id ${id} was not found`);\n }\n const conditionToDelete: RoleConditionalPolicyDecision<PermissionAction> =\n {\n ...condition,\n permissionMapping: condition.permissionMapping.map(pm => pm.action),\n };\n\n await this.conditionalStorage.deleteCondition(id);\n\n await this.aLog.auditLog<ConditionAuditInfo>({\n message: `Deleted conditional permission policy`,\n eventName: ConditionEvents.DELETE_CONDITION,\n metadata: { condition: conditionToDelete },\n stage: SEND_RESPONSE_STAGE,\n status: 'succeeded',\n request,\n response: { status: 204 },\n });\n\n response.status(204).end();\n });\n\n router.put('/roles/conditions/:id', async (request, response) => {\n const decision = await this.authorize(\n request,\n policyEntityUpdatePermission,\n );\n\n if (decision.result === AuthorizeResult.DENY) {\n throw new NotAllowedError(); // 403\n }\n\n const id: number = parseInt(request.params.id, 10);\n if (isNaN(id)) {\n throw new InputError('Id is not a valid number.');\n }\n\n const roleConditionPolicy: RoleConditionalPolicyDecision<PermissionAction> =\n request.body;\n\n validateRoleCondition(roleConditionPolicy);\n\n const conditionToUpdate = await processConditionMapping(\n roleConditionPolicy,\n this.pluginPermMetaData,\n this.options.auth,\n );\n\n await this.conditionalStorage.updateCondition(id, conditionToUpdate);\n\n await this.aLog.auditLog<ConditionAuditInfo>({\n message: `Updated conditional permission policy`,\n eventName: ConditionEvents.UPDATE_CONDITION,\n metadata: { condition: roleConditionPolicy },\n stage: SEND_RESPONSE_STAGE,\n status: 'succeeded',\n request,\n response: { status: 200 },\n });\n\n response.status(200).end();\n });\n\n router.post('/refresh/:id', async (request, response) => {\n const decision = await this.authorize(\n request,\n policyEntityCreatePermission,\n );\n\n if (decision.result === AuthorizeResult.DENY) {\n throw new NotAllowedError(); // 403\n }\n\n if (!this.rbacProviders) {\n throw new NotFoundError(`No RBAC providers were found`);\n }\n\n const idProvider = this.rbacProviders.find(provider => {\n const id = provider.getProviderName();\n return id === request.params.id;\n });\n\n if (!idProvider) {\n throw new NotFoundError(\n `The RBAC provider ${request.params.id} was not found`,\n );\n }\n\n await idProvider.refresh();\n response.status(200).end();\n });\n\n router.use(logAuditError(this.aLog));\n\n return router;\n }\n\n getEntityReference(request: Request, role?: boolean): string {\n const kind = request.params.kind;\n const namespace = request.params.namespace;\n const name = request.params.name;\n const entityRef = `${kind}:${namespace}/${name}`;\n\n const err = validateEntityReference(entityRef, role);\n if (err) {\n throw new InputError(err.message);\n }\n\n return entityRef;\n }\n\n async transformPolicyArray(\n ...policies: string[][]\n ): Promise<RoleBasedPolicy[]> {\n const roleToSourceMap = await buildRoleSourceMap(\n policies,\n this.roleMetadata,\n );\n\n const roleBasedPolices: RoleBasedPolicy[] = [];\n for (const p of policies) {\n const [entityReference, permission, policy, effect] = p;\n roleBasedPolices.push({\n entityReference,\n permission,\n policy,\n effect,\n metadata: { source: roleToSourceMap.get(entityReference)! },\n });\n }\n\n return roleBasedPolices;\n }\n\n async transformRoleArray(...roles: string[][]): Promise<Role[]> {\n const combinedRoles: { [key: string]: string[] } = {};\n\n roles.forEach(([value, role]) => {\n if (combinedRoles.hasOwnProperty(role)) {\n combinedRoles[role].push(value);\n } else {\n combinedRoles[role] = [value];\n }\n });\n\n const result: Role[] = await Promise.all(\n Object.entries(combinedRoles).map(async ([role, value]) => {\n const metadataDao = await this.roleMetadata.findRoleMetadata(role);\n const metadata = metadataDao ? daoToMetadata(metadataDao) : undefined;\n return Promise.resolve({\n memberReferences: value,\n name: role,\n metadata,\n });\n }),\n );\n return result;\n }\n\n transformPolicyToArray(policy: RoleBasedPolicy): string[] {\n return [\n policy.entityReference!,\n policy.permission!,\n policy.policy!,\n policy.effect!,\n ];\n }\n\n transformRoleToArray(role: Role): string[][] {\n const roles: string[][] = [];\n for (const entity of role.memberReferences) {\n roles.push([entity, role.name]);\n }\n return roles;\n }\n\n transformMemberReferencesToLowercase(role: Role) {\n role.memberReferences = role.memberReferences.map(member =>\n member.toLocaleLowerCase('en-US'),\n );\n }\n\n getActionQueries(\n queryValue: string | string[] | ParsedQs | ParsedQs[] | undefined,\n ): PermissionAction[] | undefined {\n if (!queryValue) {\n return undefined;\n }\n if (Array.isArray(queryValue)) {\n const permissionNames: PermissionAction[] = [];\n for (const permissionQuery of queryValue) {\n if (\n typeof permissionQuery === 'string' &&\n isPermissionAction(permissionQuery)\n ) {\n permissionNames.push(permissionQuery);\n } else {\n throw new InputError(\n `Invalid permission action query value: ${permissionQuery}. Permission name should be string.`,\n );\n }\n }\n return permissionNames;\n }\n\n if (typeof queryValue === 'string' && isPermissionAction(queryValue)) {\n return [queryValue];\n }\n throw new InputError(\n `Invalid permission action query value: ${queryValue}. Permission name should be string.`,\n );\n }\n\n getFirstQuery(\n queryValue: string | string[] | ParsedQs | ParsedQs[] | undefined,\n ): string {\n if (!queryValue) {\n return '';\n }\n if (Array.isArray(queryValue)) {\n if (typeof queryValue[0] === 'string') {\n return queryValue[0].toString();\n }\n throw new InputError(`This api doesn't support nested query`);\n }\n\n if (typeof queryValue === 'string') {\n return queryValue;\n }\n throw new InputError(`This api doesn't support nested query`);\n }\n\n isPolicyFilterEnabled(request: Request): boolean {\n return (\n !!request.query.entityRef ||\n !!request.query.permission ||\n !!request.query.policy ||\n !!request.query.effect\n );\n }\n\n async processPolicies(\n policyArray: RoleBasedPolicy[],\n isOld?: boolean,\n errorMessage?: string,\n ): Promise<string[][]> {\n const policies: string[][] = [];\n const uniqueItems = new Set<string>();\n for (const policy of policyArray) {\n let err = validatePolicy(policy);\n if (err) {\n throw new InputError(\n `Invalid ${errorMessage ?? 'policy'} definition. Cause: ${\n err.message\n }`,\n ); // 400\n }\n\n const metadata = await this.roleMetadata.findRoleMetadata(\n policy.entityReference!,\n );\n\n let action = errorMessage ? 'edit' : 'delete';\n action = isOld ? action : 'add';\n\n err = await validateSource('rest', metadata);\n if (err) {\n throw new NotAllowedError(\n `Unable to ${action} policy ${policy.entityReference},${policy.permission},${policy.policy},${policy.effect}: ${err.message}`,\n );\n }\n\n const transformedPolicy = this.transformPolicyToArray(policy);\n if (isOld && !(await this.enforcer.hasPolicy(...transformedPolicy))) {\n throw new NotFoundError(\n `Policy '${policyToString(transformedPolicy)}' not found`,\n ); // 404\n }\n\n if (!isOld && (await this.enforcer.hasPolicy(...transformedPolicy))) {\n throw new ConflictError(\n `Policy '${policyToString(\n transformedPolicy,\n )}' has been already stored`,\n ); // 409\n }\n\n // We want to ensure that there are not duplicate permission policies\n const rowString = JSON.stringify(transformedPolicy);\n if (uniqueItems.has(rowString)) {\n throw new ConflictError(\n `Duplicate polices found; ${policy.entityReference}, ${policy.permission}, ${policy.policy}, ${policy.effect} is a duplicate`,\n );\n } else {\n uniqueItems.add(rowString);\n policies.push(transformedPolicy);\n }\n }\n return policies;\n }\n\n nameSort(nameA: string, nameB: string): number {\n if (nameA.toLocaleUpperCase('en-US') < nameB.toLocaleUpperCase('en-US')) {\n return -1;\n }\n if (nameA.toLocaleUpperCase('en-US') > nameB.toLocaleUpperCase('en-US')) {\n return 1;\n }\n return 0;\n }\n}\n"],"names":["policyEntityReadPermission","NotAllowedError","createRouter","ServiceUnavailableError","createPermissionIntegrationRouter","RESOURCE_TYPE_POLICY_ENTITY","policyEntityPermissions","AuthorizeResult","PermissionEvents","SEND_RESPONSE_STAGE","NotFoundError","policyEntityDeletePermission","isEmpty","InputError","policyEntityCreatePermission","policyEntityUpdatePermission","isEqual","RoleEvents","validateRole","validateSource","ConflictError","deepSortedEqual","ListPluginPoliciesEvents","ListConditionEvents","ConditionEvents","validateRoleCondition","processConditionMapping","logAuditError","validateEntityReference","buildRoleSourceMap","daoToMetadata","isPermissionAction","validatePolicy","policyToString"],"mappings":"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"}