mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-19 17:32:37 +00:00
improvements: refactor project templates, filter policies by project type, project type specific roles
This commit is contained in:
@@ -17,6 +17,7 @@ import {
|
||||
} from "@app/components/v2";
|
||||
import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@app/context";
|
||||
import { useDeleteProjectRole, useGetProjectRoleBySlug } from "@app/hooks/api";
|
||||
import { ProjectMembershipRole } from "@app/hooks/api/roles/types";
|
||||
import { usePopUp } from "@app/hooks/usePopUp";
|
||||
import { ProjectAccessControlTabs } from "@app/types/project";
|
||||
|
||||
@@ -77,7 +78,9 @@ const Page = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const isCustomRole = !["admin", "member", "viewer", "no-access"].includes(data?.slug ?? "");
|
||||
const isCustomRole = !Object.values(ProjectMembershipRole).includes(
|
||||
(data?.slug ?? "") as ProjectMembershipRole
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="container mx-auto flex flex-col justify-between bg-bunker-800 text-white">
|
||||
|
||||
+86
-1
@@ -25,6 +25,7 @@ import {
|
||||
TPermissionConditionOperators
|
||||
} from "@app/context/ProjectPermissionContext/types";
|
||||
import { TProjectPermission } from "@app/hooks/api/roles/types";
|
||||
import { ProjectType } from "@app/hooks/api/workspace/types";
|
||||
|
||||
const GeneralPolicyActionSchema = z.object({
|
||||
read: z.boolean().optional(),
|
||||
@@ -1122,7 +1123,7 @@ export const PROJECT_PERMISSION_OBJECT: TProjectPermissionObject = {
|
||||
]
|
||||
},
|
||||
[ProjectPermissionSub.SecretApproval]: {
|
||||
title: "Secret Protect policy",
|
||||
title: "Secret Approval Policies",
|
||||
actions: [
|
||||
{ label: "Read", value: "read" },
|
||||
{ label: "Create", value: "create" },
|
||||
@@ -1195,3 +1196,87 @@ export const PROJECT_PERMISSION_OBJECT: TProjectPermissionObject = {
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
const SharedPermissionSubjects = {
|
||||
[ProjectPermissionSub.AuditLogs]: true,
|
||||
[ProjectPermissionSub.Groups]: true,
|
||||
[ProjectPermissionSub.Member]: true,
|
||||
[ProjectPermissionSub.Identity]: true,
|
||||
[ProjectPermissionSub.Project]: true,
|
||||
[ProjectPermissionSub.Role]: true,
|
||||
[ProjectPermissionSub.Settings]: true
|
||||
};
|
||||
|
||||
const SecretsManagerPermissionSubjects = (enabled = false) => ({
|
||||
[ProjectPermissionSub.SecretFolders]: enabled,
|
||||
[ProjectPermissionSub.SecretImports]: enabled,
|
||||
[ProjectPermissionSub.DynamicSecrets]: enabled,
|
||||
[ProjectPermissionSub.Secrets]: enabled,
|
||||
[ProjectPermissionSub.SecretApproval]: enabled,
|
||||
[ProjectPermissionSub.Integrations]: enabled,
|
||||
[ProjectPermissionSub.SecretSyncs]: enabled,
|
||||
[ProjectPermissionSub.Kms]: enabled,
|
||||
[ProjectPermissionSub.Environments]: enabled,
|
||||
[ProjectPermissionSub.Tags]: enabled,
|
||||
[ProjectPermissionSub.Webhooks]: enabled,
|
||||
[ProjectPermissionSub.IpAllowList]: enabled,
|
||||
[ProjectPermissionSub.SecretRollback]: enabled,
|
||||
[ProjectPermissionSub.SecretRotation]: enabled,
|
||||
[ProjectPermissionSub.ServiceTokens]: enabled
|
||||
});
|
||||
|
||||
const KmsPermissionSubjects = (enabled = false) => ({
|
||||
[ProjectPermissionSub.Cmek]: enabled,
|
||||
[ProjectPermissionSub.Kmip]: enabled
|
||||
});
|
||||
|
||||
const CertificateManagerPermissionSubjects = (enabled = false) => ({
|
||||
[ProjectPermissionSub.PkiCollections]: enabled,
|
||||
[ProjectPermissionSub.PkiAlerts]: enabled,
|
||||
[ProjectPermissionSub.CertificateAuthorities]: enabled,
|
||||
[ProjectPermissionSub.CertificateTemplates]: enabled,
|
||||
[ProjectPermissionSub.Certificates]: enabled
|
||||
});
|
||||
|
||||
const SshPermissionSubjects = (enabled = false) => ({
|
||||
[ProjectPermissionSub.SshCertificateAuthorities]: enabled,
|
||||
[ProjectPermissionSub.SshCertificates]: enabled,
|
||||
[ProjectPermissionSub.SshCertificateTemplates]: enabled,
|
||||
[ProjectPermissionSub.SshHosts]: enabled,
|
||||
[ProjectPermissionSub.SshHostGroups]: enabled
|
||||
});
|
||||
|
||||
// scott: this structure ensures we don't forget to add project permissions to their relevant project type
|
||||
export const ProjectTypePermissionSubjects: Record<
|
||||
ProjectType,
|
||||
Record<ProjectPermissionSub, boolean>
|
||||
> = {
|
||||
[ProjectType.SecretManager]: {
|
||||
...SharedPermissionSubjects,
|
||||
...SecretsManagerPermissionSubjects(true),
|
||||
...KmsPermissionSubjects(),
|
||||
...CertificateManagerPermissionSubjects(),
|
||||
...SshPermissionSubjects()
|
||||
},
|
||||
[ProjectType.KMS]: {
|
||||
...SharedPermissionSubjects,
|
||||
...KmsPermissionSubjects(true),
|
||||
...SecretsManagerPermissionSubjects(),
|
||||
...CertificateManagerPermissionSubjects(),
|
||||
...SshPermissionSubjects()
|
||||
},
|
||||
[ProjectType.CertificateManager]: {
|
||||
...SharedPermissionSubjects,
|
||||
...CertificateManagerPermissionSubjects(true),
|
||||
...KmsPermissionSubjects(),
|
||||
...SecretsManagerPermissionSubjects(),
|
||||
...SshPermissionSubjects()
|
||||
},
|
||||
[ProjectType.SSH]: {
|
||||
...SharedPermissionSubjects,
|
||||
...SshPermissionSubjects(true),
|
||||
...CertificateManagerPermissionSubjects(),
|
||||
...KmsPermissionSubjects(),
|
||||
...SecretsManagerPermissionSubjects()
|
||||
}
|
||||
};
|
||||
|
||||
@@ -6,6 +6,7 @@ import { IconButton, Tooltip } from "@app/components/v2";
|
||||
import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@app/context";
|
||||
import { useTimedReset } from "@app/hooks";
|
||||
import { useGetProjectRoleBySlug } from "@app/hooks/api";
|
||||
import { ProjectMembershipRole } from "@app/hooks/api/roles/types";
|
||||
import { UsePopUpState } from "@app/hooks/usePopUp";
|
||||
|
||||
type Props = {
|
||||
@@ -21,7 +22,9 @@ export const RoleDetailsSection = ({ roleSlug, handlePopUpOpen }: Props) => {
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { data } = useGetProjectRoleBySlug(currentWorkspace?.id ?? "", roleSlug as string);
|
||||
|
||||
const isCustomRole = !["admin", "member", "viewer", "no-access"].includes(data?.slug ?? "");
|
||||
const isCustomRole = !Object.values(ProjectMembershipRole).includes(
|
||||
(data?.slug ?? "") as ProjectMembershipRole
|
||||
);
|
||||
|
||||
return data ? (
|
||||
<div className="rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
|
||||
|
||||
@@ -115,12 +115,8 @@ export const RoleModal = ({ popUp, handlePopUpToggle }: Props) => {
|
||||
});
|
||||
|
||||
reset();
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
const error = err as any;
|
||||
const text =
|
||||
error?.response?.data?.message ??
|
||||
`Failed to ${popUp?.role?.data ? "update" : "create"} role`;
|
||||
} catch {
|
||||
const text = `Failed to ${popUp?.role?.data ? "update" : "create"} role`;
|
||||
|
||||
createNotification({
|
||||
text,
|
||||
|
||||
+24
-12
@@ -19,6 +19,7 @@ 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 { DynamicSecretPermissionConditions } from "./DynamicSecretPermissionConditions";
|
||||
@@ -31,6 +32,7 @@ import {
|
||||
isConditionalSubjects,
|
||||
PROJECT_PERMISSION_OBJECT,
|
||||
projectRoleFormSchema,
|
||||
ProjectTypePermissionSubjects,
|
||||
rolePermission2Form,
|
||||
TFormSchema
|
||||
} from "./ProjectRoleModifySection.utils";
|
||||
@@ -104,7 +106,9 @@ export const RolePermissionsSection = ({ roleSlug, isDisabled }: Props) => {
|
||||
}
|
||||
};
|
||||
|
||||
const isCustomRole = !["admin", "member", "viewer", "no-access"].includes(role?.slug ?? "");
|
||||
const isCustomRole = !Object.values(ProjectMembershipRole).includes(
|
||||
(role?.slug ?? "") as ProjectMembershipRole
|
||||
);
|
||||
|
||||
const onNewPolicy = (selectedSubject: ProjectPermissionSub) => {
|
||||
const rootPolicyValue = form.getValues(`permissions.${selectedSubject}`);
|
||||
@@ -192,6 +196,12 @@ export const RolePermissionsSection = ({ roleSlug, isDisabled }: Props) => {
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent className="thin-scrollbar max-h-96" align="end">
|
||||
{Object.keys(PROJECT_PERMISSION_OBJECT)
|
||||
.filter(
|
||||
(subject) =>
|
||||
ProjectTypePermissionSubjects[currentWorkspace.type][
|
||||
subject as ProjectPermissionSub
|
||||
]
|
||||
)
|
||||
.sort((a, b) =>
|
||||
PROJECT_PERMISSION_OBJECT[
|
||||
a as keyof typeof PROJECT_PERMISSION_OBJECT
|
||||
@@ -221,17 +231,19 @@ export const RolePermissionsSection = ({ roleSlug, isDisabled }: Props) => {
|
||||
</div>
|
||||
<div className="py-4">
|
||||
{!isPending && <PermissionEmptyState />}
|
||||
{(Object.keys(PROJECT_PERMISSION_OBJECT) as ProjectPermissionSub[]).map((subject) => (
|
||||
<GeneralPermissionPolicies
|
||||
subject={subject}
|
||||
actions={PROJECT_PERMISSION_OBJECT[subject].actions}
|
||||
title={PROJECT_PERMISSION_OBJECT[subject].title}
|
||||
key={`project-permission-${subject}`}
|
||||
isDisabled={isDisabled}
|
||||
>
|
||||
{renderConditionalComponents(subject, isDisabled)}
|
||||
</GeneralPermissionPolicies>
|
||||
))}
|
||||
{(Object.keys(PROJECT_PERMISSION_OBJECT) as ProjectPermissionSub[])
|
||||
.filter((subject) => ProjectTypePermissionSubjects[currentWorkspace.type][subject])
|
||||
.map((subject) => (
|
||||
<GeneralPermissionPolicies
|
||||
subject={subject}
|
||||
actions={PROJECT_PERMISSION_OBJECT[subject].actions}
|
||||
title={PROJECT_PERMISSION_OBJECT[subject].title}
|
||||
key={`project-permission-${subject}`}
|
||||
isDisabled={isDisabled}
|
||||
>
|
||||
{renderConditionalComponents(subject, isDisabled)}
|
||||
</GeneralPermissionPolicies>
|
||||
))}
|
||||
</div>
|
||||
</FormProvider>
|
||||
</form>
|
||||
|
||||
Reference in New Issue
Block a user