feat: removed console and resolved drift in tf due to folder removing in v1

This commit is contained in:
=
2024-10-23 16:21:29 +05:30
parent 7ae28596ec
commit 58ce623a2c
15 changed files with 128 additions and 64 deletions

View File

@ -1,4 +1,3 @@
import { packRules } from "@casl/ability/extra";
import slugify from "@sindresorhus/slugify";
import ms from "ms";
import { z } from "zod";
@ -82,7 +81,7 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
isTemporary: false,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore-error this is valid ts
permissions: JSON.stringify(packRules(backfillPermissionV1SchemaToV2Schema(permission)))
permissions: backfillPermissionV1SchemaToV2Schema(permission)
});
return { privilege };
}
@ -164,7 +163,7 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
isTemporary: true,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore-error this is valid ts
permissions: JSON.stringify(packRules(backfillPermissionV1SchemaToV2Schema(permission)))
permissions: backfillPermissionV1SchemaToV2Schema(permission)
});
return { privilege };
}
@ -249,10 +248,12 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
projectSlug: req.body.projectSlug,
data: {
...updatedInfo,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore-error this is valid ts
permissions: permission
? // eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore-error this is valid ts
JSON.stringify(packRules(backfillPermissionV1SchemaToV2Schema(permission)))
backfillPermissionV1SchemaToV2Schema(permission)
: undefined
}
});

View File

@ -68,9 +68,10 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => {
},
data: {
...req.body,
permissions: JSON.stringify(packRules(backfillPermissionV1SchemaToV2Schema(req.body.permissions)))
permissions: JSON.stringify(packRules(backfillPermissionV1SchemaToV2Schema(req.body.permissions, true)))
}
});
return { role };
}
});
@ -129,7 +130,7 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => {
data: {
...req.body,
permissions: req.body.permissions
? JSON.stringify(packRules(backfillPermissionV1SchemaToV2Schema(req.body.permissions)))
? JSON.stringify(packRules(backfillPermissionV1SchemaToV2Schema(req.body.permissions, true)))
: undefined
}
});
@ -241,6 +242,7 @@ export const registerProjectRoleRouter = async (server: FastifyZodProvider) => {
},
roleSlug: req.params.slug
});
return { role };
}
});

View File

@ -1,4 +1,3 @@
import { packRules } from "@casl/ability/extra";
import slugify from "@sindresorhus/slugify";
import ms from "ms";
import { z } from "zod";
@ -70,7 +69,7 @@ export const registerUserAdditionalPrivilegeRouter = async (server: FastifyZodPr
projectMembershipId: req.body.projectMembershipId,
...req.body.type,
slug: req.body.slug || slugify(alphaNumericNanoId(8)),
permissions: JSON.stringify(packRules(req.body.permissions))
permissions: req.body.permissions
});
return { privilege };
}
@ -137,7 +136,7 @@ export const registerUserAdditionalPrivilegeRouter = async (server: FastifyZodPr
permissions: req.body.permissions
? // eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore-error this is valid ts
JSON.stringify(packRules(req.body.permissions))
req.body.permissions
: undefined,
privilegeId: req.params.privilegeId
});

View File

@ -1,4 +1,3 @@
import { packRules } from "@casl/ability/extra";
import slugify from "@sindresorhus/slugify";
import ms from "ms";
import { z } from "zod";
@ -78,7 +77,7 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
identityId: req.body.identityId,
...req.body.type,
slug: req.body.slug || slugify(alphaNumericNanoId(8)),
permissions: JSON.stringify(packRules(req.body.permissions))
permissions: req.body.permissions
});
return { privilege };
}
@ -149,11 +148,7 @@ export const registerIdentityProjectAdditionalPrivilegeRouter = async (server: F
data: {
...req.body,
...req.body.type,
permissions: req.body.permissions
? // eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore-error this is valid ts
JSON.stringify(packRules(req.body.permissions))
: undefined
permissions: req.body.permissions || undefined
}
});
return { privilege };

View File

