@backstage-community/plugin-rbac-backend 5.2.4 → 5.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/admin-permissions/admin-creation.cjs.js.map +1 -1
  3. package/dist/audit-log/audit-logger.cjs.js.map +1 -1
  4. package/dist/audit-log/rest-errors-interceptor.cjs.js.map +1 -1
  5. package/dist/conditional-aliases/alias-resolver.cjs.js.map +1 -1
  6. package/dist/database/casbin-adapter-factory.cjs.js.map +1 -1
  7. package/dist/database/conditional-storage.cjs.js.map +1 -1
  8. package/dist/database/migration.cjs.js.map +1 -1
  9. package/dist/database/role-metadata.cjs.js.map +1 -1
  10. package/dist/file-permissions/csv-file-watcher.cjs.js.map +1 -1
  11. package/dist/file-permissions/file-watcher.cjs.js.map +1 -1
  12. package/dist/file-permissions/yaml-conditional-file-watcher.cjs.js.map +1 -1
  13. package/dist/helper.cjs.js.map +1 -1
  14. package/dist/plugin.cjs.js.map +1 -1
  15. package/dist/policies/allow-all-policy.cjs.js.map +1 -1
  16. package/dist/policies/permission-policy.cjs.js.map +1 -1
  17. package/dist/providers/connect-providers.cjs.js.map +1 -1
  18. package/dist/role-manager/ancestor-search-memo.cjs.js.map +1 -1
  19. package/dist/role-manager/member-list.cjs.js.map +1 -1
  20. package/dist/role-manager/role-manager.cjs.js.map +1 -1
  21. package/dist/service/enforcer-delegate.cjs.js.map +1 -1
  22. package/dist/service/permission-model.cjs.js.map +1 -1
  23. package/dist/service/plugin-endpoints.cjs.js.map +1 -1
  24. package/dist/service/policies-rest-api.cjs.js.map +1 -1
  25. package/dist/service/policy-builder.cjs.js.map +1 -1
  26. package/dist/service/router.cjs.js.map +1 -1
  27. package/dist/validation/condition-validation.cjs.js.map +1 -1
  28. package/dist/validation/policies-validation.cjs.js.map +1 -1
  29. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"condition-validation.cjs.js","sources":["../../src/validation/condition-validation.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 PermissionCondition,\n PermissionCriteria,\n PermissionRuleParams,\n} from '@backstage/plugin-permission-common';\n\nimport type {\n PermissionAction,\n RoleConditionalPolicyDecision,\n} from '@backstage-community/plugin-rbac-common';\n\nimport { isPermissionAction } from '../helper';\n\nexport function validateRoleCondition(\n condition: RoleConditionalPolicyDecision<PermissionAction>,\n) {\n if (!condition.roleEntityRef) {\n throw new Error(`'roleEntityRef' must be specified in the role condition`);\n }\n if (!condition.result) {\n throw new Error(`'result' must be specified in the role condition`);\n }\n if (!condition.pluginId) {\n throw new Error(`'pluginId' must be specified in the role condition`);\n }\n if (!condition.resourceType) {\n throw new Error(`'resourceType' must be specified in the role condition`);\n }\n\n if (\n !condition.permissionMapping ||\n condition.permissionMapping.length === 0\n ) {\n throw new Error(\n `'permissionMapping' must be non empty array in the role condition`,\n );\n }\n const nonActionValue = condition.permissionMapping.find(\n action => !isPermissionAction(action),\n );\n if (nonActionValue) {\n throw new Error(\n `'permissionMapping' array contains non action value: '${nonActionValue}'`,\n );\n }\n\n if (!condition.conditions) {\n throw new Error(`'conditions' must be specified in the role condition`);\n }\n if (condition.conditions) {\n validatePermissionCondition(\n condition.conditions,\n 'roleCondition.conditions',\n );\n }\n}\n\n/**\n * validatePermissionCondition validate conditional permission policies using validateCriteria and validateRule.\n * @param conditionOrCriteria The Permission Criteria of the conditional permission.\n * @param jsonPathLocator The location in the JSON of the current check.\n * @returns undefined.\n */\nfunction validatePermissionCondition(\n conditionOrCriteria: PermissionCriteria<\n PermissionCondition<string, PermissionRuleParams>\n >,\n jsonPathLocator: string,\n) {\n validateCriteria(conditionOrCriteria, jsonPathLocator);\n\n if ('not' in conditionOrCriteria) {\n validatePermissionCondition(\n conditionOrCriteria.not,\n `${jsonPathLocator}.not`,\n );\n return;\n }\n\n if ('allOf' in conditionOrCriteria) {\n if (\n !Array.isArray(conditionOrCriteria.allOf) ||\n conditionOrCriteria.allOf.length === 0\n ) {\n throw new Error(\n `${jsonPathLocator}.allOf criteria must be non empty array`,\n );\n }\n for (const [index, elem] of conditionOrCriteria.allOf.entries()) {\n validatePermissionCondition(elem, `${jsonPathLocator}.allOf[${index}]`);\n }\n return;\n }\n\n if ('anyOf' in conditionOrCriteria) {\n if (\n !Array.isArray(conditionOrCriteria.anyOf) ||\n conditionOrCriteria.anyOf.length === 0\n ) {\n throw new Error(\n `${jsonPathLocator}.anyOf criteria must be non empty array`,\n );\n }\n for (const [index, elem] of conditionOrCriteria.anyOf.entries()) {\n validatePermissionCondition(elem, `${jsonPathLocator}.anyOf[${index}]`);\n }\n }\n}\n\n/**\n * validateRule ensures that there is a rule and resource type associated with each conditional permission.\n * @param conditionOrCriteria The Permission Criteria of the conditional permission.\n * @param jsonPathLocator The location in the JSON of the current check.\n */\nfunction validateRule(\n conditionOrCriteria: PermissionCriteria<\n PermissionCondition<string, PermissionRuleParams>\n >,\n jsonPathLocator: string,\n) {\n if (!('resourceType' in conditionOrCriteria)) {\n throw new Error(\n `'resourceType' must be specified in the ${jsonPathLocator}.condition`,\n );\n }\n if (!('rule' in conditionOrCriteria)) {\n throw new Error(\n `'rule' must be specified in the ${jsonPathLocator}.condition`,\n );\n }\n}\n\n/**\n * validateCriteria ensures that there is only one of the following criteria: allOf, anyOf, and not, at any given level.\n * We want to make sure that there are no parallel conditional criteria for conditional permission policies as this is\n * not support by the permission framework.\n *\n * If more than one criteria are at a given level, we throw an error about the inability to support parallel conditions.\n * If no criteria are found, we validate the rule.\n *\n * @param conditionOrCriteria The Permission Criteria of the conditional permission.\n * @param jsonPathLocator The location in the JSON of the current check.\n */\nfunction validateCriteria(\n conditionOrCriteria: PermissionCriteria<\n PermissionCondition<string, PermissionRuleParams>\n >,\n jsonPathLocator: string,\n) {\n const criteriaList = ['allOf', 'anyOf', 'not'];\n const found: string[] = [];\n\n for (const crit of criteriaList) {\n if (crit in conditionOrCriteria) {\n found.push(crit);\n }\n }\n\n if (found.length > 1) {\n throw new Error(\n `RBAC plugin does not support parallel conditions, consider reworking request to include nested condition criteria. Conditional criteria causing the error ${found}.`,\n );\n } else if (found.length === 0) {\n validateRule(conditionOrCriteria, jsonPathLocator);\n }\n\n if (found.length === 1 && 'rule' in conditionOrCriteria) {\n throw new Error(\n `RBAC plugin does not support parallel conditions alongside rules, consider reworking request to include nested condition criteria. Conditional criteria causing the error ${found}, 'rule: ${conditionOrCriteria.rule}'.`,\n );\n }\n}\n"],"names":["isPermissionAction"],"mappings":"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"}
