feat(backend): add enforcementLevel into secret_approval_policies

This commit is contained in:
Alfonso Hernandez
2024-07-17 21:39:33 +02:00
parent 869fcd6541
commit 2c57bd94fb
6 changed files with 41 additions and 8 deletions
@@ -0,0 +1,15 @@
import { Knex } from "knex";
import { EnforcementLevel } from "@app/lib/types";
export async function up(knex: Knex): Promise<void> {
await knex.schema.table("secret_approval_policies", (table) => {
table.specificType("enforcementLevel", "VARCHAR(10)").notNullable().defaultTo(EnforcementLevel.Hard);
});
}
export async function down(knex: Knex): Promise<void> {
await knex.schema.table("secret_approval_policies", (table) => {
table.dropColumn("enforcementLevel");
});
}
@@ -5,6 +5,8 @@
import { z } from "zod"; import { z } from "zod";
import { EnforcementLevel } from "@app/lib/types";
import { TImmutableDBKeys } from "./models"; import { TImmutableDBKeys } from "./models";
export const SecretApprovalPoliciesSchema = z.object({ export const SecretApprovalPoliciesSchema = z.object({
@@ -12,6 +14,7 @@ export const SecretApprovalPoliciesSchema = z.object({
name: z.string(), name: z.string(),
secretPath: z.string().nullable().optional(), secretPath: z.string().nullable().optional(),
approvals: z.number().default(1), approvals: z.number().default(1),
enforcementLevel: z.nativeEnum(EnforcementLevel),
envId: z.string().uuid(), envId: z.string().uuid(),
createdAt: z.date(), createdAt: z.date(),
updatedAt: z.date() updatedAt: z.date()
@@ -2,6 +2,7 @@ import { nanoid } from "nanoid";
import { z } from "zod"; import { z } from "zod";
import { removeTrailingSlash } from "@app/lib/fn"; import { removeTrailingSlash } from "@app/lib/fn";
import { EnforcementLevel } from "@app/lib/types";
import { readLimit, writeLimit } from "@app/server/config/rateLimiter"; import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth"; import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { sapPubSchema } from "@app/server/routes/sanitizedSchemas"; import { sapPubSchema } from "@app/server/routes/sanitizedSchemas";
@@ -26,7 +27,8 @@ export const registerSecretApprovalPolicyRouter = async (server: FastifyZodProvi
.nullable() .nullable()
.transform((val) => (val ? removeTrailingSlash(val) : val)), .transform((val) => (val ? removeTrailingSlash(val) : val)),
approvers: z.string().array().min(1), approvers: z.string().array().min(1),
approvals: z.number().min(1).default(1) approvals: z.number().min(1).default(1),
enforcementLevel: z.nativeEnum(EnforcementLevel)
}) })
.refine((data) => data.approvals <= data.approvers.length, { .refine((data) => data.approvals <= data.approvers.length, {
path: ["approvals"], path: ["approvals"],
@@ -47,7 +49,8 @@ export const registerSecretApprovalPolicyRouter = async (server: FastifyZodProvi
actorOrgId: req.permission.orgId, actorOrgId: req.permission.orgId,
projectId: req.body.workspaceId, projectId: req.body.workspaceId,
...req.body, ...req.body,
name: req.body.name ?? `${req.body.environment}-${nanoid(3)}` name: req.body.name ?? `${req.body.environment}-${nanoid(3)}`,
enforcementLevel: req.body.enforcementLevel ?? EnforcementLevel.Hard
}); });
return { approval }; return { approval };
} }
@@ -72,7 +75,8 @@ export const registerSecretApprovalPolicyRouter = async (server: FastifyZodProvi
.string() .string()
.optional() .optional()
.nullable() .nullable()
.transform((val) => (val ? removeTrailingSlash(val) : val)) .transform((val) => (val ? removeTrailingSlash(val) : val)),
enforcementLevel: z.nativeEnum(EnforcementLevel)
}) })
.refine((data) => data.approvals <= data.approvers.length, { .refine((data) => data.approvals <= data.approvers.length, {
path: ["approvals"], path: ["approvals"],
@@ -48,7 +48,8 @@ export const secretApprovalPolicyServiceFactory = ({
approvers, approvers,
projectId, projectId,
secretPath, secretPath,
environment environment,
enforcementLevel
}: TCreateSapDTO) => { }: TCreateSapDTO) => {
if (approvals > approvers.length) if (approvals > approvers.length)
throw new BadRequestError({ message: "Approvals cannot be greater than approvers" }); throw new BadRequestError({ message: "Approvals cannot be greater than approvers" });
@@ -73,7 +74,8 @@ export const secretApprovalPolicyServiceFactory = ({
envId: env.id, envId: env.id,
approvals, approvals,
secretPath, secretPath,
name name,
enforcementLevel
}, },
tx tx
); );
@@ -98,7 +100,8 @@ export const secretApprovalPolicyServiceFactory = ({
actorOrgId, actorOrgId,
actorAuthMethod, actorAuthMethod,
approvals, approvals,
secretPolicyId secretPolicyId,
enforcementLevel
}: TUpdateSapDTO) => { }: TUpdateSapDTO) => {
const secretApprovalPolicy = await secretApprovalPolicyDAL.findById(secretPolicyId); const secretApprovalPolicy = await secretApprovalPolicyDAL.findById(secretPolicyId);
if (!secretApprovalPolicy) throw new BadRequestError({ message: "Secret approval policy not found" }); if (!secretApprovalPolicy) throw new BadRequestError({ message: "Secret approval policy not found" });
@@ -118,7 +121,8 @@ export const secretApprovalPolicyServiceFactory = ({
{ {
approvals, approvals,
secretPath, secretPath,
name name,
enforcementLevel
}, },
tx tx
); );
@@ -1,4 +1,4 @@
import { TProjectPermission } from "@app/lib/types"; import { EnforcementLevel, TProjectPermission } from "@app/lib/types";
export type TCreateSapDTO = { export type TCreateSapDTO = {
approvals: number; approvals: number;
@@ -7,6 +7,7 @@ export type TCreateSapDTO = {
approvers: string[]; approvers: string[];
projectId: string; projectId: string;
name: string; name: string;
enforcementLevel: EnforcementLevel;
} & Omit<TProjectPermission, "projectId">; } & Omit<TProjectPermission, "projectId">;
export type TUpdateSapDTO = { export type TUpdateSapDTO = {
@@ -15,6 +16,7 @@ export type TUpdateSapDTO = {
secretPath?: string | null; secretPath?: string | null;
approvers: string[]; approvers: string[];
name?: string; name?: string;
enforcementLevel?: EnforcementLevel;
} & Omit<TProjectPermission, "projectId">; } & Omit<TProjectPermission, "projectId">;
export type TDeleteSapDTO = { export type TDeleteSapDTO = {
+5
View File
@@ -42,3 +42,8 @@ export type RequiredKeys<T> = {
}[keyof T]; }[keyof T];
export type PickRequired<T> = Pick<T, RequiredKeys<T>>; export type PickRequired<T> = Pick<T, RequiredKeys<T>>;
export enum EnforcementLevel {
Hard = "hard",
Soft = "soft"
}