mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-03 14:26:02 +00:00
feat: made review changes
This commit is contained in:
@@ -208,6 +208,7 @@ const kickOutSecretManagerProject = async (knex: Knex, oldProjectId: string) =>
|
|||||||
if (secret) {
|
if (secret) {
|
||||||
const newProjectId = await newProject(knex, oldProjectId, ProjectType.SecretManager);
|
const newProjectId = await newProject(knex, oldProjectId, ProjectType.SecretManager);
|
||||||
await knex(TableName.IntegrationAuth).where("projectId", oldProjectId).update("projectId", newProjectId);
|
await knex(TableName.IntegrationAuth).where("projectId", oldProjectId).update("projectId", newProjectId);
|
||||||
|
await knex(TableName.Environment).where("projectId", oldProjectId).update("projectId", newProjectId);
|
||||||
await knex(TableName.SecretBlindIndex).where("projectId", oldProjectId).update("projectId", newProjectId);
|
await knex(TableName.SecretBlindIndex).where("projectId", oldProjectId).update("projectId", newProjectId);
|
||||||
await knex(TableName.SecretSync).where("projectId", oldProjectId).update("projectId", newProjectId);
|
await knex(TableName.SecretSync).where("projectId", oldProjectId).update("projectId", newProjectId);
|
||||||
await knex(TableName.SecretTag).where("projectId", oldProjectId).update("projectId", newProjectId);
|
await knex(TableName.SecretTag).where("projectId", oldProjectId).update("projectId", newProjectId);
|
||||||
@@ -229,7 +230,7 @@ const kickOutCertManagerProject = async (knex: Knex, oldProjectId: string) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const kickOutSecretScanningProject = async (knex: Knex, oldProjectId: string) => {
|
const kickOutSecretScanningProject = async (knex: Knex, oldProjectId: string) => {
|
||||||
const cas = await knex(TableName.SecretScanningConfig).where("projectId", oldProjectId).returning("id").first();
|
const cas = await knex(TableName.SecretScanningDataSource).where("projectId", oldProjectId).returning("id").first();
|
||||||
if (cas) {
|
if (cas) {
|
||||||
const newProjectId = await newProject(knex, oldProjectId, ProjectType.SecretScanning);
|
const newProjectId = await newProject(knex, oldProjectId, ProjectType.SecretScanning);
|
||||||
await knex(TableName.SecretScanningConfig).where("projectId", oldProjectId).update("projectId", newProjectId);
|
await knex(TableName.SecretScanningConfig).where("projectId", oldProjectId).update("projectId", newProjectId);
|
||||||
@@ -244,6 +245,7 @@ const kickOutKmsProject = async (knex: Knex, oldProjectId: string) => {
|
|||||||
.andWhere("isReserved", false)
|
.andWhere("isReserved", false)
|
||||||
.returning("id")
|
.returning("id")
|
||||||
.first();
|
.first();
|
||||||
|
|
||||||
if (kmsKeys) {
|
if (kmsKeys) {
|
||||||
const newProjectId = await newProject(knex, oldProjectId, ProjectType.KMS);
|
const newProjectId = await newProject(knex, oldProjectId, ProjectType.KMS);
|
||||||
await knex(TableName.KmsKey)
|
await knex(TableName.KmsKey)
|
||||||
@@ -255,7 +257,7 @@ const kickOutKmsProject = async (knex: Knex, oldProjectId: string) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const kickOutSshProject = async (knex: Knex, oldProjectId: string) => {
|
const kickOutSshProject = async (knex: Knex, oldProjectId: string) => {
|
||||||
const hosts = await knex(TableName.ProjectSshConfig).where("projectId", oldProjectId).returning("id").first();
|
const hosts = await knex(TableName.SshCertificateAuthority).where("projectId", oldProjectId).returning("id").first();
|
||||||
if (hosts) {
|
if (hosts) {
|
||||||
const newProjectId = await newProject(knex, oldProjectId, ProjectType.SSH);
|
const newProjectId = await newProject(knex, oldProjectId, ProjectType.SSH);
|
||||||
await knex(TableName.SshHost).where("projectId", oldProjectId).update("projectId", newProjectId);
|
await knex(TableName.SshHost).where("projectId", oldProjectId).update("projectId", newProjectId);
|
||||||
@@ -270,6 +272,9 @@ const BATCH_SIZE = 1000;
|
|||||||
export async function up(knex: Knex): Promise<void> {
|
export async function up(knex: Knex): Promise<void> {
|
||||||
const hasTemplateTypeColumn = await knex.schema.hasColumn(TableName.ProjectTemplates, "type");
|
const hasTemplateTypeColumn = await knex.schema.hasColumn(TableName.ProjectTemplates, "type");
|
||||||
if (hasTemplateTypeColumn) {
|
if (hasTemplateTypeColumn) {
|
||||||
|
await knex(TableName.ProjectTemplates).whereNull("type").update({
|
||||||
|
type: ProjectType.SecretManager
|
||||||
|
});
|
||||||
await knex.schema.alterTable(TableName.ProjectTemplates, (t) => {
|
await knex.schema.alterTable(TableName.ProjectTemplates, (t) => {
|
||||||
t.string("type").notNullable().defaultTo(ProjectType.SecretManager).alter();
|
t.string("type").notNullable().defaultTo(ProjectType.SecretManager).alter();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ export const getDefaultOnPremFeatures = (): TFeatureSet => ({
|
|||||||
},
|
},
|
||||||
pkiEst: false,
|
pkiEst: false,
|
||||||
enforceMfa: false,
|
enforceMfa: false,
|
||||||
projectTemplates: false,
|
projectTemplates: true,
|
||||||
kmip: false,
|
kmip: false,
|
||||||
gateway: false,
|
gateway: false,
|
||||||
sshHostGroups: false,
|
sshHostGroups: false,
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ export const pkiAlertServiceFactory = ({
|
|||||||
projectId: alert.projectId,
|
projectId: alert.projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId,
|
||||||
actionProjectType: ActionProjectType.Any
|
actionProjectType: ActionProjectType.CertificateManager
|
||||||
});
|
});
|
||||||
|
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.PkiAlerts);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Edit, ProjectPermissionSub.PkiAlerts);
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ export const serviceTokenServiceFactory = ({
|
|||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId,
|
||||||
actionProjectType: ActionProjectType.Any
|
actionProjectType: ActionProjectType.SecretManager
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.ServiceTokens);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Create, ProjectPermissionSub.ServiceTokens);
|
||||||
|
|
||||||
@@ -158,7 +158,7 @@ export const serviceTokenServiceFactory = ({
|
|||||||
projectId,
|
projectId,
|
||||||
actorAuthMethod,
|
actorAuthMethod,
|
||||||
actorOrgId,
|
actorOrgId,
|
||||||
actionProjectType: ActionProjectType.Any
|
actionProjectType: ActionProjectType.SecretManager
|
||||||
});
|
});
|
||||||
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.ServiceTokens);
|
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.ServiceTokens);
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ import {
|
|||||||
useSubscription,
|
useSubscription,
|
||||||
useUser
|
useUser
|
||||||
} from "@app/context";
|
} from "@app/context";
|
||||||
import { getProjectHomePage } from "@app/helpers/project";
|
import { getProjectHomePage, getProjectLottieIcon } from "@app/helpers/project";
|
||||||
import { useCreateWorkspace, useGetExternalKmsList, useGetUserWorkspaces } from "@app/hooks/api";
|
import { useCreateWorkspace, useGetExternalKmsList, useGetUserWorkspaces } from "@app/hooks/api";
|
||||||
import { INTERNAL_KMS_KEY_ID } from "@app/hooks/api/kms/types";
|
import { INTERNAL_KMS_KEY_ID } from "@app/hooks/api/kms/types";
|
||||||
import { InfisicalProjectTemplate, useListProjectTemplates } from "@app/hooks/api/projectTemplates";
|
import { InfisicalProjectTemplate, useListProjectTemplates } from "@app/hooks/api/projectTemplates";
|
||||||
@@ -63,28 +63,23 @@ type NewProjectFormProps = Pick<NewProjectModalProps, "onOpenChange">;
|
|||||||
const PROJECT_TYPE_MENU_ITEMS = [
|
const PROJECT_TYPE_MENU_ITEMS = [
|
||||||
{
|
{
|
||||||
label: "Secret Manager",
|
label: "Secret Manager",
|
||||||
value: ProjectType.SecretManager,
|
value: ProjectType.SecretManager
|
||||||
icon: "vault"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Certificate Manager",
|
label: "Certificate Manager",
|
||||||
value: ProjectType.CertificateManager,
|
value: ProjectType.CertificateManager
|
||||||
icon: "note"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "KMS",
|
label: "KMS",
|
||||||
value: ProjectType.KMS,
|
value: ProjectType.KMS
|
||||||
icon: "unlock"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "SSH",
|
label: "SSH",
|
||||||
value: ProjectType.SSH,
|
value: ProjectType.SSH
|
||||||
icon: "terminal"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "Secret Scanning",
|
label: "Secret Scanning",
|
||||||
value: ProjectType.SecretScanning,
|
value: ProjectType.SecretScanning
|
||||||
icon: "secret-scan"
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -102,18 +97,11 @@ const NewProjectForm = ({ onOpenChange }: NewProjectFormProps) => {
|
|||||||
OrgPermissionSubjects.ProjectTemplates
|
OrgPermissionSubjects.ProjectTemplates
|
||||||
);
|
);
|
||||||
|
|
||||||
const { data: projectTemplates = [] } = useListProjectTemplates({
|
|
||||||
enabled: Boolean(canReadProjectTemplates && subscription?.projectTemplates)
|
|
||||||
});
|
|
||||||
|
|
||||||
const { data: externalKmsList } = useGetExternalKmsList(currentOrg.id, {
|
|
||||||
enabled: permission.can(OrgPermissionActions.Read, OrgPermissionSubjects.Kms)
|
|
||||||
});
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
control,
|
control,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
reset,
|
reset,
|
||||||
|
watch,
|
||||||
formState: { isSubmitting, errors }
|
formState: { isSubmitting, errors }
|
||||||
} = useForm<TAddProjectFormData>({
|
} = useForm<TAddProjectFormData>({
|
||||||
resolver: zodResolver(formSchema),
|
resolver: zodResolver(formSchema),
|
||||||
@@ -123,6 +111,16 @@ const NewProjectForm = ({ onOpenChange }: NewProjectFormProps) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const selectedProjectType = watch("type");
|
||||||
|
const { data: projectTemplates = [] } = useListProjectTemplates({
|
||||||
|
enabled: Boolean(canReadProjectTemplates && subscription?.projectTemplates),
|
||||||
|
select: (template) => template.filter((el) => el.type === selectedProjectType)
|
||||||
|
});
|
||||||
|
|
||||||
|
const { data: externalKmsList } = useGetExternalKmsList(currentOrg.id, {
|
||||||
|
enabled: permission.can(OrgPermissionActions.Read, OrgPermissionSubjects.Kms)
|
||||||
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (Object.keys(errors).length > 0) {
|
if (Object.keys(errors).length > 0) {
|
||||||
console.log("Current form errors:", errors);
|
console.log("Current form errors:", errors);
|
||||||
@@ -212,7 +210,7 @@ const NewProjectForm = ({ onOpenChange }: NewProjectFormProps) => {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Lottie icon={el.icon} className="h-8 w-8" />
|
<Lottie icon={getProjectLottieIcon(el.value)} className="h-8 w-8" />
|
||||||
<div className="text-center text-xs">{el.label}</div>
|
<div className="text-center text-xs">{el.label}</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ export const getProjectHomePage = (type: ProjectType) => {
|
|||||||
|
|
||||||
export const getProjectTitle = (type: ProjectType) => {
|
export const getProjectTitle = (type: ProjectType) => {
|
||||||
const titleConvert = {
|
const titleConvert = {
|
||||||
[ProjectType.SecretManager]: "Secret Management",
|
[ProjectType.SecretManager]: "Secrets Management",
|
||||||
[ProjectType.KMS]: "Key Management",
|
[ProjectType.KMS]: "Key Management",
|
||||||
[ProjectType.CertificateManager]: "Cert Management",
|
[ProjectType.CertificateManager]: "Cert Management",
|
||||||
[ProjectType.SSH]: "SSH",
|
[ProjectType.SSH]: "SSH",
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
import { TProjectRole } from "@app/hooks/api/roles/types";
|
import { TProjectRole } from "@app/hooks/api/roles/types";
|
||||||
|
|
||||||
|
import { ProjectType } from "../workspace/types";
|
||||||
|
|
||||||
export type TProjectTemplate = {
|
export type TProjectTemplate = {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
|
type: ProjectType;
|
||||||
roles: Pick<TProjectRole, "slug" | "name" | "permissions">[];
|
roles: Pick<TProjectRole, "slug" | "name" | "permissions">[];
|
||||||
environments?: { name: string; slug: string; position: number }[] | null;
|
environments?: { name: string; slug: string; position: number }[] | null;
|
||||||
createdAt: string;
|
createdAt: string;
|
||||||
@@ -16,6 +19,7 @@ export type TProjectTemplateResponse = { projectTemplate: TProjectTemplate };
|
|||||||
export type TCreateProjectTemplateDTO = {
|
export type TCreateProjectTemplateDTO = {
|
||||||
name: string;
|
name: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
|
type?: ProjectType;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TUpdateProjectTemplateDTO = Partial<
|
export type TUpdateProjectTemplateDTO = Partial<
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ export const SecretScanningLayout = () => {
|
|||||||
)}
|
)}
|
||||||
</Link>
|
</Link>
|
||||||
<Link
|
<Link
|
||||||
to="/projects/secret-management/$projectId/settings"
|
to="/projects/secret-scanning/$projectId/settings"
|
||||||
params={{
|
params={{
|
||||||
projectId: currentWorkspace.id
|
projectId: currentWorkspace.id
|
||||||
}}
|
}}
|
||||||
|
|||||||
+6
-2
@@ -5,6 +5,7 @@ import { createNotification } from "@app/components/notifications";
|
|||||||
import { OrgPermissionCan } from "@app/components/permissions";
|
import { OrgPermissionCan } from "@app/components/permissions";
|
||||||
import { Button, DeleteActionModal } from "@app/components/v2";
|
import { Button, DeleteActionModal } from "@app/components/v2";
|
||||||
import { OrgPermissionActions, OrgPermissionSubjects } from "@app/context";
|
import { OrgPermissionActions, OrgPermissionSubjects } from "@app/context";
|
||||||
|
import { getProjectTitle } from "@app/helpers/project";
|
||||||
import { usePopUp } from "@app/hooks";
|
import { usePopUp } from "@app/hooks";
|
||||||
import { TProjectTemplate, useDeleteProjectTemplate } from "@app/hooks/api/projectTemplates";
|
import { TProjectTemplate, useDeleteProjectTemplate } from "@app/hooks/api/projectTemplates";
|
||||||
|
|
||||||
@@ -24,7 +25,7 @@ export const EditProjectTemplate = ({ isInfisicalTemplate, projectTemplate, onBa
|
|||||||
"editDetails"
|
"editDetails"
|
||||||
] as const);
|
] as const);
|
||||||
|
|
||||||
const { id: templateId, name, description } = projectTemplate;
|
const { id: templateId, name, description, type } = projectTemplate;
|
||||||
|
|
||||||
const deleteProjectTemplate = useDeleteProjectTemplate();
|
const deleteProjectTemplate = useDeleteProjectTemplate();
|
||||||
|
|
||||||
@@ -53,7 +54,10 @@ export const EditProjectTemplate = ({ isInfisicalTemplate, projectTemplate, onBa
|
|||||||
<div className="mb-4 flex items-start justify-between border-b border-bunker-400 pb-4">
|
<div className="mb-4 flex items-start justify-between border-b border-bunker-400 pb-4">
|
||||||
<div className="flex-col">
|
<div className="flex-col">
|
||||||
<h3 className="text-xl font-semibold">{name}</h3>
|
<h3 className="text-xl font-semibold">{name}</h3>
|
||||||
<h2 className="text-sm text-mineshaft-400">{description || "Project Template"}</h2>
|
<h2 className="text-sm text-mineshaft-400">
|
||||||
|
{`${getProjectTitle(type)} - `}
|
||||||
|
{description || "Project Template"}
|
||||||
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
{!isInfisicalTemplate && (
|
{!isInfisicalTemplate && (
|
||||||
<div className="flex gap-2">
|
<div className="flex gap-2">
|
||||||
|
|||||||
+69
-3
@@ -1,5 +1,6 @@
|
|||||||
import { useForm } from "react-hook-form";
|
import { Controller, useForm } from "react-hook-form";
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
|
import { twMerge } from "tailwind-merge";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import { createNotification } from "@app/components/notifications";
|
import { createNotification } from "@app/components/notifications";
|
||||||
@@ -7,21 +8,25 @@ import {
|
|||||||
Button,
|
Button,
|
||||||
FormControl,
|
FormControl,
|
||||||
Input,
|
Input,
|
||||||
|
Lottie,
|
||||||
Modal,
|
Modal,
|
||||||
ModalClose,
|
ModalClose,
|
||||||
ModalContent,
|
ModalContent,
|
||||||
TextArea
|
TextArea
|
||||||
} from "@app/components/v2";
|
} from "@app/components/v2";
|
||||||
|
import { getProjectLottieIcon } from "@app/helpers/project";
|
||||||
import {
|
import {
|
||||||
TProjectTemplate,
|
TProjectTemplate,
|
||||||
useCreateProjectTemplate,
|
useCreateProjectTemplate,
|
||||||
useUpdateProjectTemplate
|
useUpdateProjectTemplate
|
||||||
} from "@app/hooks/api/projectTemplates";
|
} from "@app/hooks/api/projectTemplates";
|
||||||
|
import { ProjectType } from "@app/hooks/api/workspace/types";
|
||||||
import { slugSchema } from "@app/lib/schemas";
|
import { slugSchema } from "@app/lib/schemas";
|
||||||
|
|
||||||
const formSchema = z.object({
|
const formSchema = z.object({
|
||||||
name: slugSchema({ min: 1, max: 64, field: "Name" }),
|
name: slugSchema({ min: 1, max: 64, field: "Name" }),
|
||||||
description: z.string().max(500).optional()
|
description: z.string().max(500).optional(),
|
||||||
|
type: z.nativeEnum(ProjectType).optional()
|
||||||
});
|
});
|
||||||
|
|
||||||
export type FormData = z.infer<typeof formSchema>;
|
export type FormData = z.infer<typeof formSchema>;
|
||||||
@@ -38,6 +43,29 @@ type FormProps = {
|
|||||||
onComplete: (template: TProjectTemplate) => void;
|
onComplete: (template: TProjectTemplate) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const PROJECT_TYPE_MENU_ITEMS = [
|
||||||
|
{
|
||||||
|
label: "Secrets Manager",
|
||||||
|
value: ProjectType.SecretManager
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Certificates Manager",
|
||||||
|
value: ProjectType.CertificateManager
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "KMS",
|
||||||
|
value: ProjectType.KMS
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "SSH",
|
||||||
|
value: ProjectType.SSH
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Secret Scanning",
|
||||||
|
value: ProjectType.SecretScanning
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
const ProjectTemplateForm = ({ onComplete, projectTemplate }: FormProps) => {
|
const ProjectTemplateForm = ({ onComplete, projectTemplate }: FormProps) => {
|
||||||
const createProjectTemplate = useCreateProjectTemplate();
|
const createProjectTemplate = useCreateProjectTemplate();
|
||||||
const updateProjectTemplate = useUpdateProjectTemplate();
|
const updateProjectTemplate = useUpdateProjectTemplate();
|
||||||
@@ -45,12 +73,14 @@ const ProjectTemplateForm = ({ onComplete, projectTemplate }: FormProps) => {
|
|||||||
const {
|
const {
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
register,
|
register,
|
||||||
|
control,
|
||||||
formState: { isSubmitting, errors }
|
formState: { isSubmitting, errors }
|
||||||
} = useForm<FormData>({
|
} = useForm<FormData>({
|
||||||
resolver: zodResolver(formSchema),
|
resolver: zodResolver(formSchema),
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
name: projectTemplate?.name,
|
name: projectTemplate?.name,
|
||||||
description: projectTemplate?.description
|
description: projectTemplate?.description,
|
||||||
|
type: ProjectType.SecretManager
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -90,6 +120,42 @@ const ProjectTemplateForm = ({ onComplete, projectTemplate }: FormProps) => {
|
|||||||
>
|
>
|
||||||
<Input autoFocus placeholder="my-project-template" {...register("name")} />
|
<Input autoFocus placeholder="my-project-template" {...register("name")} />
|
||||||
</FormControl>
|
</FormControl>
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
name="type"
|
||||||
|
defaultValue={ProjectType.SecretManager}
|
||||||
|
render={({ field, fieldState: { error } }) => (
|
||||||
|
<FormControl
|
||||||
|
label="Project Type"
|
||||||
|
isError={Boolean(error)}
|
||||||
|
errorText={error?.message}
|
||||||
|
className="flex-1"
|
||||||
|
>
|
||||||
|
<div className="mt-2 grid grid-cols-5 gap-4">
|
||||||
|
{PROJECT_TYPE_MENU_ITEMS.map((el) => (
|
||||||
|
<div
|
||||||
|
key={el.value}
|
||||||
|
className={twMerge(
|
||||||
|
"flex cursor-pointer flex-col items-center gap-2 rounded border border-mineshaft-600 p-4 opacity-75 transition-all hover:border-primary-400 hover:bg-mineshaft-600",
|
||||||
|
field.value === el.value && "border-primary-400 bg-mineshaft-600 opacity-100"
|
||||||
|
)}
|
||||||
|
onClick={() => field.onChange(el.value)}
|
||||||
|
role="button"
|
||||||
|
tabIndex={0}
|
||||||
|
onKeyDown={(e) => {
|
||||||
|
if (e.key === "Enter") {
|
||||||
|
field.onChange(el.value);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Lottie icon={getProjectLottieIcon(el.value)} className="h-8 w-8" />
|
||||||
|
<div className="text-center text-xs">{el.label}</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</FormControl>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
<FormControl
|
<FormControl
|
||||||
label="Description (optional)"
|
label="Description (optional)"
|
||||||
errorText={errors.description?.message}
|
errorText={errors.description?.message}
|
||||||
|
|||||||
+4
-2
@@ -23,6 +23,7 @@ import {
|
|||||||
Tr
|
Tr
|
||||||
} from "@app/components/v2";
|
} from "@app/components/v2";
|
||||||
import { OrgPermissionActions, OrgPermissionSubjects, useSubscription } from "@app/context";
|
import { OrgPermissionActions, OrgPermissionSubjects, useSubscription } from "@app/context";
|
||||||
|
import { getProjectTitle } from "@app/helpers/project";
|
||||||
import { usePopUp } from "@app/hooks";
|
import { usePopUp } from "@app/hooks";
|
||||||
import { TProjectTemplate, useListProjectTemplates } from "@app/hooks/api/projectTemplates";
|
import { TProjectTemplate, useListProjectTemplates } from "@app/hooks/api/projectTemplates";
|
||||||
|
|
||||||
@@ -66,8 +67,8 @@ export const ProjectTemplatesTable = ({ onEdit }: Props) => {
|
|||||||
<THead>
|
<THead>
|
||||||
<Tr>
|
<Tr>
|
||||||
<Th>Name</Th>
|
<Th>Name</Th>
|
||||||
|
<Th>Type</Th>
|
||||||
<Th>Roles</Th>
|
<Th>Roles</Th>
|
||||||
<Th>Environments</Th>
|
|
||||||
<Th />
|
<Th />
|
||||||
</Tr>
|
</Tr>
|
||||||
</THead>
|
</THead>
|
||||||
@@ -80,7 +81,7 @@ export const ProjectTemplatesTable = ({ onEdit }: Props) => {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{filteredTemplates.map((template) => {
|
{filteredTemplates.map((template) => {
|
||||||
const { id, name, roles, environments = [], description } = template;
|
const { id, name, roles, environments = [], description, type } = template;
|
||||||
return (
|
return (
|
||||||
<Tr
|
<Tr
|
||||||
onClick={() => onEdit(template)}
|
onClick={() => onEdit(template)}
|
||||||
@@ -99,6 +100,7 @@ export const ProjectTemplatesTable = ({ onEdit }: Props) => {
|
|||||||
</Tooltip>
|
</Tooltip>
|
||||||
)}
|
)}
|
||||||
</Td>
|
</Td>
|
||||||
|
<Td>{getProjectTitle(type)}</Td>
|
||||||
<Td className="pl-8">
|
<Td className="pl-8">
|
||||||
{roles.length}
|
{roles.length}
|
||||||
{roles.length > 0 && (
|
{roles.length > 0 && (
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { useNavigate, useSearch } from "@tanstack/react-router";
|
|||||||
import { PageHeader, Tab, TabList, TabPanel, Tabs } from "@app/components/v2";
|
import { PageHeader, Tab, TabList, TabPanel, Tabs } from "@app/components/v2";
|
||||||
import { useWorkspace } from "@app/context";
|
import { useWorkspace } from "@app/context";
|
||||||
import { getProjectBaseURL } from "@app/helpers/project";
|
import { getProjectBaseURL } from "@app/helpers/project";
|
||||||
|
import { ProjectType } from "@app/hooks/api/workspace/types";
|
||||||
import { ProjectAccessControlTabs } from "@app/types/project";
|
import { ProjectAccessControlTabs } from "@app/types/project";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -33,6 +34,8 @@ const Page = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const isSecretManager = currentWorkspace.type === ProjectType.SecretManager;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="container mx-auto flex flex-col justify-between bg-bunker-800 text-white">
|
<div className="container mx-auto flex flex-col justify-between bg-bunker-800 text-white">
|
||||||
<div className="mx-auto mb-6 w-full max-w-7xl">
|
<div className="mx-auto mb-6 w-full max-w-7xl">
|
||||||
@@ -49,7 +52,9 @@ const Page = () => {
|
|||||||
<p>Machine Identities</p>
|
<p>Machine Identities</p>
|
||||||
</div>
|
</div>
|
||||||
</Tab>
|
</Tab>
|
||||||
<Tab value={ProjectAccessControlTabs.ServiceTokens}>Service Tokens</Tab>
|
{isSecretManager && (
|
||||||
|
<Tab value={ProjectAccessControlTabs.ServiceTokens}>Service Tokens</Tab>
|
||||||
|
)}
|
||||||
<Tab value={ProjectAccessControlTabs.Roles}>Project Roles</Tab>
|
<Tab value={ProjectAccessControlTabs.Roles}>Project Roles</Tab>
|
||||||
</TabList>
|
</TabList>
|
||||||
<TabPanel value={ProjectAccessControlTabs.Member}>
|
<TabPanel value={ProjectAccessControlTabs.Member}>
|
||||||
@@ -61,9 +66,11 @@ const Page = () => {
|
|||||||
<TabPanel value={ProjectAccessControlTabs.Identities}>
|
<TabPanel value={ProjectAccessControlTabs.Identities}>
|
||||||
<IdentityTab />
|
<IdentityTab />
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
<TabPanel value={ProjectAccessControlTabs.ServiceTokens}>
|
{isSecretManager && (
|
||||||
<ServiceTokenTab />
|
<TabPanel value={ProjectAccessControlTabs.ServiceTokens}>
|
||||||
</TabPanel>
|
<ServiceTokenTab />
|
||||||
|
</TabPanel>
|
||||||
|
)}
|
||||||
<TabPanel value={ProjectAccessControlTabs.Roles}>
|
<TabPanel value={ProjectAccessControlTabs.Roles}>
|
||||||
<ProjectRoleListTab />
|
<ProjectRoleListTab />
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import {
|
|||||||
DropdownMenuTrigger,
|
DropdownMenuTrigger,
|
||||||
IconButton
|
IconButton
|
||||||
} from "@app/components/v2";
|
} from "@app/components/v2";
|
||||||
|
import { useWorkspace } from "@app/context";
|
||||||
import { usePopUp } from "@app/hooks";
|
import { usePopUp } from "@app/hooks";
|
||||||
import { PolicySelectionModal } from "@app/pages/project/RoleDetailsBySlugPage/components/PolicySelectionModal";
|
import { PolicySelectionModal } from "@app/pages/project/RoleDetailsBySlugPage/components/PolicySelectionModal";
|
||||||
import { PolicyTemplateModal } from "@app/pages/project/RoleDetailsBySlugPage/components/PolicyTemplateModal";
|
import { PolicyTemplateModal } from "@app/pages/project/RoleDetailsBySlugPage/components/PolicyTemplateModal";
|
||||||
@@ -17,6 +18,7 @@ type Props = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const AddPoliciesButton = ({ isDisabled }: Props) => {
|
export const AddPoliciesButton = ({ isDisabled }: Props) => {
|
||||||
|
const { currentWorkspace } = useWorkspace();
|
||||||
const { popUp, handlePopUpToggle, handlePopUpOpen, handlePopUpClose } = usePopUp([
|
const { popUp, handlePopUpToggle, handlePopUpOpen, handlePopUpClose } = usePopUp([
|
||||||
"addPolicy",
|
"addPolicy",
|
||||||
"addPolicyOptions",
|
"addPolicyOptions",
|
||||||
@@ -66,10 +68,12 @@ export const AddPoliciesButton = ({ isDisabled }: Props) => {
|
|||||||
</DropdownMenuContent>
|
</DropdownMenuContent>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
<PolicySelectionModal
|
<PolicySelectionModal
|
||||||
|
type={currentWorkspace.type}
|
||||||
isOpen={popUp.addPolicy.isOpen}
|
isOpen={popUp.addPolicy.isOpen}
|
||||||
onOpenChange={(isOpen) => handlePopUpToggle("addPolicy", isOpen)}
|
onOpenChange={(isOpen) => handlePopUpToggle("addPolicy", isOpen)}
|
||||||
/>
|
/>
|
||||||
<PolicyTemplateModal
|
<PolicyTemplateModal
|
||||||
|
type={currentWorkspace.type}
|
||||||
isOpen={popUp.applyTemplate.isOpen}
|
isOpen={popUp.applyTemplate.isOpen}
|
||||||
onOpenChange={(isOpen) => handlePopUpToggle("applyTemplate", isOpen)}
|
onOpenChange={(isOpen) => handlePopUpToggle("applyTemplate", isOpen)}
|
||||||
/>
|
/>
|
||||||
|
|||||||
+14
-4
@@ -19,26 +19,31 @@ import {
|
|||||||
Tr
|
Tr
|
||||||
} from "@app/components/v2";
|
} from "@app/components/v2";
|
||||||
import { ProjectPermissionSub } from "@app/context";
|
import { ProjectPermissionSub } from "@app/context";
|
||||||
|
import { ProjectType } from "@app/hooks/api/workspace/types";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
EXCLUDED_PERMISSION_SUBS,
|
EXCLUDED_PERMISSION_SUBS,
|
||||||
isConditionalSubjects,
|
isConditionalSubjects,
|
||||||
PROJECT_PERMISSION_OBJECT,
|
PROJECT_PERMISSION_OBJECT,
|
||||||
|
ProjectTypePermissionSubjects,
|
||||||
TFormSchema
|
TFormSchema
|
||||||
} from "./ProjectRoleModifySection.utils";
|
} from "./ProjectRoleModifySection.utils";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
onOpenChange: (isOpen: boolean) => void;
|
onOpenChange: (isOpen: boolean) => void;
|
||||||
|
type: ProjectType;
|
||||||
};
|
};
|
||||||
|
|
||||||
type ContentProps = {
|
type ContentProps = {
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
|
|
||||||
|
type: ProjectType;
|
||||||
};
|
};
|
||||||
|
|
||||||
type TForm = { permissions: Record<ProjectPermissionSub, boolean> };
|
type TForm = { permissions: Record<ProjectPermissionSub, boolean> };
|
||||||
|
|
||||||
const Content = ({ onClose }: ContentProps) => {
|
const Content = ({ onClose, type: projectType }: ContentProps) => {
|
||||||
const rootForm = useFormContext<TFormSchema>();
|
const rootForm = useFormContext<TFormSchema>();
|
||||||
const [search, setSearch] = useState("");
|
const [search, setSearch] = useState("");
|
||||||
const {
|
const {
|
||||||
@@ -56,7 +61,12 @@ const Content = ({ onClose }: ContentProps) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const filteredPolicies = Object.entries(PROJECT_PERMISSION_OBJECT)
|
const filteredPolicies = Object.entries(PROJECT_PERMISSION_OBJECT)
|
||||||
.filter(([, { title }]) => (search ? title.toLowerCase().includes(search.toLowerCase()) : true))
|
.filter(
|
||||||
|
([subject, { title }]) =>
|
||||||
|
ProjectTypePermissionSubjects[projectType ?? ProjectType.SecretManager][
|
||||||
|
subject as ProjectPermissionSub
|
||||||
|
] && (search ? title.toLowerCase().includes(search.toLowerCase()) : true)
|
||||||
|
)
|
||||||
.filter(([subject]) => !EXCLUDED_PERMISSION_SUBS.includes(subject as ProjectPermissionSub))
|
.filter(([subject]) => !EXCLUDED_PERMISSION_SUBS.includes(subject as ProjectPermissionSub))
|
||||||
.sort((a, b) => a[1].title.localeCompare(b[1].title))
|
.sort((a, b) => a[1].title.localeCompare(b[1].title))
|
||||||
.map(([subject]) => subject);
|
.map(([subject]) => subject);
|
||||||
@@ -191,7 +201,7 @@ const Content = ({ onClose }: ContentProps) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const PolicySelectionModal = ({ isOpen, onOpenChange }: Props) => {
|
export const PolicySelectionModal = ({ isOpen, onOpenChange, type }: Props) => {
|
||||||
return (
|
return (
|
||||||
<Modal isOpen={isOpen} onOpenChange={onOpenChange}>
|
<Modal isOpen={isOpen} onOpenChange={onOpenChange}>
|
||||||
<ModalContent
|
<ModalContent
|
||||||
@@ -199,7 +209,7 @@ export const PolicySelectionModal = ({ isOpen, onOpenChange }: Props) => {
|
|||||||
subTitle="Select one or more policies to add to this role."
|
subTitle="Select one or more policies to add to this role."
|
||||||
className="max-w-3xl"
|
className="max-w-3xl"
|
||||||
>
|
>
|
||||||
<Content onClose={() => onOpenChange(false)} />
|
<Content onClose={() => onOpenChange(false)} type={type} />
|
||||||
</ModalContent>
|
</ModalContent>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
|
|||||||
+10
-5
@@ -13,6 +13,7 @@ import {
|
|||||||
ModalContent
|
ModalContent
|
||||||
} from "@app/components/v2";
|
} from "@app/components/v2";
|
||||||
import { ProjectPermissionSub } from "@app/context";
|
import { ProjectPermissionSub } from "@app/context";
|
||||||
|
import { ProjectType } from "@app/hooks/api/workspace/types";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
PROJECT_PERMISSION_OBJECT,
|
PROJECT_PERMISSION_OBJECT,
|
||||||
@@ -24,19 +25,23 @@ import {
|
|||||||
type Props = {
|
type Props = {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
onOpenChange: (isOpen: boolean) => void;
|
onOpenChange: (isOpen: boolean) => void;
|
||||||
|
type: ProjectType;
|
||||||
};
|
};
|
||||||
|
|
||||||
type ContentProps = {
|
type ContentProps = {
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
|
type: ProjectType;
|
||||||
};
|
};
|
||||||
|
|
||||||
const Content = ({ onClose }: ContentProps) => {
|
const Content = ({ onClose, type: projectType }: ContentProps) => {
|
||||||
const rootForm = useFormContext<TFormSchema>();
|
const rootForm = useFormContext<TFormSchema>();
|
||||||
|
|
||||||
const [selectedTemplate, setSelectedTemplate] = useState<RoleTemplate>();
|
const [selectedTemplate, setSelectedTemplate] = useState<RoleTemplate>();
|
||||||
const [conflictingSubjects, setConflictingSubjects] = useState<ProjectPermissionSub[]>([]);
|
const [conflictingSubjects, setConflictingSubjects] = useState<ProjectPermissionSub[]>([]);
|
||||||
const [showConflictingSubjects, setShowConflictingSubjects] = useState(false);
|
const [showConflictingSubjects, setShowConflictingSubjects] = useState(false);
|
||||||
|
|
||||||
|
const templates = RoleTemplates[projectType ?? ProjectType.SecretManager];
|
||||||
|
|
||||||
const onSubmit = (skipConflicting = false) => {
|
const onSubmit = (skipConflicting = false) => {
|
||||||
if (!selectedTemplate) {
|
if (!selectedTemplate) {
|
||||||
createNotification({ type: "error", text: "Please select a template" });
|
createNotification({ type: "error", text: "Please select a template" });
|
||||||
@@ -121,12 +126,12 @@ const Content = ({ onClose }: ContentProps) => {
|
|||||||
type="single"
|
type="single"
|
||||||
value={selectedTemplate?.id}
|
value={selectedTemplate?.id}
|
||||||
onValueChange={(value) =>
|
onValueChange={(value) =>
|
||||||
setSelectedTemplate(RoleTemplates.find((template) => template.id === value))
|
setSelectedTemplate(templates.find((template) => template.id === value))
|
||||||
}
|
}
|
||||||
collapsible
|
collapsible
|
||||||
className="w-full border-collapse"
|
className="w-full border-collapse"
|
||||||
>
|
>
|
||||||
{RoleTemplates.map(({ name, description, permissions, id }) => (
|
{templates.map(({ name, description, permissions, id }) => (
|
||||||
<AccordionItem
|
<AccordionItem
|
||||||
key={id}
|
key={id}
|
||||||
value={id}
|
value={id}
|
||||||
@@ -182,7 +187,7 @@ const Content = ({ onClose }: ContentProps) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const PolicyTemplateModal = ({ isOpen, onOpenChange }: Props) => {
|
export const PolicyTemplateModal = ({ isOpen, onOpenChange, type }: Props) => {
|
||||||
return (
|
return (
|
||||||
<Modal isOpen={isOpen} onOpenChange={onOpenChange}>
|
<Modal isOpen={isOpen} onOpenChange={onOpenChange}>
|
||||||
<ModalContent
|
<ModalContent
|
||||||
@@ -190,7 +195,7 @@ export const PolicyTemplateModal = ({ isOpen, onOpenChange }: Props) => {
|
|||||||
subTitle="Select a template with prepopulated policies to get started. You can always add more policies later."
|
subTitle="Select a template with prepopulated policies to get started. You can always add more policies later."
|
||||||
className="max-w-3xl"
|
className="max-w-3xl"
|
||||||
>
|
>
|
||||||
<Content onClose={() => onOpenChange(false)} />
|
<Content onClose={() => onOpenChange(false)} type={type} />
|
||||||
</ModalContent>
|
</ModalContent>
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
|
|||||||
+370
-341
@@ -1645,41 +1645,378 @@ export type RoleTemplate = {
|
|||||||
permissions: { subject: ProjectPermissionSub; actions: string[] }[];
|
permissions: { subject: ProjectPermissionSub; actions: string[] }[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export const RoleTemplates = [
|
const projectManagerTemplate = (
|
||||||
{
|
additionalPermissions: RoleTemplate["permissions"] = []
|
||||||
id: "project-manager",
|
): RoleTemplate => ({
|
||||||
name: "Project Management Policies",
|
id: "project-manager",
|
||||||
description: "Grants access to manage project members and settings",
|
name: "Project Management Policies",
|
||||||
permissions: [
|
description: "Grants access to manage project members and settings",
|
||||||
|
permissions: [
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.AuditLogs,
|
||||||
|
actions: Object.values(ProjectPermissionActions)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.Groups,
|
||||||
|
actions: Object.values(ProjectPermissionGroupActions)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.Member,
|
||||||
|
actions: Object.values(ProjectPermissionMemberActions)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.Identity,
|
||||||
|
actions: Object.values(ProjectPermissionIdentityActions)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.Project,
|
||||||
|
actions: [ProjectPermissionActions.Edit, ProjectPermissionActions.Delete]
|
||||||
|
},
|
||||||
|
{ subject: ProjectPermissionSub.Role, actions: Object.values(ProjectPermissionActions) },
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.Settings,
|
||||||
|
actions: [ProjectPermissionActions.Read, ProjectPermissionActions.Edit]
|
||||||
|
},
|
||||||
|
...additionalPermissions
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
export const RoleTemplates: Record<ProjectType, RoleTemplate[]> = {
|
||||||
|
[ProjectType.SSH]: [
|
||||||
|
{
|
||||||
|
id: "ssh-viewer",
|
||||||
|
name: "SSH Viewing Policies",
|
||||||
|
description: "Grants read access to SSH certificates and hosts",
|
||||||
|
permissions: [
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.SshCertificateAuthorities,
|
||||||
|
actions: [ProjectPermissionActions.Read]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.SshCertificates,
|
||||||
|
actions: [ProjectPermissionActions.Read]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.SshCertificateTemplates,
|
||||||
|
actions: [ProjectPermissionActions.Read]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.SshHosts,
|
||||||
|
actions: [ProjectPermissionSshHostActions.Read]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.SshHostGroups,
|
||||||
|
actions: [ProjectPermissionActions.Read]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "ssh-cert-editor",
|
||||||
|
name: "SSH Certificate Editing Policies",
|
||||||
|
description: "Grants read and edit access to SSH certificates",
|
||||||
|
permissions: [
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.SshCertificateAuthorities,
|
||||||
|
actions: Object.values(ProjectPermissionActions)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.SshCertificates,
|
||||||
|
actions: Object.values(ProjectPermissionActions)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.SshCertificateTemplates,
|
||||||
|
actions: Object.values(ProjectPermissionActions)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "ssh-host-editor",
|
||||||
|
name: "SSH Host Editing Policies",
|
||||||
|
description: "Grants read and edit access to SSH hosts",
|
||||||
|
permissions: [
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.SshHosts,
|
||||||
|
actions: Object.values(ProjectPermissionSshHostActions)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.SshHostGroups,
|
||||||
|
actions: Object.values(ProjectPermissionActions)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
projectManagerTemplate()
|
||||||
|
],
|
||||||
|
[ProjectType.KMS]: [
|
||||||
|
{
|
||||||
|
id: "kms-viewer",
|
||||||
|
name: "KMS Viewing Policies",
|
||||||
|
description: "Grants read access to KMS keys and KMIP clients",
|
||||||
|
permissions: [
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.Cmek,
|
||||||
|
actions: [ProjectPermissionCmekActions.Read]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.Kmip,
|
||||||
|
actions: [ProjectPermissionKmipActions.ReadClients]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "key-editor",
|
||||||
|
name: "KMS Key Editing Policies",
|
||||||
|
description: "Grants read and edit access to KMS keys",
|
||||||
|
permissions: [
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.Cmek,
|
||||||
|
actions: Object.values(ProjectPermissionCmekActions)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "kmip-editor",
|
||||||
|
name: "KMIP Client Editing Policies",
|
||||||
|
description: "Grants read and edit access to KMIP clients",
|
||||||
|
permissions: [
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.Kmip,
|
||||||
|
actions: Object.values(ProjectPermissionKmipActions)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
projectManagerTemplate()
|
||||||
|
],
|
||||||
|
[ProjectType.CertificateManager]: [
|
||||||
|
{
|
||||||
|
id: "cert-viewer",
|
||||||
|
name: "Certificate Viewing Policies",
|
||||||
|
description: "Grants read access to certificates and related resources",
|
||||||
|
permissions: [
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.PkiCollections,
|
||||||
|
actions: [ProjectPermissionActions.Read]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.PkiAlerts,
|
||||||
|
actions: [ProjectPermissionActions.Read]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.CertificateAuthorities,
|
||||||
|
actions: [ProjectPermissionActions.Read]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.CertificateTemplates,
|
||||||
|
actions: [ProjectPermissionActions.Read]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.Certificates,
|
||||||
|
actions: [
|
||||||
|
ProjectPermissionCertificateActions.Read,
|
||||||
|
ProjectPermissionCertificateActions.ReadPrivateKey
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "cert-editor",
|
||||||
|
name: "Certificate Editing Policies",
|
||||||
|
description: "Grants read and edit access to certificates and related resources",
|
||||||
|
permissions: [
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.PkiCollections,
|
||||||
|
actions: Object.values(ProjectPermissionActions)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.PkiAlerts,
|
||||||
|
actions: Object.values(ProjectPermissionActions)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.CertificateAuthorities,
|
||||||
|
actions: Object.values(ProjectPermissionActions)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.CertificateTemplates,
|
||||||
|
actions: Object.values(ProjectPermissionActions)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.Certificates,
|
||||||
|
actions: Object.values(ProjectPermissionCertificateActions)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
projectManagerTemplate()
|
||||||
|
],
|
||||||
|
[ProjectType.SecretScanning]: [
|
||||||
|
{
|
||||||
|
id: "scanning-viewer",
|
||||||
|
name: "Secret Scanning Viewing Policies",
|
||||||
|
description: "Grants read access to data sources and findings",
|
||||||
|
permissions: [
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.SecretScanningDataSources,
|
||||||
|
actions: [
|
||||||
|
ProjectPermissionSecretScanningDataSourceActions.Read,
|
||||||
|
ProjectPermissionSecretScanningDataSourceActions.ReadResources,
|
||||||
|
ProjectPermissionSecretScanningDataSourceActions.ReadScans
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.SecretScanningFindings,
|
||||||
|
actions: [ProjectPermissionSecretScanningFindingActions.Read]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.SecretScanningConfigs,
|
||||||
|
actions: [ProjectPermissionSecretScanningConfigActions.Read]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "scanning-editor",
|
||||||
|
name: "Secret Scanning Editing Policies",
|
||||||
|
description: "Grants read and edit access to data sources and findings",
|
||||||
|
permissions: [
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.SecretScanningDataSources,
|
||||||
|
actions: Object.values(ProjectPermissionSecretScanningDataSourceActions)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.SecretScanningFindings,
|
||||||
|
actions: Object.values(ProjectPermissionSecretScanningFindingActions)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.SecretScanningConfigs,
|
||||||
|
actions: [ProjectPermissionSecretScanningConfigActions.Read]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
projectManagerTemplate([
|
||||||
{
|
{
|
||||||
subject: ProjectPermissionSub.AuditLogs,
|
subject: ProjectPermissionSub.SecretScanningConfigs,
|
||||||
actions: Object.values(ProjectPermissionActions)
|
actions: Object.values(ProjectPermissionSecretScanningConfigActions)
|
||||||
},
|
}
|
||||||
{
|
])
|
||||||
subject: ProjectPermissionSub.Groups,
|
],
|
||||||
actions: Object.values(ProjectPermissionGroupActions)
|
[ProjectType.SecretManager]: [
|
||||||
},
|
{
|
||||||
{
|
id: "secret-viewer",
|
||||||
subject: ProjectPermissionSub.Member,
|
name: "Secret Viewing Policies",
|
||||||
actions: Object.values(ProjectPermissionMemberActions)
|
description: "Grants read access to secrets and related resources",
|
||||||
},
|
permissions: [
|
||||||
{
|
{
|
||||||
subject: ProjectPermissionSub.Identity,
|
subject: ProjectPermissionSub.SecretRollback,
|
||||||
actions: Object.values(ProjectPermissionIdentityActions)
|
actions: [ProjectPermissionActions.Read]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
subject: ProjectPermissionSub.Project,
|
subject: ProjectPermissionSub.SecretImports,
|
||||||
actions: [ProjectPermissionActions.Edit, ProjectPermissionActions.Delete]
|
actions: [ProjectPermissionActions.Read]
|
||||||
},
|
},
|
||||||
{ subject: ProjectPermissionSub.Role, actions: Object.values(ProjectPermissionActions) },
|
{
|
||||||
{
|
subject: ProjectPermissionSub.Secrets,
|
||||||
subject: ProjectPermissionSub.Settings,
|
actions: [
|
||||||
actions: [ProjectPermissionActions.Read, ProjectPermissionActions.Edit]
|
ProjectPermissionSecretActions.DescribeSecret,
|
||||||
},
|
ProjectPermissionSecretActions.ReadValue
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.DynamicSecrets,
|
||||||
|
actions: [ProjectPermissionDynamicSecretActions.ReadRootCredential]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.Environments,
|
||||||
|
actions: [ProjectPermissionActions.Read]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.Tags,
|
||||||
|
actions: [ProjectPermissionActions.Read]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.SecretRotation,
|
||||||
|
actions: [ProjectPermissionSecretRotationActions.Read]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.Integrations,
|
||||||
|
actions: [ProjectPermissionActions.Read]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.SecretSyncs,
|
||||||
|
actions: [ProjectPermissionSecretSyncActions.Read]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.Commits,
|
||||||
|
actions: [ProjectPermissionCommitsActions.Read]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "secret-editor",
|
||||||
|
name: "Secret Editing Policies",
|
||||||
|
description: "Grants read and edit access to secrets and related resources",
|
||||||
|
permissions: [
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.Environments,
|
||||||
|
actions: Object.values(ProjectPermissionActions)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.DynamicSecrets,
|
||||||
|
actions: Object.values(ProjectPermissionDynamicSecretActions)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.Secrets,
|
||||||
|
actions: [
|
||||||
|
ProjectPermissionSecretActions.DescribeSecret,
|
||||||
|
ProjectPermissionSecretActions.ReadValue,
|
||||||
|
ProjectPermissionSecretActions.Edit,
|
||||||
|
ProjectPermissionSecretActions.Create,
|
||||||
|
ProjectPermissionSecretActions.Delete
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.SecretRollback,
|
||||||
|
actions: [ProjectPermissionActions.Read, ProjectPermissionActions.Create]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.Tags,
|
||||||
|
actions: Object.values(ProjectPermissionActions)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.SecretImports,
|
||||||
|
actions: Object.values(ProjectPermissionActions)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.SecretRotation,
|
||||||
|
actions: Object.values(ProjectPermissionSecretRotationActions)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.SecretFolders,
|
||||||
|
actions: [
|
||||||
|
ProjectPermissionActions.Create,
|
||||||
|
ProjectPermissionActions.Edit,
|
||||||
|
ProjectPermissionActions.Delete
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.Integrations,
|
||||||
|
actions: Object.values(ProjectPermissionActions)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.SecretSyncs,
|
||||||
|
actions: Object.values(ProjectPermissionSecretSyncActions)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.Commits,
|
||||||
|
actions: Object.values(ProjectPermissionCommitsActions)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
projectManagerTemplate([
|
||||||
{
|
{
|
||||||
subject: ProjectPermissionSub.IpAllowList,
|
subject: ProjectPermissionSub.IpAllowList,
|
||||||
actions: Object.values(ProjectPermissionActions)
|
actions: Object.values(ProjectPermissionActions)
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
subject: ProjectPermissionSub.Kms,
|
||||||
|
actions: [ProjectPermissionActions.Edit]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
subject: ProjectPermissionSub.SecretApproval,
|
subject: ProjectPermissionSub.SecretApproval,
|
||||||
actions: Object.values(ProjectPermissionActions)
|
actions: Object.values(ProjectPermissionActions)
|
||||||
@@ -1692,314 +2029,6 @@ export const RoleTemplates = [
|
|||||||
subject: ProjectPermissionSub.Webhooks,
|
subject: ProjectPermissionSub.Webhooks,
|
||||||
actions: Object.values(ProjectPermissionActions)
|
actions: Object.values(ProjectPermissionActions)
|
||||||
}
|
}
|
||||||
]
|
])
|
||||||
},
|
]
|
||||||
{
|
};
|
||||||
id: "ssh-viewer",
|
|
||||||
name: "SSH Viewing Policies",
|
|
||||||
description: "Grants read access to SSH certificates and hosts",
|
|
||||||
permissions: [
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.SshCertificateAuthorities,
|
|
||||||
actions: [ProjectPermissionActions.Read]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.SshCertificates,
|
|
||||||
actions: [ProjectPermissionActions.Read]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.SshCertificateTemplates,
|
|
||||||
actions: [ProjectPermissionActions.Read]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.SshHosts,
|
|
||||||
actions: [ProjectPermissionSshHostActions.Read]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.SshHostGroups,
|
|
||||||
actions: [ProjectPermissionActions.Read]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "ssh-cert-editor",
|
|
||||||
name: "SSH Certificate Editing Policies",
|
|
||||||
description: "Grants read and edit access to SSH certificates",
|
|
||||||
permissions: [
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.SshCertificateAuthorities,
|
|
||||||
actions: Object.values(ProjectPermissionActions)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.SshCertificates,
|
|
||||||
actions: Object.values(ProjectPermissionActions)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.SshCertificateTemplates,
|
|
||||||
actions: Object.values(ProjectPermissionActions)
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "ssh-host-editor",
|
|
||||||
name: "SSH Host Editing Policies",
|
|
||||||
description: "Grants read and edit access to SSH hosts",
|
|
||||||
permissions: [
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.SshHosts,
|
|
||||||
actions: Object.values(ProjectPermissionSshHostActions)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.SshHostGroups,
|
|
||||||
actions: Object.values(ProjectPermissionActions)
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "kms-viewer",
|
|
||||||
name: "KMS Viewing Policies",
|
|
||||||
description: "Grants read access to KMS keys and KMIP clients",
|
|
||||||
permissions: [
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.Cmek,
|
|
||||||
actions: [ProjectPermissionCmekActions.Read]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.Kmip,
|
|
||||||
actions: [ProjectPermissionKmipActions.ReadClients]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "key-editor",
|
|
||||||
name: "KMS Key Editing Policies",
|
|
||||||
description: "Grants read and edit access to KMS keys",
|
|
||||||
permissions: [
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.Cmek,
|
|
||||||
actions: Object.values(ProjectPermissionCmekActions)
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "kmip-editor",
|
|
||||||
name: "KMIP Client Editing Policies",
|
|
||||||
description: "Grants read and edit access to KMIP clients",
|
|
||||||
permissions: [
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.Kmip,
|
|
||||||
actions: Object.values(ProjectPermissionKmipActions)
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "cert-viewer",
|
|
||||||
name: "Certificate Viewing Policies",
|
|
||||||
description: "Grants read access to certificates and related resources",
|
|
||||||
permissions: [
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.PkiCollections,
|
|
||||||
actions: [ProjectPermissionActions.Read]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.PkiAlerts,
|
|
||||||
actions: [ProjectPermissionActions.Read]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.CertificateAuthorities,
|
|
||||||
actions: [ProjectPermissionActions.Read]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.CertificateTemplates,
|
|
||||||
actions: [ProjectPermissionActions.Read]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.Certificates,
|
|
||||||
actions: [
|
|
||||||
ProjectPermissionCertificateActions.Read,
|
|
||||||
ProjectPermissionCertificateActions.ReadPrivateKey
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "cert-editor",
|
|
||||||
name: "Certificate Editing Policies",
|
|
||||||
description: "Grants read and edit access to certificates and related resources",
|
|
||||||
permissions: [
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.PkiCollections,
|
|
||||||
actions: Object.values(ProjectPermissionActions)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.PkiAlerts,
|
|
||||||
actions: Object.values(ProjectPermissionActions)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.CertificateAuthorities,
|
|
||||||
actions: Object.values(ProjectPermissionActions)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.CertificateTemplates,
|
|
||||||
actions: Object.values(ProjectPermissionActions)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.Certificates,
|
|
||||||
actions: Object.values(ProjectPermissionCertificateActions)
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "scanning-viewer",
|
|
||||||
name: "Secret Scanning Viewing Policies",
|
|
||||||
description: "Grants read access to data sources and findings",
|
|
||||||
permissions: [
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.SecretScanningDataSources,
|
|
||||||
actions: [
|
|
||||||
ProjectPermissionSecretScanningDataSourceActions.Read,
|
|
||||||
ProjectPermissionSecretScanningDataSourceActions.ReadResources,
|
|
||||||
ProjectPermissionSecretScanningDataSourceActions.ReadScans
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.SecretScanningFindings,
|
|
||||||
actions: [ProjectPermissionSecretScanningFindingActions.Read]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.SecretScanningConfigs,
|
|
||||||
actions: [ProjectPermissionSecretScanningConfigActions.Read]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "scanning-editor",
|
|
||||||
name: "Secret Scanning Editing Policies",
|
|
||||||
description: "Grants read and edit access to data sources and findings",
|
|
||||||
permissions: [
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.SecretScanningDataSources,
|
|
||||||
actions: Object.values(ProjectPermissionSecretScanningDataSourceActions)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.SecretScanningFindings,
|
|
||||||
actions: Object.values(ProjectPermissionSecretScanningFindingActions)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.SecretScanningConfigs,
|
|
||||||
actions: [ProjectPermissionSecretScanningConfigActions.Read]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "secret-viewer",
|
|
||||||
name: "Secret Viewing Policies",
|
|
||||||
description: "Grants read access to secrets and related resources",
|
|
||||||
permissions: [
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.SecretRollback,
|
|
||||||
actions: [ProjectPermissionActions.Read]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.SecretImports,
|
|
||||||
actions: [ProjectPermissionActions.Read]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.Secrets,
|
|
||||||
actions: [
|
|
||||||
ProjectPermissionSecretActions.DescribeSecret,
|
|
||||||
ProjectPermissionSecretActions.ReadValue
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.DynamicSecrets,
|
|
||||||
actions: [ProjectPermissionDynamicSecretActions.ReadRootCredential]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.Environments,
|
|
||||||
actions: [ProjectPermissionActions.Read]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.Tags,
|
|
||||||
actions: [ProjectPermissionActions.Read]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.SecretRotation,
|
|
||||||
actions: [ProjectPermissionSecretRotationActions.Read]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.Integrations,
|
|
||||||
actions: [ProjectPermissionActions.Read]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.SecretSyncs,
|
|
||||||
actions: [ProjectPermissionSecretSyncActions.Read]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.Commits,
|
|
||||||
actions: [ProjectPermissionCommitsActions.Read]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: "secret-editor",
|
|
||||||
name: "Secret Editing Policies",
|
|
||||||
description: "Grants read and edit access to secrets and related resources",
|
|
||||||
permissions: [
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.Environments,
|
|
||||||
actions: Object.values(ProjectPermissionActions)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.DynamicSecrets,
|
|
||||||
actions: Object.values(ProjectPermissionDynamicSecretActions)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.Secrets,
|
|
||||||
actions: [
|
|
||||||
ProjectPermissionSecretActions.DescribeSecret,
|
|
||||||
ProjectPermissionSecretActions.ReadValue,
|
|
||||||
ProjectPermissionSecretActions.Edit,
|
|
||||||
ProjectPermissionSecretActions.Create,
|
|
||||||
ProjectPermissionSecretActions.Delete
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.SecretRollback,
|
|
||||||
actions: [ProjectPermissionActions.Read, ProjectPermissionActions.Create]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.Tags,
|
|
||||||
actions: Object.values(ProjectPermissionActions)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.SecretImports,
|
|
||||||
actions: Object.values(ProjectPermissionActions)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.SecretRotation,
|
|
||||||
actions: Object.values(ProjectPermissionSecretRotationActions)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.SecretFolders,
|
|
||||||
actions: [
|
|
||||||
ProjectPermissionActions.Create,
|
|
||||||
ProjectPermissionActions.Edit,
|
|
||||||
ProjectPermissionActions.Delete
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.Integrations,
|
|
||||||
actions: Object.values(ProjectPermissionActions)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.SecretSyncs,
|
|
||||||
actions: Object.values(ProjectPermissionSecretSyncActions)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
subject: ProjectPermissionSub.Commits,
|
|
||||||
actions: Object.values(ProjectPermissionCommitsActions)
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|||||||
+4
-1
@@ -14,6 +14,7 @@ import { ProjectPermissionSet } from "@app/context/ProjectPermissionContext";
|
|||||||
import { evaluatePermissionsAbility } from "@app/helpers/permissions";
|
import { evaluatePermissionsAbility } from "@app/helpers/permissions";
|
||||||
import { useGetProjectRoleBySlug, useUpdateProjectRole } from "@app/hooks/api";
|
import { useGetProjectRoleBySlug, useUpdateProjectRole } from "@app/hooks/api";
|
||||||
import { ProjectMembershipRole } from "@app/hooks/api/roles/types";
|
import { ProjectMembershipRole } from "@app/hooks/api/roles/types";
|
||||||
|
import { ProjectType } from "@app/hooks/api/workspace/types";
|
||||||
|
|
||||||
import { AddPoliciesButton } from "./AddPoliciesButton";
|
import { AddPoliciesButton } from "./AddPoliciesButton";
|
||||||
import { DynamicSecretPermissionConditions } from "./DynamicSecretPermissionConditions";
|
import { DynamicSecretPermissionConditions } from "./DynamicSecretPermissionConditions";
|
||||||
@@ -121,6 +122,8 @@ export const RolePermissionsSection = ({ roleSlug, isDisabled }: Props) => {
|
|||||||
(role?.slug ?? "") as ProjectMembershipRole
|
(role?.slug ?? "") as ProjectMembershipRole
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const isSecretManagerProject = currentWorkspace.type === ProjectType.SecretManager;
|
||||||
|
|
||||||
const permissions = form.watch("permissions");
|
const permissions = form.watch("permissions");
|
||||||
|
|
||||||
const formattedPermissions = useMemo(
|
const formattedPermissions = useMemo(
|
||||||
@@ -206,7 +209,7 @@ export const RolePermissionsSection = ({ roleSlug, isDisabled }: Props) => {
|
|||||||
</div>
|
</div>
|
||||||
</FormProvider>
|
</FormProvider>
|
||||||
</form>
|
</form>
|
||||||
{showAccessTree && (
|
{isSecretManagerProject && showAccessTree && (
|
||||||
<AccessTree
|
<AccessTree
|
||||||
permissions={formattedPermissions}
|
permissions={formattedPermissions}
|
||||||
subject={showAccessTree}
|
subject={showAccessTree}
|
||||||
|
|||||||
Reference in New Issue
Block a user