mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-07 19:28:09 +00:00
move v2 secret api to controller
This commit is contained in:
@@ -1,5 +1,7 @@
|
|||||||
import * as workspaceController from './workspaceController';
|
import * as workspaceController from './workspaceController';
|
||||||
|
import * as secretController from './secretController';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
workspaceController
|
workspaceController,
|
||||||
|
secretController
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,138 @@
|
|||||||
|
import to from "await-to-js";
|
||||||
|
import { Request, Response } from "express";
|
||||||
|
import mongoose, { Types } from "mongoose";
|
||||||
|
import Secret, { ISecret } from "../../models/secret";
|
||||||
|
import { CreateSecretRequestBody, ModifySecretRequestBody, SanitizedSecretForCreate, SanitizedSecretModify } from "../../types/secret/types";
|
||||||
|
const { ValidationError } = mongoose.Error;
|
||||||
|
import { BadRequestError, InternalServerError, UnauthorizedRequestError, ValidationError as RouteValidationError } from '../../utils/errors';
|
||||||
|
import { AnyBulkWriteOperation } from 'mongodb';
|
||||||
|
|
||||||
|
export const batchCreateSecrets = async (req: Request, res: Response) => {
|
||||||
|
const secretsToCreate: CreateSecretRequestBody[] = req.body.secrets;
|
||||||
|
const { workspaceId, environmentName } = req.params
|
||||||
|
const sanitizedSecretesToCreate: SanitizedSecretForCreate[] = []
|
||||||
|
|
||||||
|
secretsToCreate.forEach(rawSecret => {
|
||||||
|
const safeUpdateFields: SanitizedSecretForCreate = {
|
||||||
|
secretKeyCiphertext: rawSecret.secretKeyCiphertext,
|
||||||
|
secretKeyIV: rawSecret.secretKeyIV,
|
||||||
|
secretKeyTag: rawSecret.secretKeyTag,
|
||||||
|
secretKeyHash: rawSecret.secretKeyHash,
|
||||||
|
secretValueCiphertext: rawSecret.secretValueCiphertext,
|
||||||
|
secretValueIV: rawSecret.secretValueIV,
|
||||||
|
secretValueTag: rawSecret.secretValueTag,
|
||||||
|
secretValueHash: rawSecret.secretValueHash,
|
||||||
|
secretCommentCiphertext: rawSecret.secretCommentCiphertext,
|
||||||
|
secretCommentIV: rawSecret.secretCommentIV,
|
||||||
|
secretCommentTag: rawSecret.secretCommentTag,
|
||||||
|
secretCommentHash: rawSecret.secretCommentHash,
|
||||||
|
workspace: new Types.ObjectId(workspaceId),
|
||||||
|
environment: environmentName,
|
||||||
|
type: rawSecret.type,
|
||||||
|
user: new Types.ObjectId(req.user._id)
|
||||||
|
}
|
||||||
|
|
||||||
|
sanitizedSecretesToCreate.push(safeUpdateFields)
|
||||||
|
})
|
||||||
|
|
||||||
|
const [bulkCreateError, newlyCreatedSecrets] = await to(Secret.insertMany(sanitizedSecretesToCreate).then())
|
||||||
|
if (bulkCreateError) {
|
||||||
|
if (bulkCreateError instanceof ValidationError) {
|
||||||
|
throw RouteValidationError({ message: bulkCreateError.message, stack: bulkCreateError.stack })
|
||||||
|
}
|
||||||
|
|
||||||
|
throw InternalServerError({ message: "Unable to process your batch create request. Please try again", stack: bulkCreateError.stack })
|
||||||
|
}
|
||||||
|
|
||||||
|
res.status(200).send()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export const createSingleSecret = async (req: Request, res: Response) => {
|
||||||
|
try {
|
||||||
|
const secretFromDB = await Secret.findById(req.params.secretId)
|
||||||
|
return res.status(200).send(secretFromDB);
|
||||||
|
} catch (e) {
|
||||||
|
throw BadRequestError({ message: "Unable to find the requested secret" })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const batchDeleteSecrets = async (req: Request, res: Response) => {
|
||||||
|
const { workspaceId, environmentName } = req.params
|
||||||
|
const secretIdsToDelete: string[] = req.body.secretIds
|
||||||
|
|
||||||
|
const [secretIdsUserCanDeleteError, secretIdsUserCanDelete] = await to(Secret.find({ workspace: workspaceId, environment: environmentName }, { _id: 1 }).then())
|
||||||
|
if (secretIdsUserCanDeleteError) {
|
||||||
|
throw InternalServerError({ message: `Unable to fetch secrets you own: [error=${secretIdsUserCanDeleteError.message}]` })
|
||||||
|
}
|
||||||
|
|
||||||
|
const secretsUserCanDeleteSet: Set<string> = new Set(secretIdsUserCanDelete.map(objectId => objectId._id.toString()));
|
||||||
|
const deleteOperationsToPerform: AnyBulkWriteOperation<ISecret>[] = []
|
||||||
|
|
||||||
|
secretIdsToDelete.forEach(secretIdToDelete => {
|
||||||
|
if (secretsUserCanDeleteSet.has(secretIdToDelete)) {
|
||||||
|
const deleteOperation = { deleteOne: { filter: { _id: new Types.ObjectId(secretIdToDelete) } } }
|
||||||
|
deleteOperationsToPerform.push(deleteOperation)
|
||||||
|
} else {
|
||||||
|
throw RouteValidationError({ message: "You cannot delete secrets that you do not have access to" })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const [bulkDeleteError, bulkDelete] = await to(Secret.bulkWrite(deleteOperationsToPerform).then())
|
||||||
|
if (bulkDeleteError) {
|
||||||
|
if (bulkDeleteError instanceof ValidationError) {
|
||||||
|
throw RouteValidationError({ message: "Unable to apply modifications, please try again", stack: bulkDeleteError.stack })
|
||||||
|
}
|
||||||
|
throw InternalServerError()
|
||||||
|
}
|
||||||
|
|
||||||
|
res.status(200).send()
|
||||||
|
}
|
||||||
|
|
||||||
|
export const batchModifySecrets = async (req: Request, res: Response) => {
|
||||||
|
const { workspaceId, environmentName } = req.params
|
||||||
|
const secretsModificationsRequested: ModifySecretRequestBody[] = req.body.secrets;
|
||||||
|
const [secretIdsUserCanModifyError, secretIdsUserCanModify] = await to(Secret.find({ workspace: workspaceId, environment: environmentName }, { _id: 1 }).then())
|
||||||
|
if (secretIdsUserCanModifyError) {
|
||||||
|
throw InternalServerError({ message: "Unable to fetch secrets you own" })
|
||||||
|
}
|
||||||
|
|
||||||
|
const secretsUserCanModifySet: Set<string> = new Set(secretIdsUserCanModify.map(objectId => objectId._id.toString()));
|
||||||
|
const updateOperationsToPerform: any = []
|
||||||
|
|
||||||
|
|
||||||
|
secretsModificationsRequested.forEach(userModifiedSecret => {
|
||||||
|
if (secretsUserCanModifySet.has(userModifiedSecret._id.toString())) {
|
||||||
|
const sanitizedSecret: SanitizedSecretModify = {
|
||||||
|
secretKeyCiphertext: userModifiedSecret.secretKeyCiphertext,
|
||||||
|
secretKeyIV: userModifiedSecret.secretKeyIV,
|
||||||
|
secretKeyTag: userModifiedSecret.secretKeyTag,
|
||||||
|
secretKeyHash: userModifiedSecret.secretKeyHash,
|
||||||
|
secretValueCiphertext: userModifiedSecret.secretValueCiphertext,
|
||||||
|
secretValueIV: userModifiedSecret.secretValueIV,
|
||||||
|
secretValueTag: userModifiedSecret.secretValueTag,
|
||||||
|
secretValueHash: userModifiedSecret.secretValueHash,
|
||||||
|
secretCommentCiphertext: userModifiedSecret.secretCommentCiphertext,
|
||||||
|
secretCommentIV: userModifiedSecret.secretCommentIV,
|
||||||
|
secretCommentTag: userModifiedSecret.secretCommentTag,
|
||||||
|
secretCommentHash: userModifiedSecret.secretCommentHash,
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateOperation = { updateOne: { filter: { _id: userModifiedSecret._id, workspace: workspaceId }, update: { $inc: { version: 1 }, $set: sanitizedSecret } } }
|
||||||
|
updateOperationsToPerform.push(updateOperation)
|
||||||
|
} else {
|
||||||
|
throw UnauthorizedRequestError({ message: "You do not have permission to modify one or more of the requested secrets" })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const [bulkModificationInfoError, bulkModificationInfo] = await to(Secret.bulkWrite(updateOperationsToPerform).then())
|
||||||
|
if (bulkModificationInfoError) {
|
||||||
|
if (bulkModificationInfoError instanceof ValidationError) {
|
||||||
|
throw RouteValidationError({ message: "Unable to apply modifications, please try again", stack: bulkModificationInfoError.stack })
|
||||||
|
}
|
||||||
|
|
||||||
|
throw InternalServerError()
|
||||||
|
}
|
||||||
|
|
||||||
|
return res.status(200).send()
|
||||||
|
}
|
||||||
+11
-133
@@ -1,14 +1,9 @@
|
|||||||
import express, { Request, Response } from 'express';
|
import express from 'express';
|
||||||
import { requireAuth, requireWorkspaceAuth, validateRequest } from '../../middleware';
|
import { requireAuth, requireWorkspaceAuth, validateRequest } from '../../middleware';
|
||||||
import { ISecret, Secret } from '../../models';
|
import { body, param } from 'express-validator';
|
||||||
import { body, param, query, check } from 'express-validator';
|
|
||||||
import { BadRequestError, InternalServerError, UnauthorizedRequestError, ValidationError as RouteValidationError } from '../../utils/errors';
|
|
||||||
import { ADMIN, MEMBER, COMPLETED, GRANTED } from '../../variables';
|
import { ADMIN, MEMBER, COMPLETED, GRANTED } from '../../variables';
|
||||||
import { SanitizedSecretModify, CreateSecretRequestBody, SanitizedSecretForCreate, ModifySecretRequestBody } from '../../types/secret/types';
|
import { CreateSecretRequestBody, ModifySecretRequestBody } from '../../types/secret/types';
|
||||||
import to from 'await-to-js';
|
import { secretController } from '../../controllers/v2';
|
||||||
import mongoose, { Types } from 'mongoose';
|
|
||||||
import { AnyBulkWriteOperation } from 'mongodb';
|
|
||||||
const { ValidationError } = mongoose.Error;
|
|
||||||
|
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
@@ -26,45 +21,7 @@ router.post(
|
|||||||
param('environmentName').exists().trim(),
|
param('environmentName').exists().trim(),
|
||||||
body('secrets').exists().isArray().custom((value) => value.every((item: CreateSecretRequestBody) => typeof item === 'object')),
|
body('secrets').exists().isArray().custom((value) => value.every((item: CreateSecretRequestBody) => typeof item === 'object')),
|
||||||
validateRequest,
|
validateRequest,
|
||||||
async (req: Request, res: Response) => {
|
secretController.batchCreateSecrets
|
||||||
const secretsToCreate: CreateSecretRequestBody[] = req.body.secrets;
|
|
||||||
const { workspaceId, environmentName } = req.params
|
|
||||||
const sanitizedSecretesToCreate: SanitizedSecretForCreate[] = []
|
|
||||||
|
|
||||||
secretsToCreate.forEach(rawSecret => {
|
|
||||||
const safeUpdateFields: SanitizedSecretForCreate = {
|
|
||||||
secretKeyCiphertext: rawSecret.secretKeyCiphertext,
|
|
||||||
secretKeyIV: rawSecret.secretKeyIV,
|
|
||||||
secretKeyTag: rawSecret.secretKeyTag,
|
|
||||||
secretKeyHash: rawSecret.secretKeyHash,
|
|
||||||
secretValueCiphertext: rawSecret.secretValueCiphertext,
|
|
||||||
secretValueIV: rawSecret.secretValueIV,
|
|
||||||
secretValueTag: rawSecret.secretValueTag,
|
|
||||||
secretValueHash: rawSecret.secretValueHash,
|
|
||||||
secretCommentCiphertext: rawSecret.secretCommentCiphertext,
|
|
||||||
secretCommentIV: rawSecret.secretCommentIV,
|
|
||||||
secretCommentTag: rawSecret.secretCommentTag,
|
|
||||||
secretCommentHash: rawSecret.secretCommentHash,
|
|
||||||
workspace: new Types.ObjectId(workspaceId),
|
|
||||||
environment: environmentName,
|
|
||||||
type: rawSecret.type,
|
|
||||||
user: new Types.ObjectId(req.user._id)
|
|
||||||
}
|
|
||||||
|
|
||||||
sanitizedSecretesToCreate.push(safeUpdateFields)
|
|
||||||
})
|
|
||||||
|
|
||||||
const [bulkCreateError, newlyCreatedSecrets] = await to(Secret.insertMany(sanitizedSecretesToCreate).then())
|
|
||||||
if (bulkCreateError) {
|
|
||||||
if (bulkCreateError instanceof ValidationError) {
|
|
||||||
throw RouteValidationError({ message: bulkCreateError.message, stack: bulkCreateError.stack })
|
|
||||||
}
|
|
||||||
|
|
||||||
throw InternalServerError({ message: "Unable to process your batch create request. Please try again", stack: bulkCreateError.stack })
|
|
||||||
}
|
|
||||||
|
|
||||||
res.status(200).send()
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -76,14 +33,8 @@ router.get(
|
|||||||
acceptedRoles: [ADMIN, MEMBER],
|
acceptedRoles: [ADMIN, MEMBER],
|
||||||
acceptedStatuses: [COMPLETED, GRANTED]
|
acceptedStatuses: [COMPLETED, GRANTED]
|
||||||
}),
|
}),
|
||||||
validateRequest, async (req: Request, res: Response) => {
|
validateRequest,
|
||||||
try {
|
secretController.createSingleSecret
|
||||||
const secretFromDB = await Secret.findById(req.params.secretId)
|
|
||||||
return res.status(200).send(secretFromDB);
|
|
||||||
} catch (e) {
|
|
||||||
throw BadRequestError({ message: "Unable to find the requested secret" })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -99,37 +50,9 @@ router.delete(
|
|||||||
acceptedRoles: [ADMIN, MEMBER],
|
acceptedRoles: [ADMIN, MEMBER],
|
||||||
acceptedStatuses: [COMPLETED, GRANTED]
|
acceptedStatuses: [COMPLETED, GRANTED]
|
||||||
}),
|
}),
|
||||||
validateRequest, async (req: Request, res: Response) => {
|
validateRequest,
|
||||||
const { workspaceId, environmentName } = req.params
|
secretController.batchDeleteSecrets
|
||||||
const secretIdsToDelete: string[] = req.body.secretIds
|
|
||||||
|
|
||||||
const [secretIdsUserCanDeleteError, secretIdsUserCanDelete] = await to(Secret.find({ workspace: workspaceId, environment: environmentName }, { _id: 1 }).then())
|
|
||||||
if (secretIdsUserCanDeleteError) {
|
|
||||||
throw InternalServerError({ message: `Unable to fetch secrets you own: [error=${secretIdsUserCanDeleteError.message}]` })
|
|
||||||
}
|
|
||||||
|
|
||||||
const secretsUserCanDeleteSet: Set<string> = new Set(secretIdsUserCanDelete.map(objectId => objectId._id.toString()));
|
|
||||||
const deleteOperationsToPerform: AnyBulkWriteOperation<ISecret>[] = []
|
|
||||||
|
|
||||||
secretIdsToDelete.forEach(secretIdToDelete => {
|
|
||||||
if (secretsUserCanDeleteSet.has(secretIdToDelete)) {
|
|
||||||
const deleteOperation = { deleteOne: { filter: { _id: new Types.ObjectId(secretIdToDelete) } } }
|
|
||||||
deleteOperationsToPerform.push(deleteOperation)
|
|
||||||
} else {
|
|
||||||
throw RouteValidationError({ message: "You cannot delete secrets that you do not have access to" })
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const [bulkDeleteError, bulkDelete] = await to(Secret.bulkWrite(deleteOperationsToPerform).then())
|
|
||||||
if (bulkDeleteError) {
|
|
||||||
if (bulkDeleteError instanceof ValidationError) {
|
|
||||||
throw RouteValidationError({ message: "Unable to apply modifications, please try again", stack: bulkDeleteError.stack })
|
|
||||||
}
|
|
||||||
throw InternalServerError()
|
|
||||||
}
|
|
||||||
|
|
||||||
res.status(200).send()
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -145,53 +68,8 @@ router.patch(
|
|||||||
acceptedRoles: [ADMIN, MEMBER],
|
acceptedRoles: [ADMIN, MEMBER],
|
||||||
acceptedStatuses: [COMPLETED, GRANTED]
|
acceptedStatuses: [COMPLETED, GRANTED]
|
||||||
}),
|
}),
|
||||||
validateRequest, async (req: Request, res: Response) => {
|
validateRequest,
|
||||||
const { workspaceId, environmentName } = req.params
|
secretController.batchModifySecrets
|
||||||
const secretsModificationsRequested: ModifySecretRequestBody[] = req.body.secrets;
|
|
||||||
const [secretIdsUserCanModifyError, secretIdsUserCanModify] = await to(Secret.find({ workspace: workspaceId, environment: environmentName }, { _id: 1 }).then())
|
|
||||||
if (secretIdsUserCanModifyError) {
|
|
||||||
throw InternalServerError({ message: "Unable to fetch secrets you own" })
|
|
||||||
}
|
|
||||||
|
|
||||||
const secretsUserCanModifySet: Set<string> = new Set(secretIdsUserCanModify.map(objectId => objectId._id.toString()));
|
|
||||||
const updateOperationsToPerform: any = []
|
|
||||||
|
|
||||||
|
|
||||||
secretsModificationsRequested.forEach(userModifiedSecret => {
|
|
||||||
if (secretsUserCanModifySet.has(userModifiedSecret._id.toString())) {
|
|
||||||
const sanitizedSecret: SanitizedSecretModify = {
|
|
||||||
secretKeyCiphertext: userModifiedSecret.secretKeyCiphertext,
|
|
||||||
secretKeyIV: userModifiedSecret.secretKeyIV,
|
|
||||||
secretKeyTag: userModifiedSecret.secretKeyTag,
|
|
||||||
secretKeyHash: userModifiedSecret.secretKeyHash,
|
|
||||||
secretValueCiphertext: userModifiedSecret.secretValueCiphertext,
|
|
||||||
secretValueIV: userModifiedSecret.secretValueIV,
|
|
||||||
secretValueTag: userModifiedSecret.secretValueTag,
|
|
||||||
secretValueHash: userModifiedSecret.secretValueHash,
|
|
||||||
secretCommentCiphertext: userModifiedSecret.secretCommentCiphertext,
|
|
||||||
secretCommentIV: userModifiedSecret.secretCommentIV,
|
|
||||||
secretCommentTag: userModifiedSecret.secretCommentTag,
|
|
||||||
secretCommentHash: userModifiedSecret.secretCommentHash,
|
|
||||||
}
|
|
||||||
|
|
||||||
const updateOperation = { updateOne: { filter: { _id: userModifiedSecret._id, workspace: workspaceId }, update: { $inc: { version: 1 }, $set: sanitizedSecret } } }
|
|
||||||
updateOperationsToPerform.push(updateOperation)
|
|
||||||
} else {
|
|
||||||
throw UnauthorizedRequestError({ message: "You do not have permission to modify one or more of the requested secrets" })
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const [bulkModificationInfoError, bulkModificationInfo] = await to(Secret.bulkWrite(updateOperationsToPerform).then())
|
|
||||||
if (bulkModificationInfoError) {
|
|
||||||
if (bulkModificationInfoError instanceof ValidationError) {
|
|
||||||
throw RouteValidationError({ message: "Unable to apply modifications, please try again", stack: bulkModificationInfoError.stack })
|
|
||||||
}
|
|
||||||
|
|
||||||
throw InternalServerError()
|
|
||||||
}
|
|
||||||
|
|
||||||
return res.status(200).send()
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
export default router;
|
export default router;
|
||||||
|
|||||||
Reference in New Issue
Block a user