feat(backemd): accept soft approvals on secret requests

This commit is contained in:
Alfonso Hernandez
2024-07-18 01:02:57 +02:00
parent c331af5345
commit aed310b9ee
3 changed files with 15 additions and 5 deletions
@@ -49,7 +49,8 @@ export const registerSecretApprovalRequestRouter = async (server: FastifyZodProv
name: z.string(), name: z.string(),
approvals: z.number(), approvals: z.number(),
approvers: z.string().array(), approvers: z.string().array(),
secretPath: z.string().optional().nullable() secretPath: z.string().optional().nullable(),
enforcementLevel: z.string()
}), }),
committerUser: approvalRequestUser, committerUser: approvalRequestUser,
commits: z.object({ op: z.string(), secretId: z.string().nullable().optional() }).array(), commits: z.object({ op: z.string(), secretId: z.string().nullable().optional() }).array(),
@@ -248,7 +249,8 @@ export const registerSecretApprovalRequestRouter = async (server: FastifyZodProv
name: z.string(), name: z.string(),
approvals: z.number(), approvals: z.number(),
approvers: approvalRequestUser.array(), approvers: approvalRequestUser.array(),
secretPath: z.string().optional().nullable() secretPath: z.string().optional().nullable(),
enforcementLevel: z.string()
}), }),
environment: z.string(), environment: z.string(),
statusChangedByUser: approvalRequestUser.optional(), statusChangedByUser: approvalRequestUser.optional(),
@@ -94,6 +94,7 @@ export const secretApprovalRequestDALFactory = (db: TDbClient) => {
tx.ref("projectId").withSchema(TableName.Environment), tx.ref("projectId").withSchema(TableName.Environment),
tx.ref("slug").withSchema(TableName.Environment).as("environment"), tx.ref("slug").withSchema(TableName.Environment).as("environment"),
tx.ref("secretPath").withSchema(TableName.SecretApprovalPolicy).as("policySecretPath"), tx.ref("secretPath").withSchema(TableName.SecretApprovalPolicy).as("policySecretPath"),
tx.ref("enforcementLevel").withSchema(TableName.SecretApprovalPolicy).as("policyEnforcementLevel"),
tx.ref("approvals").withSchema(TableName.SecretApprovalPolicy).as("policyApprovals") tx.ref("approvals").withSchema(TableName.SecretApprovalPolicy).as("policyApprovals")
); );
@@ -128,7 +129,8 @@ export const secretApprovalRequestDALFactory = (db: TDbClient) => {
id: el.policyId, id: el.policyId,
name: el.policyName, name: el.policyName,
approvals: el.policyApprovals, approvals: el.policyApprovals,
secretPath: el.policySecretPath secretPath: el.policySecretPath,
enforcementLevel: el.policyEnforcementLevel
} }
}), }),
childrenMapper: [ childrenMapper: [
@@ -282,6 +284,7 @@ export const secretApprovalRequestDALFactory = (db: TDbClient) => {
`DENSE_RANK() OVER (partition by ${TableName.Environment}."projectId" ORDER BY ${TableName.SecretApprovalRequest}."id" DESC) as rank` `DENSE_RANK() OVER (partition by ${TableName.Environment}."projectId" ORDER BY ${TableName.SecretApprovalRequest}."id" DESC) as rank`
), ),
db.ref("secretPath").withSchema(TableName.SecretApprovalPolicy).as("policySecretPath"), db.ref("secretPath").withSchema(TableName.SecretApprovalPolicy).as("policySecretPath"),
db.ref("enforcementLevel").withSchema(TableName.SecretApprovalPolicy).as("policyEnforcementLevel"),
db.ref("approvals").withSchema(TableName.SecretApprovalPolicy).as("policyApprovals"), db.ref("approvals").withSchema(TableName.SecretApprovalPolicy).as("policyApprovals"),
db.ref("approverUserId").withSchema(TableName.SecretApprovalPolicyApprover), db.ref("approverUserId").withSchema(TableName.SecretApprovalPolicyApprover),
db.ref("email").withSchema("committerUser").as("committerUserEmail"), db.ref("email").withSchema("committerUser").as("committerUserEmail"),
@@ -308,7 +311,8 @@ export const secretApprovalRequestDALFactory = (db: TDbClient) => {
id: el.policyId, id: el.policyId,
name: el.policyName, name: el.policyName,
approvals: el.policyApprovals, approvals: el.policyApprovals,
secretPath: el.policySecretPath secretPath: el.policySecretPath,
enforcementLevel: el.policyEnforcementLevel
}, },
committerUser: { committerUser: {
userId: el.committerUserId, userId: el.committerUserId,
@@ -11,6 +11,7 @@ import { decryptSymmetric128BitHexKeyUTF8 } from "@app/lib/crypto";
import { BadRequestError, UnauthorizedError } from "@app/lib/errors"; import { BadRequestError, UnauthorizedError } from "@app/lib/errors";
import { groupBy, pick, unique } from "@app/lib/fn"; import { groupBy, pick, unique } from "@app/lib/fn";
import { alphaNumericNanoId } from "@app/lib/nanoid"; import { alphaNumericNanoId } from "@app/lib/nanoid";
import { EnforcementLevel } from "@app/lib/types";
import { ActorType } from "@app/services/auth/auth-type"; import { ActorType } from "@app/services/auth/auth-type";
import { TProjectDALFactory } from "@app/services/project/project-dal"; import { TProjectDALFactory } from "@app/services/project/project-dal";
import { TProjectBotServiceFactory } from "@app/services/project-bot/project-bot-service"; import { TProjectBotServiceFactory } from "@app/services/project-bot/project-bot-service";
@@ -289,7 +290,10 @@ export const secretApprovalRequestServiceFactory = ({
({ userId: approverId }) => reviewers[approverId.toString()] === ApprovalStatus.APPROVED ({ userId: approverId }) => reviewers[approverId.toString()] === ApprovalStatus.APPROVED
).length; ).length;
if (!hasMinApproval) throw new BadRequestError({ message: "Doesn't have minimum approvals needed" }); const isSoftPolicy = secretApprovalRequest.policy.enforcementLevel === EnforcementLevel.Soft;
if (!hasMinApproval && !isSoftPolicy)
throw new BadRequestError({ message: "Doesn't have minimum approvals needed" });
const secretApprovalSecrets = await secretApprovalRequestSecretDAL.findByRequestId(secretApprovalRequest.id); const secretApprovalSecrets = await secretApprovalRequestSecretDAL.findByRequestId(secretApprovalRequest.id);
if (!secretApprovalSecrets) throw new BadRequestError({ message: "No secrets found" }); if (!secretApprovalSecrets) throw new BadRequestError({ message: "No secrets found" });