diff --git a/backend/src/ee/services/permission/permission-fns.ts b/backend/src/ee/services/permission/permission-fns.ts index 1ccee129fe..80a58db0a5 100644 --- a/backend/src/ee/services/permission/permission-fns.ts +++ b/backend/src/ee/services/permission/permission-fns.ts @@ -29,4 +29,18 @@ function validateOrgSSO(actorAuthMethod: ActorAuthMethod, isOrgSsoEnforced: TOrg } } -export { isAuthMethodSaml, validateOrgSSO }; +const escapeHandlebarsMissingMetadata = (obj: Record) => { + const handler = { + get(target: Record, prop: string) { + if (!(prop in target)) { + // eslint-disable-next-line no-param-reassign + target[prop] = `{{identity.metadata.${prop}}}`; // Add missing key as an "own" property + } + return target[prop]; + } + }; + + return new Proxy(obj, handler); +}; + +export { escapeHandlebarsMissingMetadata, isAuthMethodSaml, validateOrgSSO }; diff --git a/backend/src/ee/services/permission/permission-service.ts b/backend/src/ee/services/permission/permission-service.ts index e762d00ec5..13645b8f17 100644 --- a/backend/src/ee/services/permission/permission-service.ts +++ b/backend/src/ee/services/permission/permission-service.ts @@ -21,7 +21,7 @@ import { TServiceTokenDALFactory } from "@app/services/service-token/service-tok import { orgAdminPermissions, orgMemberPermissions, orgNoAccessPermissions, OrgPermissionSet } from "./org-permission"; import { TPermissionDALFactory } from "./permission-dal"; -import { validateOrgSSO } from "./permission-fns"; +import { escapeHandlebarsMissingMetadata, validateOrgSSO } from "./permission-fns"; import { TBuildOrgPermissionDTO, TBuildProjectPermissionDTO } from "./permission-service-types"; import { buildServiceTokenProjectPermission, @@ -227,11 +227,13 @@ export const permissionServiceFactory = ({ })) || []; const rules = buildProjectPermissionRules(rolePermissions.concat(additionalPrivileges)); - const templatedRules = handlebars.compile(JSON.stringify(rules), { data: false, strict: true }); - const metadataKeyValuePair = objectify( - userProjectPermission.metadata, - (i) => i.key, - (i) => i.value + const templatedRules = handlebars.compile(JSON.stringify(rules), { data: false }); + const metadataKeyValuePair = escapeHandlebarsMissingMetadata( + objectify( + userProjectPermission.metadata, + (i) => i.key, + (i) => i.value + ) ); const interpolateRules = templatedRules( { @@ -292,12 +294,15 @@ export const permissionServiceFactory = ({ })) || []; const rules = buildProjectPermissionRules(rolePermissions.concat(additionalPrivileges)); - const templatedRules = handlebars.compile(JSON.stringify(rules), { data: false, strict: true }); - const metadataKeyValuePair = objectify( - identityProjectPermission.metadata, - (i) => i.key, - (i) => i.value + const templatedRules = handlebars.compile(JSON.stringify(rules), { data: false }); + const metadataKeyValuePair = escapeHandlebarsMissingMetadata( + objectify( + identityProjectPermission.metadata, + (i) => i.key, + (i) => i.value + ) ); + const interpolateRules = templatedRules( { identity: {