1
+ {"version":3,"file":"condition-validation.cjs.js","sources":["../../src/validation/condition-validation.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 PermissionCondition,\n PermissionCriteria,\n PermissionRuleParams,\n} from '@backstage/plugin-permission-common';\n\nimport type {\n PermissionAction,\n RoleConditionalPolicyDecision,\n} from '@backstage-community/plugin-rbac-common';\n\nimport { isPermissionAction } from '../helper';\n\nexport function validateRoleCondition(\n condition: RoleConditionalPolicyDecision<PermissionAction>,\n) {\n if (!condition.roleEntityRef) {\n throw new Error(`'roleEntityRef' must be specified in the role condition`);\n }\n if (!condition.result) {\n throw new Error(`'result' must be specified in the role condition`);\n }\n if (!condition.pluginId) {\n throw new Error(`'pluginId' must be specified in the role condition`);\n }\n if (!condition.resourceType) {\n throw new Error(`'resourceType' must be specified in the role condition`);\n }\n\n if (\n !condition.permissionMapping ||\n condition.permissionMapping.length === 0\n ) {\n throw new Error(\n `'permissionMapping' must be non empty array in the role condition`,\n );\n }\n const nonActionValue = condition.permissionMapping.find(\n action => !isPermissionAction(action),\n );\n if (nonActionValue) {\n throw new Error(\n `'permissionMapping' array contains non action value: '${nonActionValue}'`,\n );\n }\n\n if (!condition.conditions) {\n throw new Error(`'conditions' must be specified in the role condition`);\n }\n if (condition.conditions) {\n validatePermissionCondition(\n condition.conditions,\n 'roleCondition.conditions',\n );\n }\n}\n\n/**\n * validatePermissionCondition validate conditional permission policies using validateCriteria and validateRule.\n * @param conditionOrCriteria The Permission Criteria of the conditional permission.\n * @param jsonPathLocator The location in the JSON of the current check.\n * @returns undefined.\n */\nfunction validatePermissionCondition(\n conditionOrCriteria: PermissionCriteria<\n PermissionCondition<string, PermissionRuleParams>\n >,\n jsonPathLocator: string,\n) {\n validateCriteria(conditionOrCriteria, jsonPathLocator);\n\n if ('not' in conditionOrCriteria) {\n validatePermissionCondition(\n conditionOrCriteria.not,\n `${jsonPathLocator}.not`,\n );\n return;\n }\n\n if ('allOf' in conditionOrCriteria) {\n if (\n !Array.isArray(conditionOrCriteria.allOf) ||\n conditionOrCriteria.allOf.length === 0\n ) {\n throw new Error(\n `${jsonPathLocator}.allOf criteria must be non empty array`,\n );\n }\n for (const [index, elem] of conditionOrCriteria.allOf.entries()) {\n validatePermissionCondition(elem, `${jsonPathLocator}.allOf[${index}]`);\n }\n return;\n }\n\n if ('anyOf' in conditionOrCriteria) {\n if (\n !Array.isArray(conditionOrCriteria.anyOf) ||\n conditionOrCriteria.anyOf.length === 0\n ) {\n throw new Error(\n `${jsonPathLocator}.anyOf criteria must be non empty array`,\n );\n }\n for (const [index, elem] of conditionOrCriteria.anyOf.entries()) {\n validatePermissionCondition(elem, `${jsonPathLocator}.anyOf[${index}]`);\n }\n }\n}\n\n/**\n * validateRule ensures that there is a rule and resource type associated with each conditional permission.\n * @param conditionOrCriteria The Permission Criteria of the conditional permission.\n * @param jsonPathLocator The location in the JSON of the current check.\n */\nfunction validateRule(\n conditionOrCriteria: PermissionCriteria<\n PermissionCondition<string, PermissionRuleParams>\n >,\n jsonPathLocator: string,\n) {\n if (!('resourceType' in conditionOrCriteria)) {\n throw new Error(\n `'resourceType' must be specified in the ${jsonPathLocator}.condition`,\n );\n }\n if (!('rule' in conditionOrCriteria)) {\n throw new Error(\n `'rule' must be specified in the ${jsonPathLocator}.condition`,\n );\n }\n}\n\n/**\n * validateCriteria ensures that there is only one of the following criteria: allOf, anyOf, and not, at any given level.\n * We want to make sure that there are no parallel conditional criteria for conditional permission policies as this is\n * not support by the permission framework.\n *\n * If more than one criteria are at a given level, we throw an error about the inability to support parallel conditions.\n * If no criteria are found, we validate the rule.\n *\n * @param conditionOrCriteria The Permission Criteria of the conditional permission.\n * @param jsonPathLocator The location in the JSON of the current check.\n */\nfunction validateCriteria(\n conditionOrCriteria: PermissionCriteria<\n PermissionCondition<string, PermissionRuleParams>\n >,\n jsonPathLocator: string,\n) {\n const criteriaList = ['allOf', 'anyOf', 'not'];\n const found: string[] = [];\n\n for (const crit of criteriaList) {\n if (crit in conditionOrCriteria) {\n found.push(crit);\n }\n }\n\n if (found.length > 1) {\n throw new Error(\n `RBAC plugin does not support parallel conditions, consider reworking request to include nested condition criteria. Conditional criteria causing the error ${found}.`,\n );\n } else if (found.length === 0) {\n validateRule(conditionOrCriteria, jsonPathLocator);\n }\n\n if (found.length === 1 && 'rule' in conditionOrCriteria) {\n throw new Error(\n `RBAC plugin does not support parallel conditions alongside rules, consider reworking request to include nested condition criteria. Conditional criteria causing the error ${found}, 'rule: ${conditionOrCriteria.rule}'.`,\n );\n }\n}\n"],"names":["isPermissionAction"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"policies-validation.cjs.js","sources":["../../src/validation/policies-validation.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 { CompoundEntityRef, parseEntityRef } from '@backstage/catalog-model';\nimport { NotAllowedError } from '@backstage/errors';\nimport { AuthorizeResult } from '@backstage/plugin-permission-common';\n\nimport { Enforcer } from 'casbin';\n\nimport {\n isValidPermissionAction,\n PermissionActionValues,\n Role,\n RoleBasedPolicy,\n Source,\n} from '@backstage-community/plugin-rbac-common';\n\nimport {\n RoleMetadataDao,\n RoleMetadataStorage,\n} from '../database/role-metadata';\n\n/**\n * validateSource validates the source to the role that is being modified. This includes comparing the source from the\n * originating role to the source that the modification is coming from.\n * We do this to ensure consistency between permissions and roles and where they are originally defined.\n * This is a strict comparison where the source of all new roles (grouping policies) and permissions must match\n * the source of the first role that was created.\n * We are not strict for permission policies defined with an originating role source of configuration.\n * @param source The source in which the modification is coming from\n * @param roleMetadata The original role that was created\n * @returns An error in the event that the source does not match the originating role\n */\nexport const validateSource = async (\n source: Source,\n roleMetadata: RoleMetadataDao | undefined,\n): Promise<Error | undefined> => {\n if (!roleMetadata) {\n return undefined; // Role does not exist yet, there is no conflict with the source\n }\n\n if (roleMetadata.source !== source && roleMetadata.source !== 'legacy') {\n return new Error(\n `source does not match originating role ${\n roleMetadata.roleEntityRef\n }, consider making changes to the '${roleMetadata.source.toLocaleUpperCase()}'`,\n );\n }\n\n return undefined;\n};\n\n// This should be called on add and edit and delete\nexport function validatePolicy(policy: RoleBasedPolicy): Error | undefined {\n const err = validateEntityReference(policy.entityReference);\n if (err) {\n return err;\n }\n\n if (!policy.permission) {\n return new Error(`'permission' field must not be empty`);\n }\n\n if (!policy.policy) {\n return new Error(`'policy' field must not be empty`);\n } else if (!isValidPermissionAction(policy.policy)) {\n return new Error(\n `'policy' has invalid value: '${\n policy.policy\n }'. It should be one of: ${PermissionActionValues.join(', ')}`,\n );\n }\n\n if (!policy.effect) {\n return new Error(`'effect' field must not be empty`);\n } else if (!isValidEffectValue(policy.effect)) {\n return new Error(\n `'effect' has invalid value: '${\n policy.effect\n }'. It should be: '${AuthorizeResult.ALLOW.toLocaleLowerCase()}' or '${AuthorizeResult.DENY.toLocaleLowerCase()}'`,\n );\n }\n\n return undefined;\n}\n\nexport function validateRole(role: Role): Error | undefined {\n if (!role.name) {\n return new Error(`'name' field must not be empty`);\n }\n\n let err = validateEntityReference(role.name, true);\n if (err) {\n return err;\n }\n\n if (!role.memberReferences || role.memberReferences.length === 0) {\n return new Error(`'memberReferences' field must not be empty`);\n }\n\n for (const member of role.memberReferences) {\n err = validateEntityReference(member);\n if (err) {\n return err;\n }\n }\n return undefined;\n}\n\nfunction isValidEffectValue(effect: string): boolean {\n return (\n effect === AuthorizeResult.ALLOW.toLocaleLowerCase() ||\n effect === AuthorizeResult.DENY.toLocaleLowerCase()\n );\n}\n\nfunction isValidEntityName(name: string): boolean {\n const validNamePattern = /^[a-zA-Z0-9]+([._-][a-zA-Z0-9]+)*$/;\n return validNamePattern.test(name) && name.length <= 63;\n}\n\nfunction isValidEntityNamespace(namespace: string): boolean {\n const validNamespacePattern = /^[a-z0-9]+(-[a-z0-9]+)*$/;\n return validNamespacePattern.test(namespace) && namespace.length <= 63;\n}\n\n// We supports only full form entity reference: [<kind>:][<namespace>/]<name>\nexport function validateEntityReference(\n entityRef?: string,\n role?: boolean,\n): Error | undefined {\n if (!entityRef) {\n return new Error(`'entityReference' must not be empty`);\n }\n\n let entityRefCompound: CompoundEntityRef;\n try {\n entityRefCompound = parseEntityRef(entityRef);\n } catch (err) {\n return err as Error;\n }\n\n const entityRefFull = `${entityRefCompound.kind}:${entityRefCompound.namespace}/${entityRefCompound.name}`;\n if (entityRefFull !== entityRef) {\n return new Error(\n `entity reference '${entityRef}' does not match the required format [<kind>:][<namespace>/]<name>. Provide, please, full entity reference.`,\n );\n }\n\n if (role && entityRefCompound.kind !== 'role') {\n return new Error(\n `Unsupported kind ${entityRefCompound.kind}. Supported value should be \"role\"`,\n );\n }\n\n if (\n entityRefCompound.kind !== 'user' &&\n entityRefCompound.kind !== 'group' &&\n entityRefCompound.kind !== 'role'\n ) {\n return new Error(\n `Unsupported kind ${entityRefCompound.kind}. List supported values [\"user\", \"group\", \"role\"]`,\n );\n }\n\n if (!isValidEntityName(entityRefCompound.name)) {\n return new Error(\n `The name '${entityRefCompound.name}' in the entity reference must be a string that is sequences of [a-zA-Z0-9] separated by any of [-_.], at most 63 characters in total`,\n );\n }\n\n if (!isValidEntityNamespace(entityRefCompound.namespace)) {\n return new Error(\n `The namespace '${entityRefCompound.namespace}' in the entity reference must be a string that is sequences of [a-z0-9] separated by [-], at most 63 characters in total`,\n );\n }\n\n return undefined;\n}\n\nexport async function validateGroupingPolicy(\n groupPolicy: string[],\n roleMetadataStorage: RoleMetadataStorage,\n source: Source,\n): Promise<Error | undefined> {\n if (groupPolicy.length !== 2) {\n return new Error(`Group policy should have length 2`);\n }\n\n const member = groupPolicy[0];\n let err = validateEntityReference(member);\n if (err) {\n return new Error(\n `Failed to validate group policy ${groupPolicy}. Cause: ${err.message}`,\n );\n }\n const parent = groupPolicy[1];\n err = validateEntityReference(parent);\n if (err) {\n return new Error(\n `Failed to validate group policy ${groupPolicy}. Cause: ${err.message}`,\n );\n }\n if (member.startsWith(`role:`)) {\n return new Error(\n `Group policy is invalid: ${groupPolicy}. rbac-backend plugin doesn't support role inheritance.`,\n );\n }\n if (member.startsWith(`group:`) && parent.startsWith(`group:`)) {\n return new Error(\n `Group policy is invalid: ${groupPolicy}. Group inheritance information could be provided only with help of Catalog API.`,\n );\n }\n if (member.startsWith(`user:`) && parent.startsWith(`group:`)) {\n return new Error(\n `Group policy is invalid: ${groupPolicy}. User membership information could be provided only with help of Catalog API.`,\n );\n }\n\n const metadata = await roleMetadataStorage.findRoleMetadata(parent);\n\n err = await validateSource(source, metadata);\n if (metadata && err) {\n return new NotAllowedError(\n `Unable to validate role ${groupPolicy}. Cause: ${err.message}`,\n );\n }\n\n return undefined;\n}\n\nexport const checkForDuplicatePolicies = async (\n fileEnf: Enforcer,\n policy: string[],\n policyFile: string,\n): Promise<Error | undefined> => {\n const duplicates = await fileEnf.getFilteredPolicy(0, ...policy);\n if (duplicates.length > 1) {\n return new Error(\n `Duplicate policy: ${policy} found in the file ${policyFile}`,\n );\n }\n\n const flipPolicyEffect = [\n policy[0],\n policy[1],\n policy[2],\n policy[3] === 'deny' ? 'allow' : 'deny',\n ];\n\n // Check if the same policy exists but with a different effect\n const dupWithDifferentEffect = await fileEnf.getFilteredPolicy(\n 0,\n ...flipPolicyEffect,\n );\n\n if (dupWithDifferentEffect.length > 0) {\n return new Error(\n `Duplicate policy: ${policy[0]}, ${policy[1]}, ${policy[2]} with different effect found in the file ${policyFile}`,\n );\n }\n\n return undefined;\n};\n\nexport const checkForDuplicateGroupPolicies = async (\n fileEnf: Enforcer,\n policy: string[],\n policyFile: string,\n): Promise<Error | undefined> => {\n const duplicates = await fileEnf.getFilteredGroupingPolicy(0, ...policy);\n\n if (duplicates.length > 1) {\n return new Error(\n `Duplicate role: ${policy} found in the file ${policyFile}`,\n );\n }\n return undefined;\n};\n"],"names":["isValidPermissionAction","PermissionActionValues","AuthorizeResult","parseEntityRef","NotAllowedError"],"mappings":"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"}
1
+ {"version":3,"file":"policies-validation.cjs.js","sources":["../../src/validation/policies-validation.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 { CompoundEntityRef, parseEntityRef } from '@backstage/catalog-model';\nimport { NotAllowedError } from '@backstage/errors';\nimport { AuthorizeResult } from '@backstage/plugin-permission-common';\n\nimport { Enforcer } from 'casbin';\n\nimport {\n isValidPermissionAction,\n PermissionActionValues,\n Role,\n RoleBasedPolicy,\n Source,\n} from '@backstage-community/plugin-rbac-common';\n\nimport {\n RoleMetadataDao,\n RoleMetadataStorage,\n} from '../database/role-metadata';\n\n/**\n * validateSource validates the source to the role that is being modified. This includes comparing the source from the\n * originating role to the source that the modification is coming from.\n * We do this to ensure consistency between permissions and roles and where they are originally defined.\n * This is a strict comparison where the source of all new roles (grouping policies) and permissions must match\n * the source of the first role that was created.\n * We are not strict for permission policies defined with an originating role source of configuration.\n * @param source The source in which the modification is coming from\n * @param roleMetadata The original role that was created\n * @returns An error in the event that the source does not match the originating role\n */\nexport const validateSource = async (\n source: Source,\n roleMetadata: RoleMetadataDao | undefined,\n): Promise<Error | undefined> => {\n if (!roleMetadata) {\n return undefined; // Role does not exist yet, there is no conflict with the source\n }\n\n if (roleMetadata.source !== source && roleMetadata.source !== 'legacy') {\n return new Error(\n `source does not match originating role ${\n roleMetadata.roleEntityRef\n }, consider making changes to the '${roleMetadata.source.toLocaleUpperCase()}'`,\n );\n }\n\n return undefined;\n};\n\n// This should be called on add and edit and delete\nexport function validatePolicy(policy: RoleBasedPolicy): Error | undefined {\n const err = validateEntityReference(policy.entityReference);\n if (err) {\n return err;\n }\n\n if (!policy.permission) {\n return new Error(`'permission' field must not be empty`);\n }\n\n if (!policy.policy) {\n return new Error(`'policy' field must not be empty`);\n } else if (!isValidPermissionAction(policy.policy)) {\n return new Error(\n `'policy' has invalid value: '${\n policy.policy\n }'. It should be one of: ${PermissionActionValues.join(', ')}`,\n );\n }\n\n if (!policy.effect) {\n return new Error(`'effect' field must not be empty`);\n } else if (!isValidEffectValue(policy.effect)) {\n return new Error(\n `'effect' has invalid value: '${\n policy.effect\n }'. It should be: '${AuthorizeResult.ALLOW.toLocaleLowerCase()}' or '${AuthorizeResult.DENY.toLocaleLowerCase()}'`,\n );\n }\n\n return undefined;\n}\n\nexport function validateRole(role: Role): Error | undefined {\n if (!role.name) {\n return new Error(`'name' field must not be empty`);\n }\n\n let err = validateEntityReference(role.name, true);\n if (err) {\n return err;\n }\n\n if (!role.memberReferences || role.memberReferences.length === 0) {\n return new Error(`'memberReferences' field must not be empty`);\n }\n\n for (const member of role.memberReferences) {\n err = validateEntityReference(member);\n if (err) {\n return err;\n }\n }\n return undefined;\n}\n\nfunction isValidEffectValue(effect: string): boolean {\n return (\n effect === AuthorizeResult.ALLOW.toLocaleLowerCase() ||\n effect === AuthorizeResult.DENY.toLocaleLowerCase()\n );\n}\n\nfunction isValidEntityName(name: string): boolean {\n const validNamePattern = /^[a-zA-Z0-9]+([._-][a-zA-Z0-9]+)*$/;\n return validNamePattern.test(name) && name.length <= 63;\n}\n\nfunction isValidEntityNamespace(namespace: string): boolean {\n const validNamespacePattern = /^[a-z0-9]+(-[a-z0-9]+)*$/;\n return validNamespacePattern.test(namespace) && namespace.length <= 63;\n}\n\n// We supports only full form entity reference: [<kind>:][<namespace>/]<name>\nexport function validateEntityReference(\n entityRef?: string,\n role?: boolean,\n): Error | undefined {\n if (!entityRef) {\n return new Error(`'entityReference' must not be empty`);\n }\n\n let entityRefCompound: CompoundEntityRef;\n try {\n entityRefCompound = parseEntityRef(entityRef);\n } catch (err) {\n return err as Error;\n }\n\n const entityRefFull = `${entityRefCompound.kind}:${entityRefCompound.namespace}/${entityRefCompound.name}`;\n if (entityRefFull !== entityRef) {\n return new Error(\n `entity reference '${entityRef}' does not match the required format [<kind>:][<namespace>/]<name>. Provide, please, full entity reference.`,\n );\n }\n\n if (role && entityRefCompound.kind !== 'role') {\n return new Error(\n `Unsupported kind ${entityRefCompound.kind}. Supported value should be \"role\"`,\n );\n }\n\n if (\n entityRefCompound.kind !== 'user' &&\n entityRefCompound.kind !== 'group' &&\n entityRefCompound.kind !== 'role'\n ) {\n return new Error(\n `Unsupported kind ${entityRefCompound.kind}. List supported values [\"user\", \"group\", \"role\"]`,\n );\n }\n\n if (!isValidEntityName(entityRefCompound.name)) {\n return new Error(\n `The name '${entityRefCompound.name}' in the entity reference must be a string that is sequences of [a-zA-Z0-9] separated by any of [-_.], at most 63 characters in total`,\n );\n }\n\n if (!isValidEntityNamespace(entityRefCompound.namespace)) {\n return new Error(\n `The namespace '${entityRefCompound.namespace}' in the entity reference must be a string that is sequences of [a-z0-9] separated by [-], at most 63 characters in total`,\n );\n }\n\n return undefined;\n}\n\nexport async function validateGroupingPolicy(\n groupPolicy: string[],\n roleMetadataStorage: RoleMetadataStorage,\n source: Source,\n): Promise<Error | undefined> {\n if (groupPolicy.length !== 2) {\n return new Error(`Group policy should have length 2`);\n }\n\n const member = groupPolicy[0];\n let err = validateEntityReference(member);\n if (err) {\n return new Error(\n `Failed to validate group policy ${groupPolicy}. Cause: ${err.message}`,\n );\n }\n const parent = groupPolicy[1];\n err = validateEntityReference(parent);\n if (err) {\n return new Error(\n `Failed to validate group policy ${groupPolicy}. Cause: ${err.message}`,\n );\n }\n if (member.startsWith(`role:`)) {\n return new Error(\n `Group policy is invalid: ${groupPolicy}. rbac-backend plugin doesn't support role inheritance.`,\n );\n }\n if (member.startsWith(`group:`) && parent.startsWith(`group:`)) {\n return new Error(\n `Group policy is invalid: ${groupPolicy}. Group inheritance information could be provided only with help of Catalog API.`,\n );\n }\n if (member.startsWith(`user:`) && parent.startsWith(`group:`)) {\n return new Error(\n `Group policy is invalid: ${groupPolicy}. User membership information could be provided only with help of Catalog API.`,\n );\n }\n\n const metadata = await roleMetadataStorage.findRoleMetadata(parent);\n\n err = await validateSource(source, metadata);\n if (metadata && err) {\n return new NotAllowedError(\n `Unable to validate role ${groupPolicy}. Cause: ${err.message}`,\n );\n }\n\n return undefined;\n}\n\nexport const checkForDuplicatePolicies = async (\n fileEnf: Enforcer,\n policy: string[],\n policyFile: string,\n): Promise<Error | undefined> => {\n const duplicates = await fileEnf.getFilteredPolicy(0, ...policy);\n if (duplicates.length > 1) {\n return new Error(\n `Duplicate policy: ${policy} found in the file ${policyFile}`,\n );\n }\n\n const flipPolicyEffect = [\n policy[0],\n policy[1],\n policy[2],\n policy[3] === 'deny' ? 'allow' : 'deny',\n ];\n\n // Check if the same policy exists but with a different effect\n const dupWithDifferentEffect = await fileEnf.getFilteredPolicy(\n 0,\n ...flipPolicyEffect,\n );\n\n if (dupWithDifferentEffect.length > 0) {\n return new Error(\n `Duplicate policy: ${policy[0]}, ${policy[1]}, ${policy[2]} with different effect found in the file ${policyFile}`,\n );\n }\n\n return undefined;\n};\n\nexport const checkForDuplicateGroupPolicies = async (\n fileEnf: Enforcer,\n policy: string[],\n policyFile: string,\n): Promise<Error | undefined> => {\n const duplicates = await fileEnf.getFilteredGroupingPolicy(0, ...policy);\n\n if (duplicates.length > 1) {\n return new Error(\n `Duplicate role: ${policy} found in the file ${policyFile}`,\n );\n }\n return undefined;\n};\n"],"names":["isValidPermissionAction","PermissionActionValues","AuthorizeResult","parseEntityRef","NotAllowedError"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage-community/plugin-rbac-backend",
3
- "version": "5.2.4",
3
+ "version": "5.2.5",
4
4
  "main": "dist/index.cjs.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "license": "Apache-2.0",
@@ -65,10 +65,10 @@
65
65
  "@spotify/prettier-config": "^15.0.0",
66
66
  "@types/express": "4.17.21",
67
67
  "@types/lodash": "^4.14.151",
68
- "@types/node": "18.19.34",
68
+ "@types/node": "18.19.64",
69
69
  "@types/supertest": "2.0.16",
70
70
  "knex-mock-client": "2.0.1",
71
- "msw": "1.3.3",
71
+ "msw": "1.3.5",
72
72
  "prettier": "3.3.3",
73
73
  "qs": "6.11.2",
74
74
  "supertest": "6.3.4"