diff --git a/backend/src/ee/services/permission/project-permission.ts b/backend/src/ee/services/permission/project-permission.ts index 1cce302a4..c5c731dc7 100644 --- a/backend/src/ee/services/permission/project-permission.ts +++ b/backend/src/ee/services/permission/project-permission.ts @@ -473,7 +473,7 @@ export const ProjectPermissionV1Schema = z.discriminatedUnion("subject", [ }), z.object({ subject: z.literal(ProjectPermissionSub.Identity).describe("The entity this permission pertains to."), - action: CASL_ACTION_SCHEMA_NATIVE_ENUM(ProjectPermissionIdentityActions).describe( + action: CASL_ACTION_SCHEMA_NATIVE_ENUM(ProjectPermissionActions).describe( "Describe what action an entity can take." ) }), @@ -524,7 +524,7 @@ export const ProjectPermissionV2Schema = z.discriminatedUnion("subject", [ z.object({ subject: z.literal(ProjectPermissionSub.Identity).describe("The entity this permission pertains to."), inverted: z.boolean().optional().describe("Whether rule allows or forbids."), - action: CASL_ACTION_SCHEMA_NATIVE_ENUM(ProjectPermissionActions).describe( + action: CASL_ACTION_SCHEMA_NATIVE_ENUM(ProjectPermissionIdentityActions).describe( "Describe what action an entity can take." ), conditions: IdentityManagementConditionSchema.describe( diff --git a/frontend/src/context/ProjectPermissionContext/types.ts b/frontend/src/context/ProjectPermissionContext/types.ts index d368a949f..6d274734e 100644 --- a/frontend/src/context/ProjectPermissionContext/types.ts +++ b/frontend/src/context/ProjectPermissionContext/types.ts @@ -42,6 +42,30 @@ export enum ProjectPermissionSecretSyncActions { RemoveSecrets = "remove-secrets" } +export enum ProjectPermissionIdentityActions { + Read = "read", + Create = "create", + Edit = "edit", + Delete = "delete", + ManagePrivileges = "manage-privileges" +} + +export enum ProjectPermissionMemberActions { + Read = "read", + Create = "create", + Edit = "edit", + Delete = "delete", + ManagePrivileges = "manage-privileges" +} + +export enum ProjectPermissionGroupActions { + Read = "read", + Create = "create", + Edit = "edit", + Delete = "delete", + ManagePrivileges = "manage-privileges" +} + export enum PermissionConditionOperators { $IN = "$in", $ALL = "$all", diff --git a/frontend/src/pages/project/RoleDetailsBySlugPage/components/ProjectRoleModifySection.utils.tsx b/frontend/src/pages/project/RoleDetailsBySlugPage/components/ProjectRoleModifySection.utils.tsx index 7dcb118fd..c1dfb51b6 100644 --- a/frontend/src/pages/project/RoleDetailsBySlugPage/components/ProjectRoleModifySection.utils.tsx +++ b/frontend/src/pages/project/RoleDetailsBySlugPage/components/ProjectRoleModifySection.utils.tsx @@ -8,7 +8,10 @@ import { import { PermissionConditionOperators, ProjectPermissionDynamicSecretActions, + ProjectPermissionGroupActions, + ProjectPermissionIdentityActions, ProjectPermissionKmipActions, + ProjectPermissionMemberActions, ProjectPermissionSecretSyncActions, TPermissionCondition, TPermissionConditionOperators @@ -57,6 +60,30 @@ const KmipPolicyActionSchema = z.object({ [ProjectPermissionKmipActions.GenerateClientCertificates]: z.boolean().optional() }); +const MemberPolicyActionSchema = z.object({ + [ProjectPermissionMemberActions.Read]: z.boolean().optional(), + [ProjectPermissionMemberActions.Create]: z.boolean().optional(), + [ProjectPermissionMemberActions.Edit]: z.boolean().optional(), + [ProjectPermissionMemberActions.Delete]: z.boolean().optional(), + [ProjectPermissionMemberActions.ManagePrivileges]: z.boolean().optional() +}); + +const IdentityPolicyActionSchema = z.object({ + [ProjectPermissionIdentityActions.Read]: z.boolean().optional(), + [ProjectPermissionIdentityActions.Create]: z.boolean().optional(), + [ProjectPermissionIdentityActions.Edit]: z.boolean().optional(), + [ProjectPermissionIdentityActions.Delete]: z.boolean().optional(), + [ProjectPermissionIdentityActions.ManagePrivileges]: z.boolean().optional() +}); + +const GroupPolicyActionSchema = z.object({ + [ProjectPermissionGroupActions.Read]: z.boolean().optional(), + [ProjectPermissionGroupActions.Create]: z.boolean().optional(), + [ProjectPermissionGroupActions.Edit]: z.boolean().optional(), + [ProjectPermissionGroupActions.Delete]: z.boolean().optional(), + [ProjectPermissionGroupActions.ManagePrivileges]: z.boolean().optional() +}); + const SecretRollbackPolicyActionSchema = z.object({ read: z.boolean().optional(), create: z.boolean().optional() @@ -138,14 +165,14 @@ export const projectRoleFormSchema = z.object({ }) .array() .default([]), - [ProjectPermissionSub.Identity]: GeneralPolicyActionSchema.extend({ + [ProjectPermissionSub.Identity]: IdentityPolicyActionSchema.extend({ inverted: z.boolean().optional(), conditions: ConditionSchema }) .array() .default([]), - [ProjectPermissionSub.Member]: GeneralPolicyActionSchema.array().default([]), - [ProjectPermissionSub.Groups]: GeneralPolicyActionSchema.array().default([]), + [ProjectPermissionSub.Member]: MemberPolicyActionSchema.array().default([]), + [ProjectPermissionSub.Groups]: GroupPolicyActionSchema.array().default([]), [ProjectPermissionSub.Role]: GeneralPolicyActionSchema.array().default([]), [ProjectPermissionSub.Integrations]: GeneralPolicyActionSchema.array().default([]), [ProjectPermissionSub.Webhooks]: GeneralPolicyActionSchema.array().default([]), @@ -234,9 +261,6 @@ export const rolePermission2Form = (permissions: TProjectPermission[] = []) => { ProjectPermissionSub.DynamicSecrets, ProjectPermissionSub.SecretFolders, ProjectPermissionSub.SecretImports, - ProjectPermissionSub.Member, - ProjectPermissionSub.Groups, - ProjectPermissionSub.Identity, ProjectPermissionSub.Role, ProjectPermissionSub.Integrations, ProjectPermissionSub.Webhooks, @@ -391,6 +415,65 @@ export const rolePermission2Form = (permissions: TProjectPermission[] = []) => { return; } + if (subject === ProjectPermissionSub.Member) { + const canRead = action.includes(ProjectPermissionMemberActions.Read); + const canCreate = action.includes(ProjectPermissionMemberActions.Create); + const canEdit = action.includes(ProjectPermissionMemberActions.Edit); + const canDelete = action.includes(ProjectPermissionMemberActions.Delete); + const canManagePrivileges = action.includes(ProjectPermissionMemberActions.ManagePrivileges); + + if (!formVal[subject]) formVal[subject] = [{}]; + + // from above statement we are sure it won't be undefined + if (canRead) formVal[subject]![0][ProjectPermissionMemberActions.Read] = true; + if (canCreate) formVal[subject]![0][ProjectPermissionMemberActions.Create] = true; + if (canEdit) formVal[subject]![0][ProjectPermissionMemberActions.Edit] = true; + if (canDelete) formVal[subject]![0][ProjectPermissionMemberActions.Delete] = true; + if (canManagePrivileges) + formVal[subject]![0][ProjectPermissionMemberActions.ManagePrivileges] = true; + return; + } + + if (subject === ProjectPermissionSub.Identity) { + const canRead = action.includes(ProjectPermissionIdentityActions.Read); + const canCreate = action.includes(ProjectPermissionIdentityActions.Create); + const canEdit = action.includes(ProjectPermissionIdentityActions.Edit); + const canDelete = action.includes(ProjectPermissionIdentityActions.Delete); + const canManagePrivileges = action.includes( + ProjectPermissionIdentityActions.ManagePrivileges + ); + + if (!formVal[subject]) formVal[subject] = [{ conditions: [] }]; + + // from above statement we are sure it won't be undefined + if (canRead) formVal[subject]![0][ProjectPermissionIdentityActions.Read] = true; + if (canCreate) formVal[subject]![0][ProjectPermissionIdentityActions.Create] = true; + if (canEdit) formVal[subject]![0][ProjectPermissionIdentityActions.Edit] = true; + if (canDelete) formVal[subject]![0][ProjectPermissionIdentityActions.Delete] = true; + if (canManagePrivileges) + formVal[subject]![0][ProjectPermissionIdentityActions.ManagePrivileges] = true; + return; + } + + if (subject === ProjectPermissionSub.Groups) { + const canRead = action.includes(ProjectPermissionGroupActions.Read); + const canCreate = action.includes(ProjectPermissionGroupActions.Create); + const canEdit = action.includes(ProjectPermissionGroupActions.Edit); + const canDelete = action.includes(ProjectPermissionGroupActions.Delete); + const canManagePrivileges = action.includes(ProjectPermissionGroupActions.ManagePrivileges); + + if (!formVal[subject]) formVal[subject] = [{}]; + + // from above statement we are sure it won't be undefined + if (canRead) formVal[subject]![0][ProjectPermissionGroupActions.Read] = true; + if (canCreate) formVal[subject]![0][ProjectPermissionGroupActions.Create] = true; + if (canEdit) formVal[subject]![0][ProjectPermissionGroupActions.Edit] = true; + if (canDelete) formVal[subject]![0][ProjectPermissionGroupActions.Delete] = true; + if (canManagePrivileges) + formVal[subject]![0][ProjectPermissionGroupActions.ManagePrivileges] = true; + return; + } + if (subject === ProjectPermissionSub.SecretSyncs) { const canRead = action.includes(ProjectPermissionSecretSyncActions.Read); const canEdit = action.includes(ProjectPermissionSecretSyncActions.Edit); @@ -571,28 +654,31 @@ export const PROJECT_PERMISSION_OBJECT: TProjectPermissionObject = { [ProjectPermissionSub.Member]: { title: "User Management", actions: [ - { label: "View all members", value: "read" }, - { label: "Invite members", value: "create" }, - { label: "Edit members", value: "edit" }, - { label: "Remove members", value: "delete" } + { label: "Read", value: ProjectPermissionMemberActions.Read }, + { label: "Add", value: ProjectPermissionMemberActions.Create }, + { label: "Modify", value: ProjectPermissionMemberActions.Edit }, + { label: "Remove", value: ProjectPermissionMemberActions.Delete }, + { label: "Manage Privileges", value: ProjectPermissionMemberActions.ManagePrivileges } ] }, [ProjectPermissionSub.Identity]: { title: "Machine Identity Management", actions: [ - { label: "Read", value: "read" }, - { label: "Add", value: "create" }, - { label: "Modify", value: "edit" }, - { label: "Remove", value: "delete" } + { label: "Read", value: ProjectPermissionIdentityActions.Read }, + { label: "Add", value: ProjectPermissionIdentityActions.Create }, + { label: "Modify", value: ProjectPermissionIdentityActions.Edit }, + { label: "Remove", value: ProjectPermissionIdentityActions.Delete }, + { label: "Manage Privileges", value: ProjectPermissionIdentityActions.ManagePrivileges } ] }, [ProjectPermissionSub.Groups]: { title: "Group Management", actions: [ - { label: "Read", value: "read" }, - { label: "Create", value: "create" }, - { label: "Modify", value: "edit" }, - { label: "Remove", value: "delete" } + { label: "Read", value: ProjectPermissionGroupActions.Read }, + { label: "Create", value: ProjectPermissionGroupActions.Create }, + { label: "Modify", value: ProjectPermissionGroupActions.Edit }, + { label: "Remove", value: ProjectPermissionGroupActions.Delete }, + { label: "Manage Privileges", value: ProjectPermissionGroupActions.ManagePrivileges } ] }, [ProjectPermissionSub.Webhooks]: {