diff --git a/backend/src/ee/services/group/group-service.ts b/backend/src/ee/services/group/group-service.ts index d2e836745..68df7ca69 100644 --- a/backend/src/ee/services/group/group-service.ts +++ b/backend/src/ee/services/group/group-service.ts @@ -14,7 +14,7 @@ import { TUserDALFactory } from "@app/services/user/user-dal"; import { TLicenseServiceFactory } from "../license/license-service"; import { OrgPermissionGroupActions, OrgPermissionSubjects } from "../permission/org-permission"; -import { validatePrivilegeChangeOperation } from "../permission/permission-fns"; +import { constructPermissionErrorMessage, validatePrivilegeChangeOperation } from "../permission/permission-fns"; import { TPermissionServiceFactory } from "../permission/permission-service"; import { TGroupDALFactory } from "./group-dal"; import { addUsersToGroupByUserIds, removeUsersFromGroupByUserIds } from "./group-fns"; @@ -95,10 +95,16 @@ export const groupServiceFactory = ({ permission, rolePermission ); + if (!permissionBoundary.isValid) throw new ForbiddenRequestError({ name: "PermissionBoundaryError", - message: "Failed to create a more privileged group", + message: constructPermissionErrorMessage( + "Failed to create a more privileged group", + membership.shouldUseNewPrivilegeSystem, + OrgPermissionGroupActions.ManagePrivileges, + OrgPermissionSubjects.Groups + ), details: { missingPermissions: permissionBoundary.missingPermissions } }); @@ -178,7 +184,12 @@ export const groupServiceFactory = ({ if (!permissionBoundary.isValid) throw new ForbiddenRequestError({ name: "PermissionBoundaryError", - message: "Failed to update a more privileged group", + message: constructPermissionErrorMessage( + "Failed to update a more privileged group", + membership.shouldUseNewPrivilegeSystem, + OrgPermissionGroupActions.ManagePrivileges, + OrgPermissionSubjects.Groups + ), details: { missingPermissions: permissionBoundary.missingPermissions } }); if (isCustomRole) customRole = customOrgRole; @@ -362,7 +373,12 @@ export const groupServiceFactory = ({ if (!permissionBoundary.isValid) throw new ForbiddenRequestError({ name: "PermissionBoundaryError", - message: "Failed to add user to more privileged group", + message: constructPermissionErrorMessage( + "Failed to add user to more privileged group", + membership.shouldUseNewPrivilegeSystem, + OrgPermissionGroupActions.AddMembers, + OrgPermissionSubjects.Groups + ), details: { missingPermissions: permissionBoundary.missingPermissions } }); @@ -439,7 +455,12 @@ export const groupServiceFactory = ({ if (!permissionBoundary.isValid) throw new ForbiddenRequestError({ name: "PermissionBoundaryError", - message: "Failed to delete user from more privileged group", + message: constructPermissionErrorMessage( + "Failed to delete user from more privileged group", + membership.shouldUseNewPrivilegeSystem, + OrgPermissionGroupActions.RemoveMembers, + OrgPermissionSubjects.Groups + ), details: { missingPermissions: permissionBoundary.missingPermissions } }); diff --git a/backend/src/ee/services/identity-project-additional-privilege-v2/identity-project-additional-privilege-v2-service.ts b/backend/src/ee/services/identity-project-additional-privilege-v2/identity-project-additional-privilege-v2-service.ts index 37c258dc4..aaecefb7f 100644 --- a/backend/src/ee/services/identity-project-additional-privilege-v2/identity-project-additional-privilege-v2-service.ts +++ b/backend/src/ee/services/identity-project-additional-privilege-v2/identity-project-additional-privilege-v2-service.ts @@ -9,7 +9,7 @@ import { ActorType } from "@app/services/auth/auth-type"; import { TIdentityProjectDALFactory } from "@app/services/identity-project/identity-project-dal"; import { TProjectDALFactory } from "@app/services/project/project-dal"; -import { validatePrivilegeChangeOperation } from "../permission/permission-fns"; +import { constructPermissionErrorMessage, validatePrivilegeChangeOperation } from "../permission/permission-fns"; import { TPermissionServiceFactory } from "../permission/permission-service"; import { ProjectPermissionIdentityActions, ProjectPermissionSub } from "../permission/project-permission"; import { TIdentityProjectAdditionalPrivilegeV2DALFactory } from "./identity-project-additional-privilege-v2-dal"; @@ -89,7 +89,12 @@ export const identityProjectAdditionalPrivilegeV2ServiceFactory = ({ if (!permissionBoundary.isValid) throw new ForbiddenRequestError({ name: "PermissionBoundaryError", - message: "Failed to update more privileged identity", + message: constructPermissionErrorMessage( + "Failed to update more privileged identity", + membership.shouldUseNewPrivilegeSystem, + ProjectPermissionIdentityActions.ManagePrivileges, + ProjectPermissionSub.Identity + ), details: { missingPermissions: permissionBoundary.missingPermissions } }); @@ -181,7 +186,12 @@ export const identityProjectAdditionalPrivilegeV2ServiceFactory = ({ if (!permissionBoundary.isValid) throw new ForbiddenRequestError({ name: "PermissionBoundaryError", - message: "Failed to update more privileged identity", + message: constructPermissionErrorMessage( + "Failed to update more privileged identity", + membership.shouldUseNewPrivilegeSystem, + ProjectPermissionIdentityActions.ManagePrivileges, + ProjectPermissionSub.Identity + ), details: { missingPermissions: permissionBoundary.missingPermissions } }); @@ -269,7 +279,12 @@ export const identityProjectAdditionalPrivilegeV2ServiceFactory = ({ if (!permissionBoundary.isValid) throw new ForbiddenRequestError({ name: "PermissionBoundaryError", - message: "Failed to update more privileged identity", + message: constructPermissionErrorMessage( + "Failed to update more privileged identity", + membership.shouldUseNewPrivilegeSystem, + ProjectPermissionIdentityActions.ManagePrivileges, + ProjectPermissionSub.Identity + ), details: { missingPermissions: permissionBoundary.missingPermissions } }); diff --git a/backend/src/ee/services/identity-project-additional-privilege/identity-project-additional-privilege-service.ts b/backend/src/ee/services/identity-project-additional-privilege/identity-project-additional-privilege-service.ts index 6d603d664..35e26d942 100644 --- a/backend/src/ee/services/identity-project-additional-privilege/identity-project-additional-privilege-service.ts +++ b/backend/src/ee/services/identity-project-additional-privilege/identity-project-additional-privilege-service.ts @@ -9,7 +9,7 @@ import { ActorType } from "@app/services/auth/auth-type"; import { TIdentityProjectDALFactory } from "@app/services/identity-project/identity-project-dal"; import { TProjectDALFactory } from "@app/services/project/project-dal"; -import { validatePrivilegeChangeOperation } from "../permission/permission-fns"; +import { constructPermissionErrorMessage, validatePrivilegeChangeOperation } from "../permission/permission-fns"; import { TPermissionServiceFactory } from "../permission/permission-service"; import { ProjectPermissionIdentityActions, @@ -103,7 +103,12 @@ export const identityProjectAdditionalPrivilegeServiceFactory = ({ if (!permissionBoundary.isValid) throw new ForbiddenRequestError({ name: "PermissionBoundaryError", - message: "Failed to update more privileged identity", + message: constructPermissionErrorMessage( + "Failed to update more privileged identity", + membership.shouldUseNewPrivilegeSystem, + ProjectPermissionIdentityActions.ManagePrivileges, + ProjectPermissionSub.Identity + ), details: { missingPermissions: permissionBoundary.missingPermissions } }); @@ -197,7 +202,12 @@ export const identityProjectAdditionalPrivilegeServiceFactory = ({ if (!permissionBoundary.isValid) throw new ForbiddenRequestError({ name: "PermissionBoundaryError", - message: "Failed to update more privileged identity", + message: constructPermissionErrorMessage( + "Failed to update more privileged identity", + membership.shouldUseNewPrivilegeSystem, + ProjectPermissionIdentityActions.ManagePrivileges, + ProjectPermissionSub.Identity + ), details: { missingPermissions: permissionBoundary.missingPermissions } }); @@ -303,7 +313,12 @@ export const identityProjectAdditionalPrivilegeServiceFactory = ({ if (!permissionBoundary.isValid) throw new ForbiddenRequestError({ name: "PermissionBoundaryError", - message: "Failed to edit more privileged identity", + message: constructPermissionErrorMessage( + "Failed to edit more privileged identity", + membership.shouldUseNewPrivilegeSystem, + ProjectPermissionIdentityActions.ManagePrivileges, + ProjectPermissionSub.Identity + ), details: { missingPermissions: permissionBoundary.missingPermissions } }); diff --git a/backend/src/ee/services/permission/permission-fns.ts b/backend/src/ee/services/permission/permission-fns.ts index a0a94c352..f8f2fa0b8 100644 --- a/backend/src/ee/services/permission/permission-fns.ts +++ b/backend/src/ee/services/permission/permission-fns.ts @@ -181,4 +181,19 @@ const validatePrivilegeChangeOperation = ( return validatePermissionBoundary(actorPermission, managedPermission); }; -export { escapeHandlebarsMissingMetadata, isAuthMethodSaml, validateOrgSSO, validatePrivilegeChangeOperation }; +const constructPermissionErrorMessage = ( + baseMessage: string, + shouldUseNewPrivilegeSystem: boolean, + opAction: OrgPermissionSet[0] | ProjectPermissionSet[0], + opSubject: OrgPermissionSet[1] | ProjectPermissionSet[1] +) => { + return `${baseMessage}${shouldUseNewPrivilegeSystem ? `. Missing permission ${opAction} on ${opSubject}` : ""}`; +}; + +export { + escapeHandlebarsMissingMetadata, + isAuthMethodSaml, + validateOrgSSO, + validatePrivilegeChangeOperation, + constructPermissionErrorMessage +}; diff --git a/backend/src/ee/services/project-user-additional-privilege/project-user-additional-privilege-service.ts b/backend/src/ee/services/project-user-additional-privilege/project-user-additional-privilege-service.ts index c6a1ac835..cddc131c9 100644 --- a/backend/src/ee/services/project-user-additional-privilege/project-user-additional-privilege-service.ts +++ b/backend/src/ee/services/project-user-additional-privilege/project-user-additional-privilege-service.ts @@ -8,7 +8,7 @@ import { UnpackedPermissionSchema } from "@app/server/routes/sanitizedSchema/per import { ActorType } from "@app/services/auth/auth-type"; import { TProjectMembershipDALFactory } from "@app/services/project-membership/project-membership-dal"; -import { validatePrivilegeChangeOperation } from "../permission/permission-fns"; +import { constructPermissionErrorMessage, validatePrivilegeChangeOperation } from "../permission/permission-fns"; import { TPermissionServiceFactory } from "../permission/permission-service"; import { ProjectPermissionMemberActions, @@ -90,7 +90,12 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({ if (!permissionBoundary.isValid) throw new ForbiddenRequestError({ name: "PermissionBoundaryError", - message: "Failed to update more privileged user", + message: constructPermissionErrorMessage( + "Failed to update more privileged user", + membership.shouldUseNewPrivilegeSystem, + ProjectPermissionMemberActions.ManagePrivileges, + ProjectPermissionSub.Member + ), details: { missingPermissions: permissionBoundary.missingPermissions } }); @@ -187,7 +192,12 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({ if (!permissionBoundary.isValid) throw new ForbiddenRequestError({ name: "PermissionBoundaryError", - message: "Failed to update more privileged user", + message: constructPermissionErrorMessage( + "Failed to update more privileged user", + membership.shouldUseNewPrivilegeSystem, + ProjectPermissionMemberActions.ManagePrivileges, + ProjectPermissionSub.Member + ), details: { missingPermissions: permissionBoundary.missingPermissions } }); diff --git a/backend/src/services/group-project/group-project-service.ts b/backend/src/services/group-project/group-project-service.ts index 37ffacfa5..05193cc92 100644 --- a/backend/src/services/group-project/group-project-service.ts +++ b/backend/src/services/group-project/group-project-service.ts @@ -2,7 +2,10 @@ import { ForbiddenError } from "@casl/ability"; import ms from "ms"; import { ActionProjectType, ProjectMembershipRole, SecretKeyEncoding, TGroups } from "@app/db/schemas"; -import { validatePrivilegeChangeOperation } from "@app/ee/services/permission/permission-fns"; +import { + constructPermissionErrorMessage, + validatePrivilegeChangeOperation +} from "@app/ee/services/permission/permission-fns"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; import { ProjectPermissionGroupActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { decryptAsymmetric, encryptAsymmetric } from "@app/lib/crypto"; @@ -112,7 +115,12 @@ export const groupProjectServiceFactory = ({ if (!permissionBoundary.isValid) throw new ForbiddenRequestError({ name: "PermissionBoundaryError", - message: "Failed to assign group to a more privileged role", + message: constructPermissionErrorMessage( + "Failed to assign group to a more privileged role", + membership.shouldUseNewPrivilegeSystem, + ProjectPermissionGroupActions.ManagePrivileges, + ProjectPermissionSub.Groups + ), details: { missingPermissions: permissionBoundary.missingPermissions } }); } @@ -285,7 +293,12 @@ export const groupProjectServiceFactory = ({ if (!permissionBoundary.isValid) throw new ForbiddenRequestError({ name: "PermissionBoundaryError", - message: "Failed to assign group to a more privileged role", + message: constructPermissionErrorMessage( + "Failed to assign group to a more privileged role", + membership.shouldUseNewPrivilegeSystem, + ProjectPermissionGroupActions.ManagePrivileges, + ProjectPermissionSub.Groups + ), details: { missingPermissions: permissionBoundary.missingPermissions } }); } diff --git a/backend/src/services/identity-aws-auth/identity-aws-auth-service.ts b/backend/src/services/identity-aws-auth/identity-aws-auth-service.ts index f80b1b2c3..ddef0c553 100644 --- a/backend/src/services/identity-aws-auth/identity-aws-auth-service.ts +++ b/backend/src/services/identity-aws-auth/identity-aws-auth-service.ts @@ -6,7 +6,10 @@ import jwt from "jsonwebtoken"; import { IdentityAuthMethod } from "@app/db/schemas"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission"; -import { validatePrivilegeChangeOperation } from "@app/ee/services/permission/permission-fns"; +import { + constructPermissionErrorMessage, + validatePrivilegeChangeOperation +} from "@app/ee/services/permission/permission-fns"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; import { getConfig } from "@app/lib/config/env"; import { BadRequestError, ForbiddenRequestError, NotFoundError, UnauthorizedError } from "@app/lib/errors"; @@ -350,7 +353,12 @@ export const identityAwsAuthServiceFactory = ({ if (!permissionBoundary.isValid) throw new ForbiddenRequestError({ name: "PermissionBoundaryError", - message: "Failed to revoke aws auth of identity with more privileged role", + message: constructPermissionErrorMessage( + "Failed to revoke aws auth of identity with more privileged role", + membership.shouldUseNewPrivilegeSystem, + OrgPermissionIdentityActions.RevokeAuth, + OrgPermissionSubjects.Identity + ), details: { missingPermissions: permissionBoundary.missingPermissions } }); diff --git a/backend/src/services/identity-azure-auth/identity-azure-auth-service.ts b/backend/src/services/identity-azure-auth/identity-azure-auth-service.ts index 56249c606..61f9ca23f 100644 --- a/backend/src/services/identity-azure-auth/identity-azure-auth-service.ts +++ b/backend/src/services/identity-azure-auth/identity-azure-auth-service.ts @@ -4,7 +4,10 @@ import jwt from "jsonwebtoken"; import { IdentityAuthMethod } from "@app/db/schemas"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission"; -import { validatePrivilegeChangeOperation } from "@app/ee/services/permission/permission-fns"; +import { + constructPermissionErrorMessage, + validatePrivilegeChangeOperation +} from "@app/ee/services/permission/permission-fns"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; import { getConfig } from "@app/lib/config/env"; import { BadRequestError, ForbiddenRequestError, NotFoundError, UnauthorizedError } from "@app/lib/errors"; @@ -322,7 +325,12 @@ export const identityAzureAuthServiceFactory = ({ if (!permissionBoundary.isValid) throw new ForbiddenRequestError({ name: "PermissionBoundaryError", - message: "Failed to revoke azure auth of identity with more privileged role", + message: constructPermissionErrorMessage( + "Failed to revoke azure auth of identity with more privileged role", + membership.shouldUseNewPrivilegeSystem, + OrgPermissionIdentityActions.RevokeAuth, + OrgPermissionSubjects.Identity + ), details: { missingPermissions: permissionBoundary.missingPermissions } }); diff --git a/backend/src/services/identity-gcp-auth/identity-gcp-auth-service.ts b/backend/src/services/identity-gcp-auth/identity-gcp-auth-service.ts index 11c5151e9..014e4619f 100644 --- a/backend/src/services/identity-gcp-auth/identity-gcp-auth-service.ts +++ b/backend/src/services/identity-gcp-auth/identity-gcp-auth-service.ts @@ -4,7 +4,10 @@ import jwt from "jsonwebtoken"; import { IdentityAuthMethod } from "@app/db/schemas"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission"; -import { validatePrivilegeChangeOperation } from "@app/ee/services/permission/permission-fns"; +import { + constructPermissionErrorMessage, + validatePrivilegeChangeOperation +} from "@app/ee/services/permission/permission-fns"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; import { getConfig } from "@app/lib/config/env"; import { BadRequestError, ForbiddenRequestError, NotFoundError, UnauthorizedError } from "@app/lib/errors"; @@ -368,7 +371,12 @@ export const identityGcpAuthServiceFactory = ({ if (!permissionBoundary.isValid) throw new ForbiddenRequestError({ name: "PermissionBoundaryError", - message: "Failed to revoke gcp auth of identity with more privileged role", + message: constructPermissionErrorMessage( + "Failed to revoke gcp auth of identity with more privileged role", + membership.shouldUseNewPrivilegeSystem, + OrgPermissionIdentityActions.RevokeAuth, + OrgPermissionSubjects.Identity + ), details: { missingPermissions: permissionBoundary.missingPermissions } }); diff --git a/backend/src/services/identity-jwt-auth/identity-jwt-auth-service.ts b/backend/src/services/identity-jwt-auth/identity-jwt-auth-service.ts index 353d1e46f..114ca79c0 100644 --- a/backend/src/services/identity-jwt-auth/identity-jwt-auth-service.ts +++ b/backend/src/services/identity-jwt-auth/identity-jwt-auth-service.ts @@ -6,7 +6,10 @@ import { JwksClient } from "jwks-rsa"; import { IdentityAuthMethod, TIdentityJwtAuthsUpdate } from "@app/db/schemas"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission"; -import { validatePrivilegeChangeOperation } from "@app/ee/services/permission/permission-fns"; +import { + constructPermissionErrorMessage, + validatePrivilegeChangeOperation +} from "@app/ee/services/permission/permission-fns"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; import { getConfig } from "@app/lib/config/env"; import { BadRequestError, ForbiddenRequestError, NotFoundError, UnauthorizedError } from "@app/lib/errors"; @@ -526,7 +529,12 @@ export const identityJwtAuthServiceFactory = ({ if (!permissionBoundary.isValid) throw new ForbiddenRequestError({ name: "PermissionBoundaryError", - message: "Failed to revoke jwt auth of identity with more privileged role", + message: constructPermissionErrorMessage( + "Failed to revoke jwt auth of identity with more privileged role", + membership.shouldUseNewPrivilegeSystem, + OrgPermissionIdentityActions.RevokeAuth, + OrgPermissionSubjects.Identity + ), details: { missingPermissions: permissionBoundary.missingPermissions } }); diff --git a/backend/src/services/identity-kubernetes-auth/identity-kubernetes-auth-service.ts b/backend/src/services/identity-kubernetes-auth/identity-kubernetes-auth-service.ts index bc7dda22e..a18de9ad8 100644 --- a/backend/src/services/identity-kubernetes-auth/identity-kubernetes-auth-service.ts +++ b/backend/src/services/identity-kubernetes-auth/identity-kubernetes-auth-service.ts @@ -6,7 +6,10 @@ import jwt from "jsonwebtoken"; import { IdentityAuthMethod, TIdentityKubernetesAuthsUpdate } from "@app/db/schemas"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission"; -import { validatePrivilegeChangeOperation } from "@app/ee/services/permission/permission-fns"; +import { + constructPermissionErrorMessage, + validatePrivilegeChangeOperation +} from "@app/ee/services/permission/permission-fns"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; import { getConfig } from "@app/lib/config/env"; import { BadRequestError, ForbiddenRequestError, NotFoundError, UnauthorizedError } from "@app/lib/errors"; @@ -497,7 +500,12 @@ export const identityKubernetesAuthServiceFactory = ({ if (!permissionBoundary.isValid) throw new ForbiddenRequestError({ name: "PermissionBoundaryError", - message: "Failed to revoke kubernetes auth of identity with more privileged role", + message: constructPermissionErrorMessage( + "Failed to revoke kubernetes auth of identity with more privileged role", + membership.shouldUseNewPrivilegeSystem, + OrgPermissionIdentityActions.RevokeAuth, + OrgPermissionSubjects.Identity + ), details: { missingPermissions: permissionBoundary.missingPermissions } }); diff --git a/backend/src/services/identity-oidc-auth/identity-oidc-auth-service.ts b/backend/src/services/identity-oidc-auth/identity-oidc-auth-service.ts index bb0077664..3e58c8f6f 100644 --- a/backend/src/services/identity-oidc-auth/identity-oidc-auth-service.ts +++ b/backend/src/services/identity-oidc-auth/identity-oidc-auth-service.ts @@ -7,7 +7,10 @@ import { JwksClient } from "jwks-rsa"; import { IdentityAuthMethod, TIdentityOidcAuthsUpdate } from "@app/db/schemas"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission"; -import { validatePrivilegeChangeOperation } from "@app/ee/services/permission/permission-fns"; +import { + constructPermissionErrorMessage, + validatePrivilegeChangeOperation +} from "@app/ee/services/permission/permission-fns"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; import { getConfig } from "@app/lib/config/env"; import { BadRequestError, ForbiddenRequestError, NotFoundError, UnauthorizedError } from "@app/lib/errors"; @@ -439,7 +442,12 @@ export const identityOidcAuthServiceFactory = ({ if (!permissionBoundary.isValid) throw new ForbiddenRequestError({ name: "PermissionBoundaryError", - message: "Failed to revoke oidc auth of identity with more privileged role", + message: constructPermissionErrorMessage( + "Failed to revoke oidc auth of identity with more privileged role", + membership.shouldUseNewPrivilegeSystem, + OrgPermissionIdentityActions.RevokeAuth, + OrgPermissionSubjects.Identity + ), details: { missingPermissions: permissionBoundary.missingPermissions } }); diff --git a/backend/src/services/identity-project/identity-project-service.ts b/backend/src/services/identity-project/identity-project-service.ts index ae7f8f25b..5486b37a8 100644 --- a/backend/src/services/identity-project/identity-project-service.ts +++ b/backend/src/services/identity-project/identity-project-service.ts @@ -2,7 +2,10 @@ import { ForbiddenError, subject } from "@casl/ability"; import ms from "ms"; import { ActionProjectType, ProjectMembershipRole } from "@app/db/schemas"; -import { validatePrivilegeChangeOperation } from "@app/ee/services/permission/permission-fns"; +import { + constructPermissionErrorMessage, + validatePrivilegeChangeOperation +} from "@app/ee/services/permission/permission-fns"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; import { ProjectPermissionIdentityActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { BadRequestError, ForbiddenRequestError, NotFoundError } from "@app/lib/errors"; @@ -100,7 +103,12 @@ export const identityProjectServiceFactory = ({ if (!permissionBoundary.isValid) throw new ForbiddenRequestError({ name: "PermissionBoundaryError", - message: "Failed to assign to a more privileged role", + message: constructPermissionErrorMessage( + "Failed to assign to a more privileged role", + membership.shouldUseNewPrivilegeSystem, + ProjectPermissionIdentityActions.ManagePrivileges, + ProjectPermissionSub.Identity + ), details: { missingPermissions: permissionBoundary.missingPermissions } }); } @@ -203,7 +211,12 @@ export const identityProjectServiceFactory = ({ if (!permissionBoundary.isValid) throw new ForbiddenRequestError({ name: "PermissionBoundaryError", - message: "Failed to change to a more privileged role", + message: constructPermissionErrorMessage( + "Failed to change to a more privileged role", + membership.shouldUseNewPrivilegeSystem, + ProjectPermissionIdentityActions.ManagePrivileges, + ProjectPermissionSub.Identity + ), details: { missingPermissions: permissionBoundary.missingPermissions } }); } diff --git a/backend/src/services/identity-token-auth/identity-token-auth-service.ts b/backend/src/services/identity-token-auth/identity-token-auth-service.ts index ab2216458..4079d0756 100644 --- a/backend/src/services/identity-token-auth/identity-token-auth-service.ts +++ b/backend/src/services/identity-token-auth/identity-token-auth-service.ts @@ -4,7 +4,10 @@ import jwt from "jsonwebtoken"; import { IdentityAuthMethod, TableName } from "@app/db/schemas"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission"; -import { validatePrivilegeChangeOperation } from "@app/ee/services/permission/permission-fns"; +import { + constructPermissionErrorMessage, + validatePrivilegeChangeOperation +} from "@app/ee/services/permission/permission-fns"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; import { getConfig } from "@app/lib/config/env"; import { BadRequestError, ForbiddenRequestError, NotFoundError } from "@app/lib/errors"; @@ -255,7 +258,12 @@ export const identityTokenAuthServiceFactory = ({ if (!permissionBoundary.isValid) throw new ForbiddenRequestError({ name: "PermissionBoundaryError", - message: "Failed to revoke token auth of identity with more privileged role", + message: constructPermissionErrorMessage( + "Failed to revoke token auth of identity with more privileged role", + membership.shouldUseNewPrivilegeSystem, + OrgPermissionIdentityActions.RevokeAuth, + OrgPermissionSubjects.Identity + ), details: { missingPermissions: permissionBoundary.missingPermissions } }); @@ -314,7 +322,12 @@ export const identityTokenAuthServiceFactory = ({ if (!permissionBoundary.isValid) throw new ForbiddenRequestError({ name: "PermissionBoundaryError", - message: "Failed to create token for identity with more privileged role", + message: constructPermissionErrorMessage( + "Failed to create token for identity with more privileged role", + membership.shouldUseNewPrivilegeSystem, + OrgPermissionIdentityActions.CreateToken, + OrgPermissionSubjects.Identity + ), details: { missingPermissions: permissionBoundary.missingPermissions } }); @@ -442,7 +455,12 @@ export const identityTokenAuthServiceFactory = ({ if (!permissionBoundary.isValid) throw new ForbiddenRequestError({ name: "PermissionBoundaryError", - message: "Failed to update token for identity with more privileged role", + message: constructPermissionErrorMessage( + "Failed to update token for identity with more privileged role", + membership.shouldUseNewPrivilegeSystem, + OrgPermissionIdentityActions.CreateToken, + OrgPermissionSubjects.Identity + ), details: { missingPermissions: permissionBoundary.missingPermissions } }); diff --git a/backend/src/services/identity-ua/identity-ua-service.ts b/backend/src/services/identity-ua/identity-ua-service.ts index 0c067e057..c057a656a 100644 --- a/backend/src/services/identity-ua/identity-ua-service.ts +++ b/backend/src/services/identity-ua/identity-ua-service.ts @@ -7,7 +7,10 @@ import jwt from "jsonwebtoken"; import { IdentityAuthMethod } from "@app/db/schemas"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission"; -import { validatePrivilegeChangeOperation } from "@app/ee/services/permission/permission-fns"; +import { + constructPermissionErrorMessage, + validatePrivilegeChangeOperation +} from "@app/ee/services/permission/permission-fns"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; import { getConfig } from "@app/lib/config/env"; import { BadRequestError, ForbiddenRequestError, NotFoundError, UnauthorizedError } from "@app/lib/errors"; @@ -377,7 +380,12 @@ export const identityUaServiceFactory = ({ if (!permissionBoundary.isValid) throw new ForbiddenRequestError({ name: "PermissionBoundaryError", - message: "Failed to revoke universal auth of identity with more privileged role", + message: constructPermissionErrorMessage( + "Failed to revoke universal auth of identity with more privileged role", + membership.shouldUseNewPrivilegeSystem, + OrgPermissionIdentityActions.RevokeAuth, + OrgPermissionSubjects.Identity + ), details: { missingPermissions: permissionBoundary.missingPermissions } }); @@ -433,7 +441,12 @@ export const identityUaServiceFactory = ({ if (!permissionBoundary.isValid) throw new ForbiddenRequestError({ name: "PermissionBoundaryError", - message: "Failed to create client secret for a more privileged identity.", + message: constructPermissionErrorMessage( + "Failed to create client secret for a more privileged identity.", + membership.shouldUseNewPrivilegeSystem, + OrgPermissionIdentityActions.CreateToken, + OrgPermissionSubjects.Identity + ), details: { missingPermissions: permissionBoundary.missingPermissions } }); @@ -502,7 +515,12 @@ export const identityUaServiceFactory = ({ if (!permissionBoundary.isValid) throw new ForbiddenRequestError({ name: "PermissionBoundaryError", - message: "Failed to get identity client secret with more privileged role", + message: constructPermissionErrorMessage( + "Failed to get identity client secret with more privileged role", + membership.shouldUseNewPrivilegeSystem, + OrgPermissionIdentityActions.GetToken, + OrgPermissionSubjects.Identity + ), details: { missingPermissions: permissionBoundary.missingPermissions } }); @@ -560,7 +578,12 @@ export const identityUaServiceFactory = ({ if (!permissionBoundary.isValid) throw new ForbiddenRequestError({ name: "PermissionBoundaryError", - message: "Failed to read identity client secret of identity with more privileged role", + message: constructPermissionErrorMessage( + "Failed to read identity client secret of identity with more privileged role", + membership.shouldUseNewPrivilegeSystem, + OrgPermissionIdentityActions.GetToken, + OrgPermissionSubjects.Identity + ), details: { missingPermissions: permissionBoundary.missingPermissions } }); @@ -612,7 +635,12 @@ export const identityUaServiceFactory = ({ if (!permissionBoundary.isValid) { throw new ForbiddenRequestError({ name: "PermissionBoundaryError", - message: "Failed to revoke identity client secret with more privileged role", + message: constructPermissionErrorMessage( + "Failed to revoke identity client secret with more privileged role", + membership.shouldUseNewPrivilegeSystem, + OrgPermissionIdentityActions.DeleteToken, + OrgPermissionSubjects.Identity + ), details: { missingPermissions: permissionBoundary.missingPermissions } }); } diff --git a/backend/src/services/identity/identity-service.ts b/backend/src/services/identity/identity-service.ts index 937fba6f7..0426e6f8c 100644 --- a/backend/src/services/identity/identity-service.ts +++ b/backend/src/services/identity/identity-service.ts @@ -3,7 +3,10 @@ import { ForbiddenError } from "@casl/ability"; import { OrgMembershipRole, TableName, TOrgRoles } from "@app/db/schemas"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; import { OrgPermissionIdentityActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission"; -import { validatePrivilegeChangeOperation } from "@app/ee/services/permission/permission-fns"; +import { + constructPermissionErrorMessage, + validatePrivilegeChangeOperation +} from "@app/ee/services/permission/permission-fns"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; import { BadRequestError, ForbiddenRequestError, NotFoundError } from "@app/lib/errors"; import { TIdentityProjectDALFactory } from "@app/services/identity-project/identity-project-dal"; @@ -73,7 +76,12 @@ export const identityServiceFactory = ({ if (!permissionBoundary.isValid) throw new ForbiddenRequestError({ name: "PermissionBoundaryError", - message: "Failed to create a more privileged identity", + message: constructPermissionErrorMessage( + "Failed to create a more privileged identity", + membership.shouldUseNewPrivilegeSystem, + OrgPermissionIdentityActions.ManagePrivileges, + OrgPermissionSubjects.Identity + ), details: { missingPermissions: permissionBoundary.missingPermissions } }); @@ -155,7 +163,12 @@ export const identityServiceFactory = ({ if (!appliedRolePermissionBoundary.isValid) throw new ForbiddenRequestError({ name: "PermissionBoundaryError", - message: "Failed to create a more privileged identity", + message: constructPermissionErrorMessage( + "Failed to update identity", + membership.shouldUseNewPrivilegeSystem, + OrgPermissionIdentityActions.ManagePrivileges, + OrgPermissionSubjects.Identity + ), details: { missingPermissions: appliedRolePermissionBoundary.missingPermissions } }); if (isCustomRole) customRole = customOrgRole; diff --git a/backend/src/services/org/org-service.ts b/backend/src/services/org/org-service.ts index 63aaa2457..844d3f385 100644 --- a/backend/src/services/org/org-service.ts +++ b/backend/src/services/org/org-service.ts @@ -24,7 +24,10 @@ import { OrgPermissionGroupActions, OrgPermissionSubjects } from "@app/ee/services/permission/org-permission"; -import { validatePrivilegeChangeOperation } from "@app/ee/services/permission/permission-fns"; +import { + constructPermissionErrorMessage, + validatePrivilegeChangeOperation +} from "@app/ee/services/permission/permission-fns"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; import { ProjectPermissionMemberActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { TProjectUserAdditionalPrivilegeDALFactory } from "@app/ee/services/project-user-additional-privilege/project-user-additional-privilege-dal"; @@ -930,7 +933,12 @@ export const orgServiceFactory = ({ if (!permissionBoundary.isValid) throw new ForbiddenRequestError({ name: "PermissionBoundaryError", - message: "Failed to invite user to a more privileged role in the project", + message: constructPermissionErrorMessage( + "Failed to invite user to a more privileged role in the project", + membership.shouldUseNewPrivilegeSystem, + ProjectPermissionMemberActions.ManagePrivileges, + ProjectPermissionSub.Member + ), details: { missingPermissions: permissionBoundary.missingPermissions } }); } diff --git a/backend/src/services/project-membership/project-membership-service.ts b/backend/src/services/project-membership/project-membership-service.ts index 62668ed77..2708e69ba 100644 --- a/backend/src/services/project-membership/project-membership-service.ts +++ b/backend/src/services/project-membership/project-membership-service.ts @@ -4,7 +4,10 @@ import ms from "ms"; import { ActionProjectType, ProjectMembershipRole, ProjectVersion, TableName } from "@app/db/schemas"; import { TLicenseServiceFactory } from "@app/ee/services/license/license-service"; -import { validatePrivilegeChangeOperation } from "@app/ee/services/permission/permission-fns"; +import { + constructPermissionErrorMessage, + validatePrivilegeChangeOperation +} from "@app/ee/services/permission/permission-fns"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; import { ProjectPermissionMemberActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission"; import { TProjectUserAdditionalPrivilegeDALFactory } from "@app/ee/services/project-user-additional-privilege/project-user-additional-privilege-dal"; @@ -284,7 +287,12 @@ export const projectMembershipServiceFactory = ({ if (!permissionBoundary.isValid) throw new ForbiddenRequestError({ name: "PermissionBoundaryError", - message: `Failed to change to a more privileged role ${requestedRoleChange}`, + message: constructPermissionErrorMessage( + `Failed to change to a more privileged role ${requestedRoleChange}`, + membership.shouldUseNewPrivilegeSystem, + ProjectPermissionMemberActions.ManagePrivileges, + ProjectPermissionSub.Member + ), details: { missingPermissions: permissionBoundary.missingPermissions } }); }