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 5132b0fc9..26a694a4a 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 @@ -2,6 +2,7 @@ import { ForbiddenError } from "@casl/ability"; import { packRules } from "@casl/ability/extra"; import ms from "ms"; +import { TableName } from "@app/db/schemas"; import { isAtLeastAsPrivileged } from "@app/lib/casl"; import { BadRequestError, ForbiddenRequestError, NotFoundError } from "@app/lib/errors"; import { unpackPermissions } from "@app/server/routes/santizedSchemas/permission"; @@ -322,9 +323,12 @@ export const identityProjectAdditionalPrivilegeV2ServiceFactory = ({ ); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Identity); - const identityPrivileges = await identityProjectAdditionalPrivilegeDAL.find({ - projectMembershipId: identityProjectMembership.id - }); + const identityPrivileges = await identityProjectAdditionalPrivilegeDAL.find( + { + projectMembershipId: identityProjectMembership.id + }, + { sort: [[`${TableName.IdentityProjectAdditionalPrivilege}.slug` as "slug", "asc"]] } + ); return identityPrivileges; }; 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 cadcd610a..86d8e652a 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 @@ -2,6 +2,7 @@ import { ForbiddenError, MongoAbility, RawRuleOf } from "@casl/ability"; import { PackRule, packRules, unpackRules } from "@casl/ability/extra"; import ms from "ms"; +import { TableName } from "@app/db/schemas"; import { isAtLeastAsPrivileged } from "@app/lib/casl"; import { BadRequestError, ForbiddenRequestError, NotFoundError } from "@app/lib/errors"; import { UnpackedPermissionSchema } from "@app/server/routes/santizedSchemas/permission"; @@ -294,10 +295,13 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({ ); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Member); - const userPrivileges = await projectUserAdditionalPrivilegeDAL.find({ - userId: projectMembership.userId, - projectId: projectMembership.projectId - }); + const userPrivileges = await projectUserAdditionalPrivilegeDAL.find( + { + userId: projectMembership.userId, + projectId: projectMembership.projectId + }, + { sort: [[`${TableName.ProjectUserAdditionalPrivilege}.slug` as "slug", "asc"]] } + ); return userPrivileges; }; diff --git a/backend/src/services/project-role/project-role-service.ts b/backend/src/services/project-role/project-role-service.ts index 95009f645..55564bc17 100644 --- a/backend/src/services/project-role/project-role-service.ts +++ b/backend/src/services/project-role/project-role-service.ts @@ -1,7 +1,7 @@ import { ForbiddenError, MongoAbility, RawRuleOf } from "@casl/ability"; import { PackRule, packRules, unpackRules } from "@casl/ability/extra"; -import { ProjectMembershipRole } from "@app/db/schemas"; +import { ProjectMembershipRole, TableName } from "@app/db/schemas"; import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service"; import { ProjectPermissionActions, @@ -193,7 +193,10 @@ export const projectRoleServiceFactory = ({ actorOrgId ); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Role); - const customRoles = await projectRoleDAL.find({ projectId }); + const customRoles = await projectRoleDAL.find( + { projectId }, + { sort: [[`${TableName.ProjectRoles}.slug` as "slug", "asc"]] } + ); const roles = [...getPredefinedRoles(projectId), ...(customRoles || [])]; return roles; diff --git a/frontend/src/views/Project/RolePage/components/RolePermissionsSection/ProjectRoleModifySection.utils.tsx b/frontend/src/views/Project/RolePage/components/RolePermissionsSection/ProjectRoleModifySection.utils.tsx index 25a390ac5..e298281f8 100644 --- a/frontend/src/views/Project/RolePage/components/RolePermissionsSection/ProjectRoleModifySection.utils.tsx +++ b/frontend/src/views/Project/RolePage/components/RolePermissionsSection/ProjectRoleModifySection.utils.tsx @@ -234,36 +234,53 @@ export const rolePermission2Form = (permissions: TProjectPermission[] = []) => { inverted, [ProjectPermissionDynamicSecretActions.Lease]: canLease }); - } else { - // for other subjects - const canRead = action.includes(ProjectPermissionActions.Read); - const canEdit = action.includes(ProjectPermissionActions.Edit); - const canDelete = action.includes(ProjectPermissionActions.Delete); - const canCreate = action.includes(ProjectPermissionActions.Create); - formVal[subject]!.push({ - read: canRead, - create: canCreate, - edit: canEdit, - delete: canDelete, - conditions: conditions ? convertCaslConditionToFormOperator(conditions) : [], - inverted - }); + return; } - } else { - // deduplicate multiple rules for other policies - // because they don't have condition it doesn't make sense for multiple rules + // for other subjects const canRead = action.includes(ProjectPermissionActions.Read); const canEdit = action.includes(ProjectPermissionActions.Edit); const canDelete = action.includes(ProjectPermissionActions.Delete); const canCreate = action.includes(ProjectPermissionActions.Create); - if (!formVal[subject]) formVal[subject] = [{}]; - if (canRead) formVal[subject as ProjectPermissionSub.Member]![0].read = true; - if (canEdit) formVal[subject as ProjectPermissionSub.Member]![0].edit = true; - if (canCreate) formVal[subject as ProjectPermissionSub.Member]![0].create = true; - if (canDelete) formVal[subject as ProjectPermissionSub.Member]![0].delete = true; + // remove this condition later + // keeping when old routes create permission with folder read + if ( + subject === ProjectPermissionSub.SecretFolders && + canRead && + !canEdit && + !canDelete && + !canCreate + ) { + return; + } + + formVal[subject]!.push({ + read: canRead, + create: canCreate, + edit: canEdit, + delete: canDelete, + conditions: conditions ? convertCaslConditionToFormOperator(conditions) : [], + inverted + }); + return; } - } else if (subject === ProjectPermissionSub.Project) { + + // deduplicate multiple rules for other policies + // because they don't have condition it doesn't make sense for multiple rules + const canRead = action.includes(ProjectPermissionActions.Read); + const canEdit = action.includes(ProjectPermissionActions.Edit); + const canDelete = action.includes(ProjectPermissionActions.Delete); + const canCreate = action.includes(ProjectPermissionActions.Create); + + if (!formVal[subject]) formVal[subject] = [{}]; + if (canRead) formVal[subject as ProjectPermissionSub.Member]![0].read = true; + if (canEdit) formVal[subject as ProjectPermissionSub.Member]![0].edit = true; + if (canCreate) formVal[subject as ProjectPermissionSub.Member]![0].create = true; + if (canDelete) formVal[subject as ProjectPermissionSub.Member]![0].delete = true; + return; + } + + if (subject === ProjectPermissionSub.Project) { const canEdit = action.includes(ProjectPermissionActions.Edit); const canDelete = action.includes(ProjectPermissionActions.Delete); if (!formVal[subject]) formVal[subject] = [{}]; @@ -271,7 +288,10 @@ export const rolePermission2Form = (permissions: TProjectPermission[] = []) => { // from above statement we are sure it won't be undefined if (canEdit) formVal[subject as ProjectPermissionSub.Project]![0].edit = true; if (canDelete) formVal[subject as ProjectPermissionSub.Member]![0].delete = true; - } else if (subject === ProjectPermissionSub.SecretRollback) { + return; + } + + if (subject === ProjectPermissionSub.SecretRollback) { const canRead = action.includes(ProjectPermissionActions.Read); const canCreate = action.includes(ProjectPermissionActions.Create); if (!formVal[subject]) formVal[subject] = [{}]; @@ -279,7 +299,10 @@ export const rolePermission2Form = (permissions: TProjectPermission[] = []) => { // from above statement we are sure it won't be undefined if (canRead) formVal[subject as ProjectPermissionSub.Member]![0].read = true; if (canCreate) formVal[subject as ProjectPermissionSub.Member]![0].create = true; - } else if (subject === ProjectPermissionSub.Cmek) { + return; + } + + if (subject === ProjectPermissionSub.Cmek) { const canRead = action.includes(ProjectPermissionCmekActions.Read); const canEdit = action.includes(ProjectPermissionCmekActions.Edit); const canDelete = action.includes(ProjectPermissionCmekActions.Delete);