import { useMemo } from "react"; import { FormProvider, useForm } from "react-hook-form"; import { MongoAbility, MongoQuery, RawRuleOf } from "@casl/ability"; import { faSave } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { zodResolver } from "@hookform/resolvers/zod"; import { twMerge } from "tailwind-merge"; import { createNotification } from "@app/components/notifications"; import { AccessTree } from "@app/components/permissions"; import { Button } from "@app/components/v2"; import { ProjectPermissionSub, useWorkspace } from "@app/context"; import { ProjectPermissionSet } from "@app/context/ProjectPermissionContext"; import { evaluatePermissionsAbility } from "@app/helpers/permissions"; import { useGetProjectRoleBySlug, useUpdateProjectRole } from "@app/hooks/api"; import { ProjectMembershipRole } from "@app/hooks/api/roles/types"; import { ProjectType } from "@app/hooks/api/workspace/types"; import { AddPoliciesButton } from "./AddPoliciesButton"; import { DynamicSecretPermissionConditions } from "./DynamicSecretPermissionConditions"; import { GeneralPermissionConditions } from "./GeneralPermissionConditions"; import { GeneralPermissionPolicies } from "./GeneralPermissionPolicies"; import { IdentityManagementPermissionConditions } from "./IdentityManagementPermissionConditions"; import { PermissionEmptyState } from "./PermissionEmptyState"; import { PkiSubscriberPermissionConditions } from "./PkiSubscriberPermissionConditions"; import { PkiTemplatePermissionConditions } from "./PkiTemplatePermissionConditions"; import { formRolePermission2API, isConditionalSubjects, PROJECT_PERMISSION_OBJECT, projectRoleFormSchema, ProjectTypePermissionSubjects, rolePermission2Form, TFormSchema } from "./ProjectRoleModifySection.utils"; import { SecretPermissionConditions } from "./SecretPermissionConditions"; import { SshHostPermissionConditions } from "./SshHostPermissionConditions"; type Props = { roleSlug: string; isDisabled?: boolean; }; export const renderConditionalComponents = ( subject: ProjectPermissionSub, isDisabled?: boolean ) => { if (subject === ProjectPermissionSub.Secrets) return ; if (subject === ProjectPermissionSub.DynamicSecrets) return ; if (isConditionalSubjects(subject)) { if (subject === ProjectPermissionSub.Identity) { return ; } if (subject === ProjectPermissionSub.SshHosts) { return ; } if (subject === ProjectPermissionSub.PkiSubscribers) { return ; } if (subject === ProjectPermissionSub.CertificateTemplates) { return ; } return ; } return undefined; }; export const RolePermissionsSection = ({ roleSlug, isDisabled }: Props) => { const { currentWorkspace } = useWorkspace(); const projectId = currentWorkspace?.id || ""; const { data: role, isPending } = useGetProjectRoleBySlug( currentWorkspace?.id ?? "", roleSlug as string ); const form = useForm({ values: role ? { ...role, permissions: rolePermission2Form(role.permissions) } : undefined, resolver: zodResolver(projectRoleFormSchema) }); const { handleSubmit, formState: { isDirty, isSubmitting }, reset } = form; const { mutateAsync: updateRole } = useUpdateProjectRole(); const onSubmit = async (el: TFormSchema) => { try { if (!projectId || !role?.id) return; await updateRole({ id: role?.id as string, projectId, ...el, permissions: formRolePermission2API(el.permissions) }); createNotification({ type: "success", text: "Successfully updated role" }); } catch (err) { console.log(err); createNotification({ type: "error", text: "Failed to update role" }); } }; const isCustomRole = !Object.values(ProjectMembershipRole).includes( (role?.slug ?? "") as ProjectMembershipRole ); const permissions = form.watch("permissions"); const formattedPermissions = useMemo( () => evaluatePermissionsAbility( formRolePermission2API(permissions) as RawRuleOf< MongoAbility >[] ), [JSON.stringify(permissions)] ); return (
{currentWorkspace.type === ProjectType.SecretManager && ( )}

Policies

{isCustomRole && ( <> {isDirty && ( )}
)}
{!isPending && } {(Object.keys(PROJECT_PERMISSION_OBJECT) as ProjectPermissionSub[]) .filter((subject) => ProjectTypePermissionSubjects[currentWorkspace.type][subject]) .map((subject) => ( {renderConditionalComponents(subject, isDisabled)} ))}
); };