feat(secret-approval): added permission for policy management and fixed bugs on fellow user reviewing secrets

This commit is contained in:
Akhil Mohan
2023-10-05 20:34:50 +05:30
parent 9dc97f7208
commit df636c91b4
13 changed files with 128 additions and 50 deletions
@@ -6,8 +6,9 @@ import { ApprovalStatus, SecretApprovalRequest } from "../../models/secretApprov
import * as reqValidator from "../../validation/secretApprovalRequest";
import { getFolderWithPathFromId } from "../../services/FolderService";
import { BadRequestError, UnauthorizedRequestError } from "../../utils/errors";
import { ISecretApprovalPolicy } from "../../models/secretApprovalPolicy";
import { ISecretApprovalPolicy, SecretApprovalPolicy } from "../../models/secretApprovalPolicy";
import { performSecretApprovalRequestMerge } from "../../services/SecretApprovalService";
import { Types } from "mongoose";
export const getSecretApprovalRequests = async (req: Request, res: Response) => {
const {
@@ -17,24 +18,43 @@ export const getSecretApprovalRequests = async (req: Request, res: Response) =>
const { membership } = await getUserProjectPermissions(req.user._id, workspaceId);
const query = {
workspace: workspaceId,
workspace: new Types.ObjectId(workspaceId),
environment,
committer,
status,
...(membership.role !== "admin"
? { $or: [{ committer: membership.id }, { "policy.approvers": membership.id }] }
: {})
committer: committer ? new Types.ObjectId(committer) : undefined,
status
};
// to strip of undefined in query we use es6 spread to ignore those fields
Object.entries(query).forEach(
([key, value]) => value === undefined && delete query[key as keyof typeof query]
);
const approvalRequests = await SecretApprovalRequest.find(query)
.sort({ createdAt: -1 })
.limit(limit)
.skip(offset)
.populate("policy")
.lean();
const approvalRequests = await SecretApprovalRequest.aggregate([
{
$match: query
},
{
$lookup: {
from: SecretApprovalPolicy.collection.name,
localField: "policy",
foreignField: "_id",
as: "policy"
}
},
{ $unwind: "$policy" },
...(membership.role !== "admin"
? [
{
$match: {
$or: [
{ committer: new Types.ObjectId(membership.id) },
{ "policy.approvers": new Types.ObjectId(membership.id) }
]
}
}
]
: []),
{ $skip: offset },
{ $limit: limit }
]);
if (!approvalRequests.length) return res.send({ approvals: [] });
const unqiueEnvs = environment ?? {
@@ -114,7 +134,7 @@ export const updateSecretApprovalReviewStatus = async (req: Request, res: Respon
if (
membership.role !== "admin" &&
secretApprovalRequest.committer !== membership.id &&
!secretApprovalRequest.policy.approvers.find((approverId) => approverId === membership.id)
!secretApprovalRequest.policy.approvers.find((approverId) => approverId.equals(membership.id))
) {
throw UnauthorizedRequestError({ message: "User has no access" });
}
@@ -42,7 +42,7 @@ export const getSecretPolicyOfBoard = async (
// now sort by priority. exact secret path gets first match followed by glob followed by just env scoped
// if that is tie get by first createdAt
const policiesByPriority = policiesFilteredByPath.sort(
(a, b) => getPolicyScore(a) - getPolicyScore(b)
(a, b) => getPolicyScore(b) - getPolicyScore(a)
);
const finalPolicy = policiesByPriority.shift();
return finalPolicy;