diff --git a/backend/src/controllers/v3/secretsController.ts b/backend/src/controllers/v3/secretsController.ts index e1e54d4d0..1c691088a 100644 --- a/backend/src/controllers/v3/secretsController.ts +++ b/backend/src/controllers/v3/secretsController.ts @@ -6,12 +6,12 @@ import { BotService } from "../../services"; import { containsGlobPatterns, repackageSecretToRaw } from "../../helpers/secrets"; import { encryptSymmetric128BitHexKeyUTF8 } from "../../utils/crypto"; import { getAllImportedSecrets } from "../../services/SecretImportService"; -import { - Folder, - IServiceTokenData, +import { + Folder, + IServiceTokenData, Membership, - ServiceTokenData, - User + ServiceTokenData, + User } from "../../models"; import { getFolderByPath } from "../../services/FolderService"; import { BadRequestError } from "../../utils/errors"; @@ -33,6 +33,7 @@ import { getSecretPolicyOfBoard } from "../../ee/services/SecretApprovalService"; import { CommitType } from "../../ee/models/secretApprovalRequest"; +import { logger } from "../../utils/logging"; const checkSecretsPermission = async ({ authData, @@ -103,7 +104,7 @@ const checkSecretsPermission = async ({ authData, workspaceId: new Types.ObjectId(workspaceId) }); - + ForbiddenError.from(permission).throwUnlessCan( secretAction, subject(ProjectPermissionSub.Secrets, { environment, secretPath }) @@ -196,6 +197,8 @@ export const getSecretsRaw = async (req: Request, res: Response) => { query: { include_imports: includeImports } } = validatedData; + logger.info(`getSecretsRaw: fetch raw secrets [environment=${environment}] [workspaceId=${workspaceId}] [secretPath=${secretPath}] [includeImports=${includeImports}]`) + if (req.authData.authPayload instanceof ServiceTokenData) { // if the service token has single scope, it will get all secrets for that scope by default @@ -353,6 +356,8 @@ export const getSecretByNameRaw = async (req: Request, res: Response) => { params: { secretName } } = await validateRequest(reqValidator.GetSecretByNameRawV3, req); + logger.info(`getSecretByNameRaw: fetch raw secret by name [environment=${environment}] [workspaceId=${workspaceId}] [secretPath=${secretPath}] [type=${type}] [include_imports=${include_imports}]`) + await checkSecretsPermission({ authData: req.authData, workspaceId, @@ -476,6 +481,8 @@ export const createSecretRaw = async (req: Request, res: Response) => { } } = await validateRequest(reqValidator.CreateSecretRawV3, req); + logger.info(`createSecretRaw: create a secret raw by name and value [environment=${environment}] [workspaceId=${workspaceId}] [secretPath=${secretPath}] [type=${type}] [skipMultilineEncoding=${skipMultilineEncoding}]`) + await checkSecretsPermission({ authData: req.authData, workspaceId, @@ -621,6 +628,8 @@ export const updateSecretByNameRaw = async (req: Request, res: Response) => { body: { workspaceId, environment, secretValue, secretPath, type, skipMultilineEncoding } } = await validateRequest(reqValidator.UpdateSecretByNameRawV3, req); + logger.info(`updateSecretByNameRaw: update raw secret by name [environment=${environment}] [workspaceId=${workspaceId}] [secretPath=${secretPath}] [type=${type}] [skipMultilineEncoding=${skipMultilineEncoding}]`) + await checkSecretsPermission({ authData: req.authData, workspaceId, @@ -743,6 +752,8 @@ export const deleteSecretByNameRaw = async (req: Request, res: Response) => { body: { environment, secretPath, type, workspaceId } } = await validateRequest(reqValidator.DeleteSecretByNameRawV3, req); + logger.info(`deleteSecretByNameRaw: delete a secret by name [environment=${environment}] [workspaceId=${workspaceId}] [secretPath=${secretPath}] [type=${type}]`) + await checkSecretsPermission({ authData: req.authData, workspaceId, @@ -796,6 +807,8 @@ export const getSecrets = async (req: Request, res: Response) => { query: { secretPath } } = validatedData; + logger.info(`getSecrets: fetch encrypted secrets [environment=${environment}] [workspaceId=${workspaceId}] [includeImports=${includeImports}]`) + const { authVerifier: permissionCheckFn } = await checkSecretsPermission({ authData: req.authData, workspaceId, @@ -850,6 +863,8 @@ export const getSecretByName = async (req: Request, res: Response) => { params: { secretName } } = await validateRequest(reqValidator.GetSecretByNameV3, req); + logger.info(`getSecretByName: get a single secret by name [environment=${environment}] [workspaceId=${workspaceId}] [include_imports=${include_imports}] [type=${type}]`) + await checkSecretsPermission({ authData: req.authData, workspaceId, @@ -900,6 +915,8 @@ export const createSecret = async (req: Request, res: Response) => { params: { secretName } } = await validateRequest(reqValidator.CreateSecretV3, req); + logger.info(`createSecret: create an encrypted secret [environment=${environment}] [workspaceId=${workspaceId}] [skipMultilineEncoding=${skipMultilineEncoding}] [type=${type}]`) + await checkSecretsPermission({ authData: req.authData, workspaceId, @@ -913,7 +930,7 @@ export const createSecret = async (req: Request, res: Response) => { user: req.authData.authPayload._id, workspace: new Types.ObjectId(workspaceId) }); - + if (membership && type !== "personal") { const secretApprovalPolicy = await getSecretPolicyOfBoard(workspaceId, environment, secretPath); if (secretApprovalPolicy) { @@ -1012,6 +1029,8 @@ export const updateSecretByName = async (req: Request, res: Response) => { params: { secretName } } = await validateRequest(reqValidator.UpdateSecretByNameV3, req); + logger.info(`updateSecretByName: update a encrypted secret by name [environment=${environment}] [workspaceId=${workspaceId}] [skipMultilineEncoding=${skipMultilineEncoding}] [type=${type}]`) + if (newSecretName && (!secretKeyIV || !secretKeyTag || !secretKeyCiphertext)) { throw BadRequestError({ message: "Missing encrypted key" }); } @@ -1111,6 +1130,8 @@ export const deleteSecretByName = async (req: Request, res: Response) => { params: { secretName } } = await validateRequest(reqValidator.DeleteSecretByNameV3, req); + logger.info(`deleteSecretByName: delete a encrypted secret by name [environment=${environment}] [workspaceId=${workspaceId}] [type=${type}]`) + await checkSecretsPermission({ authData: req.authData, workspaceId, @@ -1124,7 +1145,7 @@ export const deleteSecretByName = async (req: Request, res: Response) => { user: req.authData.authPayload._id, workspace: new Types.ObjectId(workspaceId) }); - + if (membership && type !== "personal") { const secretApprovalPolicy = await getSecretPolicyOfBoard(workspaceId, environment, secretPath); if (secretApprovalPolicy) { @@ -1176,6 +1197,8 @@ export const createSecretByNameBatch = async (req: Request, res: Response) => { body: { secrets, secretPath, environment, workspaceId } } = await validateRequest(reqValidator.CreateSecretByNameBatchV3, req); + logger.info(`createSecretByNameBatch: create a list of secrets by their names [environment=${environment}] [workspaceId=${workspaceId}] [secretsLength=${secrets?.length}]`) + await checkSecretsPermission({ authData: req.authData, workspaceId, @@ -1189,7 +1212,7 @@ export const createSecretByNameBatch = async (req: Request, res: Response) => { user: req.authData.authPayload._id, workspace: new Types.ObjectId(workspaceId) }); - + if (membership) { const secretApprovalPolicy = await getSecretPolicyOfBoard(workspaceId, environment, secretPath); if (secretApprovalPolicy) { @@ -1235,6 +1258,8 @@ export const updateSecretByNameBatch = async (req: Request, res: Response) => { body: { secrets, secretPath, environment, workspaceId } } = await validateRequest(reqValidator.UpdateSecretByNameBatchV3, req); + logger.info(`updateSecretByNameBatch: update a list of secrets by their names [environment=${environment}] [workspaceId=${workspaceId}] [secretsLength=${secrets?.length}]`) + await checkSecretsPermission({ authData: req.authData, workspaceId, @@ -1248,7 +1273,7 @@ export const updateSecretByNameBatch = async (req: Request, res: Response) => { user: req.authData.authPayload._id, workspace: new Types.ObjectId(workspaceId) }); - + if (membership) { const secretApprovalPolicy = await getSecretPolicyOfBoard(workspaceId, environment, secretPath); if (secretApprovalPolicy) { @@ -1293,7 +1318,9 @@ export const deleteSecretByNameBatch = async (req: Request, res: Response) => { const { body: { secrets, secretPath, environment, workspaceId } } = await validateRequest(reqValidator.DeleteSecretByNameBatchV3, req); - + + logger.info(`deleteSecretByNameBatch: delete a list of secrets by their names [environment=${environment}] [workspaceId=${workspaceId}] [secretsLength=${secrets?.length}]`) + await checkSecretsPermission({ authData: req.authData, workspaceId,