feat(api): improve errors and error handling

This commit is contained in:
Daniel Hougaard
2024-09-27 20:02:43 +04:00
parent 02c51b05b6
commit 2d51ed317f
99 changed files with 922 additions and 847 deletions
@@ -1,10 +1,10 @@
import { ForbiddenError, subject } from "@casl/ability";
import { BadRequestError } from "@app/lib/errors";
import { BadRequestError, ForbiddenRequestError } from "@app/lib/errors";
import { ActorType } from "@app/services/auth/auth-type";
import { ProjectPermissionActions, ProjectPermissionSub } from "../permission/project-permission";
import { TVerifyApprovers } from "./access-approval-policy-types";
import { TVerifyApprovers, VerifyApproversError } from "./access-approval-policy-types";
export const verifyApprovers = async ({
userIds,
@@ -13,7 +13,8 @@ export const verifyApprovers = async ({
envSlug,
actorAuthMethod,
secretPath,
permissionService
permissionService,
error
}: TVerifyApprovers) => {
for await (const userId of userIds) {
try {
@@ -30,7 +31,16 @@ export const verifyApprovers = async ({
subject(ProjectPermissionSub.Secrets, { environment: envSlug, secretPath })
);
} catch (err) {
throw new BadRequestError({ message: "One or more approvers doesn't have access to be specified secret path" });
if (error === VerifyApproversError.BadRequestError) {
throw new BadRequestError({
message: "One or more approvers doesn't have access to be specified secret path"
});
}
if (error === VerifyApproversError.ForbiddenError) {
throw new ForbiddenRequestError({
message: "You don't have access to approve this request"
});
}
}
}
};
@@ -19,7 +19,8 @@ import {
TGetAccessApprovalPolicyByIdDTO,
TGetAccessPolicyCountByEnvironmentDTO,
TListAccessApprovalPoliciesDTO,
TUpdateAccessApprovalPolicy
TUpdateAccessApprovalPolicy,
VerifyApproversError
} from "./access-approval-policy-types";
type TSecretApprovalPolicyServiceFactoryDep = {
@@ -58,7 +59,7 @@ export const accessApprovalPolicyServiceFactory = ({
enforcementLevel
}: TCreateAccessApprovalPolicy) => {
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
if (!project) throw new BadRequestError({ message: "Project not found" });
if (!project) throw new NotFoundError({ message: "Project not found" });
// If there is a group approver people might be added to the group later to meet the approvers quota
const groupApprovers = approvers
@@ -89,7 +90,7 @@ export const accessApprovalPolicyServiceFactory = ({
ProjectPermissionSub.SecretApproval
);
const env = await projectEnvDAL.findOne({ slug: environment, projectId: project.id });
if (!env) throw new BadRequestError({ message: "Environment not found" });
if (!env) throw new NotFoundError({ message: "Environment not found" });
let approverUserIds = userApprovers;
if (userApproverNames.length) {
@@ -139,7 +140,8 @@ export const accessApprovalPolicyServiceFactory = ({
secretPath,
actorAuthMethod,
permissionService,
userIds: verifyAllApprovers
userIds: verifyAllApprovers,
error: VerifyApproversError.BadRequestError
});
const accessApproval = await accessApprovalPolicyDAL.transaction(async (tx) => {
@@ -186,7 +188,7 @@ export const accessApprovalPolicyServiceFactory = ({
projectSlug
}: TListAccessApprovalPoliciesDTO) => {
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
if (!project) throw new BadRequestError({ message: "Project not found" });
if (!project) throw new NotFoundError({ message: "Project not found" });
// Anyone in the project should be able to get the policies.
/* const { permission } = */ await permissionService.getProjectPermission(
@@ -237,7 +239,7 @@ export const accessApprovalPolicyServiceFactory = ({
throw new BadRequestError({ message: "Approvals cannot be greater than approvers" });
}
if (!accessApprovalPolicy) throw new BadRequestError({ message: "Secret approval policy not found" });
if (!accessApprovalPolicy) throw new NotFoundError({ message: "Secret approval policy not found" });
const { permission } = await permissionService.getProjectPermission(
actor,
actorId,
@@ -290,7 +292,8 @@ export const accessApprovalPolicyServiceFactory = ({
secretPath: doc.secretPath!,
actorAuthMethod,
permissionService,
userIds: userApproverIds
userIds: userApproverIds,
error: VerifyApproversError.BadRequestError
});
await accessApprovalPolicyApproverDAL.insertMany(
@@ -329,7 +332,8 @@ export const accessApprovalPolicyServiceFactory = ({
secretPath: doc.secretPath!,
actorAuthMethod,
permissionService,
userIds: verifyGroupApprovers
userIds: verifyGroupApprovers,
error: VerifyApproversError.BadRequestError
});
await accessApprovalPolicyApproverDAL.insertMany(
groupApprovers.map((groupId) => ({
@@ -357,7 +361,7 @@ export const accessApprovalPolicyServiceFactory = ({
actorOrgId
}: TDeleteAccessApprovalPolicy) => {
const policy = await accessApprovalPolicyDAL.findById(policyId);
if (!policy) throw new BadRequestError({ message: "Secret approval policy not found" });
if (!policy) throw new NotFoundError({ message: "Secret approval policy not found" });
const { permission } = await permissionService.getProjectPermission(
actor,
@@ -385,7 +389,7 @@ export const accessApprovalPolicyServiceFactory = ({
}: TGetAccessPolicyCountByEnvironmentDTO) => {
const project = await projectDAL.findProjectBySlug(projectSlug, actorOrgId);
if (!project) throw new BadRequestError({ message: "Project not found" });
if (!project) throw new NotFoundError({ message: "Project not found" });
const { membership } = await permissionService.getProjectPermission(
actor,
@@ -394,13 +398,13 @@ export const accessApprovalPolicyServiceFactory = ({
actorAuthMethod,
actorOrgId
);
if (!membership) throw new BadRequestError({ message: "User not found in project" });
if (!membership) throw new NotFoundError({ message: "User not found in project" });
const environment = await projectEnvDAL.findOne({ projectId: project.id, slug: envSlug });
if (!environment) throw new BadRequestError({ message: "Environment not found" });
if (!environment) throw new NotFoundError({ message: "Environment not found" });
const policies = await accessApprovalPolicyDAL.find({ envId: environment.id, projectId: project.id });
if (!policies) throw new BadRequestError({ message: "No policies found" });
if (!policies) throw new NotFoundError({ message: "No policies found" });
return { count: policies.length };
};
@@ -3,6 +3,11 @@ import { ActorAuthMethod } from "@app/services/auth/auth-type";
import { TPermissionServiceFactory } from "../permission/permission-service";
export enum VerifyApproversError {
ForbiddenError = "ForbiddenError",
BadRequestError = "BadRequestError"
}
export type TVerifyApprovers = {
userIds: string[];
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
@@ -11,6 +16,7 @@ export type TVerifyApprovers = {
secretPath: string;
projectId: string;
orgId: string;
error: VerifyApproversError;
};
export enum ApproverType {