feat: refactored frontend form logic and added sort on list for roles, privileges

This commit is contained in:
=
2024-10-25 00:59:41 +05:30
parent e0cbcb0318
commit c8e47771d4
4 changed files with 68 additions and 34 deletions
@@ -2,6 +2,7 @@ import { ForbiddenError } from "@casl/ability";
import { packRules } from "@casl/ability/extra"; import { packRules } from "@casl/ability/extra";
import ms from "ms"; import ms from "ms";
import { TableName } from "@app/db/schemas";
import { isAtLeastAsPrivileged } from "@app/lib/casl"; import { isAtLeastAsPrivileged } from "@app/lib/casl";
import { BadRequestError, ForbiddenRequestError, NotFoundError } from "@app/lib/errors"; import { BadRequestError, ForbiddenRequestError, NotFoundError } from "@app/lib/errors";
import { unpackPermissions } from "@app/server/routes/santizedSchemas/permission"; import { unpackPermissions } from "@app/server/routes/santizedSchemas/permission";
@@ -322,9 +323,12 @@ export const identityProjectAdditionalPrivilegeV2ServiceFactory = ({
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Identity); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Identity);
const identityPrivileges = await identityProjectAdditionalPrivilegeDAL.find({ const identityPrivileges = await identityProjectAdditionalPrivilegeDAL.find(
{
projectMembershipId: identityProjectMembership.id projectMembershipId: identityProjectMembership.id
}); },
{ sort: [[`${TableName.IdentityProjectAdditionalPrivilege}.slug` as "slug", "asc"]] }
);
return identityPrivileges; return identityPrivileges;
}; };
@@ -2,6 +2,7 @@ import { ForbiddenError, MongoAbility, RawRuleOf } from "@casl/ability";
import { PackRule, packRules, unpackRules } from "@casl/ability/extra"; import { PackRule, packRules, unpackRules } from "@casl/ability/extra";
import ms from "ms"; import ms from "ms";
import { TableName } from "@app/db/schemas";
import { isAtLeastAsPrivileged } from "@app/lib/casl"; import { isAtLeastAsPrivileged } from "@app/lib/casl";
import { BadRequestError, ForbiddenRequestError, NotFoundError } from "@app/lib/errors"; import { BadRequestError, ForbiddenRequestError, NotFoundError } from "@app/lib/errors";
import { UnpackedPermissionSchema } from "@app/server/routes/santizedSchemas/permission"; import { UnpackedPermissionSchema } from "@app/server/routes/santizedSchemas/permission";
@@ -294,10 +295,13 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Member); ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Member);
const userPrivileges = await projectUserAdditionalPrivilegeDAL.find({ const userPrivileges = await projectUserAdditionalPrivilegeDAL.find(
{
userId: projectMembership.userId, userId: projectMembership.userId,
projectId: projectMembership.projectId projectId: projectMembership.projectId
}); },
{ sort: [[`${TableName.ProjectUserAdditionalPrivilege}.slug` as "slug", "asc"]] }
);
return userPrivileges; return userPrivileges;
}; };
@@ -1,7 +1,7 @@
import { ForbiddenError, MongoAbility, RawRuleOf } from "@casl/ability"; import { ForbiddenError, MongoAbility, RawRuleOf } from "@casl/ability";
import { PackRule, packRules, unpackRules } from "@casl/ability/extra"; 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 { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
import { import {
ProjectPermissionActions, ProjectPermissionActions,
@@ -193,7 +193,10 @@ export const projectRoleServiceFactory = ({
actorOrgId actorOrgId
); );
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Role); 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 || [])]; const roles = [...getPredefinedRoles(projectId), ...(customRoles || [])];
return roles; return roles;
@@ -234,12 +234,26 @@ export const rolePermission2Form = (permissions: TProjectPermission[] = []) => {
inverted, inverted,
[ProjectPermissionDynamicSecretActions.Lease]: canLease [ProjectPermissionDynamicSecretActions.Lease]: canLease
}); });
} else { return;
}
// for other subjects // for other subjects
const canRead = action.includes(ProjectPermissionActions.Read); const canRead = action.includes(ProjectPermissionActions.Read);
const canEdit = action.includes(ProjectPermissionActions.Edit); const canEdit = action.includes(ProjectPermissionActions.Edit);
const canDelete = action.includes(ProjectPermissionActions.Delete); const canDelete = action.includes(ProjectPermissionActions.Delete);
const canCreate = action.includes(ProjectPermissionActions.Create); const canCreate = action.includes(ProjectPermissionActions.Create);
// 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({ formVal[subject]!.push({
read: canRead, read: canRead,
create: canCreate, create: canCreate,
@@ -248,8 +262,9 @@ export const rolePermission2Form = (permissions: TProjectPermission[] = []) => {
conditions: conditions ? convertCaslConditionToFormOperator(conditions) : [], conditions: conditions ? convertCaslConditionToFormOperator(conditions) : [],
inverted inverted
}); });
return;
} }
} else {
// deduplicate multiple rules for other policies // deduplicate multiple rules for other policies
// because they don't have condition it doesn't make sense for multiple rules // because they don't have condition it doesn't make sense for multiple rules
const canRead = action.includes(ProjectPermissionActions.Read); const canRead = action.includes(ProjectPermissionActions.Read);
@@ -262,8 +277,10 @@ export const rolePermission2Form = (permissions: TProjectPermission[] = []) => {
if (canEdit) formVal[subject as ProjectPermissionSub.Member]![0].edit = true; if (canEdit) formVal[subject as ProjectPermissionSub.Member]![0].edit = true;
if (canCreate) formVal[subject as ProjectPermissionSub.Member]![0].create = true; if (canCreate) formVal[subject as ProjectPermissionSub.Member]![0].create = true;
if (canDelete) formVal[subject as ProjectPermissionSub.Member]![0].delete = true; if (canDelete) formVal[subject as ProjectPermissionSub.Member]![0].delete = true;
return;
} }
} else if (subject === ProjectPermissionSub.Project) {
if (subject === ProjectPermissionSub.Project) {
const canEdit = action.includes(ProjectPermissionActions.Edit); const canEdit = action.includes(ProjectPermissionActions.Edit);
const canDelete = action.includes(ProjectPermissionActions.Delete); const canDelete = action.includes(ProjectPermissionActions.Delete);
if (!formVal[subject]) formVal[subject] = [{}]; 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 // from above statement we are sure it won't be undefined
if (canEdit) formVal[subject as ProjectPermissionSub.Project]![0].edit = true; if (canEdit) formVal[subject as ProjectPermissionSub.Project]![0].edit = true;
if (canDelete) formVal[subject as ProjectPermissionSub.Member]![0].delete = 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 canRead = action.includes(ProjectPermissionActions.Read);
const canCreate = action.includes(ProjectPermissionActions.Create); const canCreate = action.includes(ProjectPermissionActions.Create);
if (!formVal[subject]) formVal[subject] = [{}]; 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 // from above statement we are sure it won't be undefined
if (canRead) formVal[subject as ProjectPermissionSub.Member]![0].read = true; if (canRead) formVal[subject as ProjectPermissionSub.Member]![0].read = true;
if (canCreate) formVal[subject as ProjectPermissionSub.Member]![0].create = 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 canRead = action.includes(ProjectPermissionCmekActions.Read);
const canEdit = action.includes(ProjectPermissionCmekActions.Edit); const canEdit = action.includes(ProjectPermissionCmekActions.Edit);
const canDelete = action.includes(ProjectPermissionCmekActions.Delete); const canDelete = action.includes(ProjectPermissionCmekActions.Delete);