@ -1,4 +1,5 @@
import { ForbiddenError } from "@casl/ability";
import { packRules } from "@casl/ability/extra";
import ms from "ms";
import { isAtLeastAsPrivileged } from "@app/lib/casl";
@ -61,14 +62,18 @@ export const identityProjectAdditionalPrivilegeV2ServiceFactory = ({
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Identity);
const { permission: identityRolePermission } = await permissionService.getProjectPermission(
const { permission: targetIdentityPermission } = await permissionService.getProjectPermission(
ActorType.IDENTITY,
identityId,
identityProjectMembership.projectId,
actorAuthMethod,
actorOrgId
);
const hasRequiredPriviledges = isAtLeastAsPrivileged(permission, identityRolePermission);
// we need to validate that the privilege given is not higher than the assigning users permission
// @ts-expect-error this is expected error because of one being really accurate rule definition other being a bit more broader. Both are valid casl rules
targetIdentityPermission.update(targetIdentityPermission.rules.concat(customPermission));
const hasRequiredPriviledges = isAtLeastAsPrivileged(permission, targetIdentityPermission);
if (!hasRequiredPriviledges)
throw new ForbiddenRequestError({ message: "Failed to update more privileged identity" });
@ -78,11 +83,12 @@ export const identityProjectAdditionalPrivilegeV2ServiceFactory = ({
});
if (existingSlug) throw new BadRequestError({ message: "Additional privilege with provided slug already exists" });
const packedPermission = JSON.stringify(packRules(customPermission));
if (!dto.isTemporary) {
const additionalPrivilege = await identityProjectAdditionalPrivilegeDAL.create({
projectMembershipId: identityProjectMembership.id,
slug,
permissions: customPermission
permissions: packedPermission
});
return {
@ -95,7 +101,7 @@ export const identityProjectAdditionalPrivilegeV2ServiceFactory = ({
const additionalPrivilege = await identityProjectAdditionalPrivilegeDAL.create({
projectMembershipId: identityProjectMembership.id,
slug,
permissions: customPermission,
permissions: packedPermission,
isTemporary: true,
temporaryMode: IdentityProjectAdditionalPrivilegeTemporaryMode.Relative,
temporaryRange: dto.temporaryRange,
@ -133,14 +139,18 @@ export const identityProjectAdditionalPrivilegeV2ServiceFactory = ({
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Identity);
const { permission: identityRolePermission } = await permissionService.getProjectPermission(
const { permission: targetIdentityPermission } = await permissionService.getProjectPermission(
ActorType.IDENTITY,
identityProjectMembership.identityId,
identityProjectMembership.projectId,
actorAuthMethod,
actorOrgId
);
const hasRequiredPriviledges = isAtLeastAsPrivileged(permission, identityRolePermission);
// we need to validate that the privilege given is not higher than the assigning users permission
// @ts-expect-error this is expected error because of one being really accurate rule definition other being a bit more broader. Both are valid casl rules
targetIdentityPermission.update(targetIdentityPermission.rules.concat(data.permissions || []));
const hasRequiredPriviledges = isAtLeastAsPrivileged(permission, targetIdentityPermission);
if (!hasRequiredPriviledges)
throw new ForbiddenRequestError({ message: "Failed to update more privileged identity" });
@ -154,12 +164,13 @@ export const identityProjectAdditionalPrivilegeV2ServiceFactory = ({
}
const isTemporary = typeof data?.isTemporary !== "undefined" ? data.isTemporary : identityPrivilege.isTemporary;
const packedPermission = data.permissions ? JSON.stringify(packRules(data.permissions)) : undefined;
if (isTemporary) {
const temporaryAccessStartTime = data?.temporaryAccessStartTime || identityPrivilege?.temporaryAccessStartTime;
const temporaryRange = data?.temporaryRange || identityPrivilege?.temporaryRange;
const additionalPrivilege = await identityProjectAdditionalPrivilegeDAL.updateById(identityPrivilege.id, {
slug: data.slug,
permissions: data.permissions,
permissions: packedPermission,
isTemporary: data.isTemporary,
temporaryRange: data.temporaryRange,
temporaryMode: data.temporaryMode,
@ -174,7 +185,7 @@ export const identityProjectAdditionalPrivilegeV2ServiceFactory = ({
const additionalPrivilege = await identityProjectAdditionalPrivilegeDAL.updateById(identityPrivilege.id, {
slug: data.slug,
permissions: data.permissions,
permissions: packedPermission,
isTemporary: false,
temporaryAccessStartTime: null,
temporaryAccessEndTime: null,

View File

@ -1,11 +1,13 @@
import { TProjectPermission } from "@app/lib/types";
import { TProjectPermissionV2Schema } from "../permission/project-permission";
export enum IdentityProjectAdditionalPrivilegeTemporaryMode {
Relative = "relative"
}
export type TCreateIdentityPrivilegeDTO = {
permissions: unknown;
permissions: TProjectPermissionV2Schema[];
identityId: string;
projectId: string;
slug: string;
@ -24,7 +26,7 @@ export type TCreateIdentityPrivilegeDTO = {
export type TUpdateIdentityPrivilegeByIdDTO = { id: string } & Omit<TProjectPermission, "projectId"> & {
data: Partial<{
permissions: unknown;
permissions: TProjectPermissionV2Schema[];
slug: string;
isTemporary: boolean;
temporaryMode: IdentityProjectAdditionalPrivilegeTemporaryMode.Relative;

View File

@ -1,5 +1,5 @@
import { ForbiddenError, MongoAbility, RawRuleOf } from "@casl/ability";
import { PackRule, unpackRules } from "@casl/ability/extra";
import { PackRule, packRules, unpackRules } from "@casl/ability/extra";
import ms from "ms";
import { isAtLeastAsPrivileged } from "@app/lib/casl";
@ -70,14 +70,18 @@ export const identityProjectAdditionalPrivilegeServiceFactory = ({
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Identity);
const { permission: identityRolePermission } = await permissionService.getProjectPermission(
const { permission: targetIdentityPermission } = await permissionService.getProjectPermission(
ActorType.IDENTITY,
identityId,
identityProjectMembership.projectId,
actorAuthMethod,
actorOrgId
);
const hasRequiredPriviledges = isAtLeastAsPrivileged(permission, identityRolePermission);
// we need to validate that the privilege given is not higher than the assigning users permission
// @ts-expect-error this is expected error because of one being really accurate rule definition other being a bit more broader. Both are valid casl rules
targetIdentityPermission.update(targetIdentityPermission.rules.concat(customPermission));
const hasRequiredPriviledges = isAtLeastAsPrivileged(permission, targetIdentityPermission);
if (!hasRequiredPriviledges)
throw new ForbiddenRequestError({ message: "Failed to update more privileged identity" });
@ -87,11 +91,12 @@ export const identityProjectAdditionalPrivilegeServiceFactory = ({
});
if (existingSlug) throw new BadRequestError({ message: "Additional privilege of provided slug exist" });
const packedPermission = JSON.stringify(packRules(customPermission));
if (!dto.isTemporary) {
const additionalPrivilege = await identityProjectAdditionalPrivilegeDAL.create({
projectMembershipId: identityProjectMembership.id,
slug,
permissions: customPermission
permissions: packedPermission
});
return {
...additionalPrivilege,
@ -103,7 +108,7 @@ export const identityProjectAdditionalPrivilegeServiceFactory = ({
const additionalPrivilege = await identityProjectAdditionalPrivilegeDAL.create({
projectMembershipId: identityProjectMembership.id,
slug,
permissions: customPermission,
permissions: packedPermission,
isTemporary: true,
temporaryMode: IdentityProjectAdditionalPrivilegeTemporaryMode.Relative,
temporaryRange: dto.temporaryRange,
@ -142,14 +147,19 @@ export const identityProjectAdditionalPrivilegeServiceFactory = ({
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Identity);
const { permission: identityRolePermission } = await permissionService.getProjectPermission(
const { permission: targetIdentityPermission } = await permissionService.getProjectPermission(
ActorType.IDENTITY,
identityProjectMembership.identityId,
identityProjectMembership.projectId,
actorAuthMethod,
actorOrgId
);
const hasRequiredPriviledges = isAtLeastAsPrivileged(permission, identityRolePermission);
// we need to validate that the privilege given is not higher than the assigning users permission
// @ts-expect-error this is expected error because of one being really accurate rule definition other being a bit more broader. Both are valid casl rules
targetIdentityPermission.update(targetIdentityPermission.rules.concat(data.permissions || []));
const hasRequiredPriviledges = isAtLeastAsPrivileged(permission, targetIdentityPermission);
if (!hasRequiredPriviledges)
throw new ForbiddenRequestError({ message: "Failed to update more privileged identity" });
@ -172,23 +182,29 @@ export const identityProjectAdditionalPrivilegeServiceFactory = ({
}
const isTemporary = typeof data?.isTemporary !== "undefined" ? data.isTemporary : identityPrivilege.isTemporary;
const packedPermission = data.permissions ? JSON.stringify(packRules(data.permissions)) : undefined;
if (isTemporary) {
const temporaryAccessStartTime = data?.temporaryAccessStartTime || identityPrivilege?.temporaryAccessStartTime;
const temporaryRange = data?.temporaryRange || identityPrivilege?.temporaryRange;
const additionalPrivilege = await identityProjectAdditionalPrivilegeDAL.updateById(identityPrivilege.id, {
...data,
slug: data.slug,
permissions: packedPermission,
isTemporary: data.isTemporary,
temporaryRange: data.temporaryRange,
temporaryMode: data.temporaryMode,
temporaryAccessStartTime: new Date(temporaryAccessStartTime || ""),
temporaryAccessEndTime: new Date(new Date(temporaryAccessStartTime || "").getTime() + ms(temporaryRange || ""))
});
return {
...additionalPrivilege,
permissions: unpackPermissions(additionalPrivilege.permissions)
};
}
const additionalPrivilege = await identityProjectAdditionalPrivilegeDAL.updateById(identityPrivilege.id, {
...data,
slug: data.slug,
permissions: packedPermission,
isTemporary: false,
temporaryAccessStartTime: null,
temporaryAccessEndTime: null,

View File

@ -1,11 +1,13 @@
import { TProjectPermission } from "@app/lib/types";
import { TProjectPermissionV2Schema } from "../permission/project-permission";
export enum IdentityProjectAdditionalPrivilegeTemporaryMode {
Relative = "relative"
}
export type TCreateIdentityPrivilegeDTO = {
permissions: unknown;
permissions: TProjectPermissionV2Schema[];
identityId: string;
projectSlug: string;
slug: string;
@ -27,7 +29,7 @@ export type TUpdateIdentityPrivilegeDTO = { slug: string; identityId: string; pr
"projectId"
> & {
data: Partial<{
permissions: unknown;
permissions: TProjectPermissionV2Schema[];
slug: string;
isTemporary: boolean;
temporaryMode: IdentityProjectAdditionalPrivilegeTemporaryMode.Relative;

View File

@ -21,7 +21,7 @@ export const getDefaultOnPremFeatures = (): TFeatureSet => ({
secretVersioning: true,
pitRecovery: false,
ipAllowlisting: false,
rbac: false,
rbac: true,
customRateLimits: false,
customAlerts: false,
auditLogs: false,

View File

@ -420,6 +420,8 @@ export const ProjectPermissionV2Schema = z.discriminatedUnion("subject", [
...GeneralPermissionSchema
]);
export type TProjectPermissionV2Schema = z.infer<typeof ProjectPermissionV2Schema>;
const buildAdminPermissionRules = () => {
const { can, rules } = new AbilityBuilder<MongoAbility<ProjectPermissionSet>>(createMongoAbility);
@ -757,8 +759,11 @@ export const isAtLeastAsPrivilegedWorkspace = (
};
/* eslint-enable */
export const backfillPermissionV1SchemaToV2Schema = (data: z.infer<typeof ProjectPermissionV1Schema>[]) => {
const formattedData = UnpackedPermissionSchema.array().parse(data);
export const backfillPermissionV1SchemaToV2Schema = (
data: z.infer<typeof ProjectPermissionV1Schema>[],
dontRemoveReadFolderPermission?: boolean
) => {
let formattedData = UnpackedPermissionSchema.array().parse(data);
const secretSubjects = formattedData.filter((el) => el.subject === ProjectPermissionSub.Secrets);
// this means the folder permission as readonly is set
@ -802,13 +807,15 @@ export const backfillPermissionV1SchemaToV2Schema = (data: z.infer<typeof Projec
};
});
return formattedData
.filter((i) => i.subject !== ProjectPermissionSub.SecretFolders)
.concat(
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore-error this is valid ts
secretImportPolicies,
dynamicSecretPolicies,
hasReadOnlyFolder.length ? [] : secretFolderPolicies
);
if (!dontRemoveReadFolderPermission) {
formattedData = formattedData.filter((i) => i.subject !== ProjectPermissionSub.SecretFolders);
}
return formattedData.concat(
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore-error this is valid ts
secretImportPolicies,
dynamicSecretPolicies,
hasReadOnlyFolder.length ? [] : secretFolderPolicies
);
};

View File

@ -1,5 +1,5 @@
import { ForbiddenError, MongoAbility, RawRuleOf } from "@casl/ability";
import { PackRule, unpackRules } from "@casl/ability/extra";
import { PackRule, packRules, unpackRules } from "@casl/ability/extra";
import ms from "ms";
import { isAtLeastAsPrivileged } from "@app/lib/casl";
@ -62,14 +62,18 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Member);
const { permission: entityPermission } = await permissionService.getProjectPermission(
const { permission: targetUserPermission } = await permissionService.getProjectPermission(
ActorType.USER,
projectMembership.userId,
projectMembership.projectId,
actorAuthMethod,
actorOrgId
);
const hasRequiredPriviledges = isAtLeastAsPrivileged(permission, entityPermission);
// we need to validate that the privilege given is not higher than the assigning users permission
// @ts-expect-error this is expected error because of one being really accurate rule definition other being a bit more broader. Both are valid casl rules
targetUserPermission.update(targetUserPermission.rules.concat(customPermission));
const hasRequiredPriviledges = isAtLeastAsPrivileged(permission, targetUserPermission);
if (!hasRequiredPriviledges)
throw new ForbiddenRequestError({ message: "Failed to update more privileged identity" });
@ -81,12 +85,13 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({
if (existingSlug)
throw new BadRequestError({ message: `Additional privilege with provided slug ${slug} already exists` });
const packedPermission = JSON.stringify(packRules(customPermission));
if (!dto.isTemporary) {
const additionalPrivilege = await projectUserAdditionalPrivilegeDAL.create({
userId: projectMembership.userId,
projectId: projectMembership.projectId,
slug,
permissions: customPermission
permissions: packedPermission
});
return {
...additionalPrivilege,
@ -99,7 +104,7 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({
projectId: projectMembership.projectId,
userId: projectMembership.userId,
slug,
permissions: customPermission,
permissions: packedPermission,
isTemporary: true,
temporaryMode: ProjectUserAdditionalPrivilegeTemporaryMode.Relative,
temporaryRange: dto.temporaryRange,
@ -142,14 +147,18 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({
actorOrgId
);
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.Member);
const { permission: entityPermission } = await permissionService.getProjectPermission(
const { permission: targetUserPermission } = await permissionService.getProjectPermission(
ActorType.USER,
projectMembership.userId,
projectMembership.projectId,
actorAuthMethod,
actorOrgId
);
const hasRequiredPriviledges = isAtLeastAsPrivileged(permission, entityPermission);
// we need to validate that the privilege given is not higher than the assigning users permission
// @ts-expect-error this is expected error because of one being really accurate rule definition other being a bit more broader. Both are valid casl rules
targetUserPermission.update(targetUserPermission.rules.concat(dto.permissions || []));
const hasRequiredPriviledges = isAtLeastAsPrivileged(permission, targetUserPermission);
if (!hasRequiredPriviledges)
throw new ForbiddenRequestError({ message: "Failed to update more privileged identity" });
@ -164,12 +173,14 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({
}
const isTemporary = typeof dto?.isTemporary !== "undefined" ? dto.isTemporary : userPrivilege.isTemporary;
const packedPermission = dto.permissions && JSON.stringify(packRules(dto.permissions));
if (isTemporary) {
const temporaryAccessStartTime = dto?.temporaryAccessStartTime || userPrivilege?.temporaryAccessStartTime;
const temporaryRange = dto?.temporaryRange || userPrivilege?.temporaryRange;
const additionalPrivilege = await projectUserAdditionalPrivilegeDAL.updateById(userPrivilege.id, {
slug: dto.slug,
permissions: dto.permissions,
permissions: packedPermission,
isTemporary: dto.isTemporary,
temporaryRange: dto.temporaryRange,
temporaryMode: dto.temporaryMode,
@ -185,7 +196,7 @@ export const projectUserAdditionalPrivilegeServiceFactory = ({
const additionalPrivilege = await projectUserAdditionalPrivilegeDAL.updateById(userPrivilege.id, {
slug: dto.slug,
permissions: dto.permissions,
permissions: packedPermission,
isTemporary: false,
temporaryAccessStartTime: null,
temporaryAccessEndTime: null,

View File

@ -1,18 +1,20 @@
import { TProjectPermission } from "@app/lib/types";
import { TProjectPermissionV2Schema } from "../permission/project-permission";
export enum ProjectUserAdditionalPrivilegeTemporaryMode {
Relative = "relative"
}
export type TCreateUserPrivilegeDTO = (
| {
permissions: unknown;
permissions: TProjectPermissionV2Schema[];
projectMembershipId: string;
slug: string;
isTemporary: false;
}
| {
permissions: unknown;
permissions: TProjectPermissionV2Schema[];
projectMembershipId: string;
slug: string;
isTemporary: true;
@ -25,7 +27,7 @@ export type TCreateUserPrivilegeDTO = (
export type TUpdateUserPrivilegeDTO = { privilegeId: string } & Omit<TProjectPermission, "projectId"> &
Partial<{
permissions: unknown;
permissions: TProjectPermissionV2Schema[];
slug: string;
isTemporary: boolean;
temporaryMode: ProjectUserAdditionalPrivilegeTemporaryMode.Relative;

View File

@ -7,6 +7,7 @@ import { TLicenseServiceFactory } from "@app/ee/services/license/license-service
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
import { TProjectUserAdditionalPrivilegeDALFactory } from "@app/ee/services/project-user-additional-privilege/project-user-additional-privilege-dal";
import { isAtLeastAsPrivileged } from "@app/lib/casl";
import { getConfig } from "@app/lib/config/env";
import { BadRequestError, ForbiddenRequestError, NotFoundError } from "@app/lib/errors";
import { groupBy } from "@app/lib/fn";
@ -36,7 +37,7 @@ import {
import { TProjectUserMembershipRoleDALFactory } from "./project-user-membership-role-dal";
type TProjectMembershipServiceFactoryDep = {
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission" | "getProjectPermissionByRole">;
smtpService: TSmtpService;
projectBotDAL: TProjectBotDALFactory;
projectMembershipDAL: TProjectMembershipDALFactory;
@ -262,6 +263,21 @@ export const projectMembershipServiceFactory = ({
throw new ForbiddenRequestError({ message: "Forbidden member update" });
}
for await (const { role: requestedRoleChange } of roles) {
const { permission: rolePermission } = await permissionService.getProjectPermissionByRole(
requestedRoleChange,
projectId
);
const hasRequiredPriviledges = isAtLeastAsPrivileged(permission, rolePermission);
if (!hasRequiredPriviledges) {
throw new ForbiddenRequestError({
message: `Failed to change to a more privileged role ${requestedRoleChange}`
});
}
}
// validate custom roles input
const customInputRoles = roles.filter(
({ role }) => !Object.values(ProjectMembershipRole).includes(role as ProjectMembershipRole)

View File

@ -94,7 +94,6 @@ export const MembershipProjectAdditionalPrivilegeModifySection = ({
privilegeId || ""
);
console.log(privilegeDetails);
const { permission } = useProjectPermission();
const isMemberEditDisabled = permission.cannot(
ProjectPermissionActions.Edit,

View File

@ -179,6 +179,7 @@ export const rolePermission2Form = (permissions: TProjectPermission[] = []) => {
permissions.forEach((permission) => {
const { subject: caslSub, action, conditions, inverted } = permission;
const subject = (typeof caslSub === "string" ? caslSub : caslSub[0]) as ProjectPermissionSub;
if (!action.length) return;
if (
[