feat: added support for getting imported secrets in v3 getSecret api

This commit is contained in:
Akhil Mohan
2023-09-26 12:25:23 +05:30
parent a255af6ad8
commit 4c1324baa9
5 changed files with 79 additions and 9 deletions

View File

@@ -146,7 +146,7 @@ export const getSecretsRaw = async (req: Request, res: Response) => {
*/
export const getSecretByNameRaw = async (req: Request, res: Response) => {
const {
query: { secretPath, environment, workspaceId, type },
query: { secretPath, environment, workspaceId, type, include_imports },
params: { secretName }
} = await validateRequest(reqValidator.GetSecretByNameRawV3, req);
@@ -172,7 +172,8 @@ export const getSecretByNameRaw = async (req: Request, res: Response) => {
environment,
type,
secretPath,
authData: req.authData
authData: req.authData,
include_imports
});
const key = await BotService.getWorkspaceKeyWithBot({
@@ -483,7 +484,7 @@ export const getSecrets = async (req: Request, res: Response) => {
*/
export const getSecretByName = async (req: Request, res: Response) => {
const {
query: { secretPath, environment, workspaceId, type },
query: { secretPath, environment, workspaceId, type, include_imports },
params: { secretName }
} = await validateRequest(reqValidator.GetSecretByNameV3, req);
@@ -509,7 +510,8 @@ export const getSecretByName = async (req: Request, res: Response) => {
environment,
type,
secretPath,
authData: req.authData
authData: req.authData,
include_imports
});
return res.status(200).send({

View File

@@ -48,6 +48,7 @@ import { getAuthDataPayloadIdObj, getAuthDataPayloadUserObj } from "../utils/aut
import { getFolderByPath, getFolderIdFromServiceToken } from "../services/FolderService";
import picomatch from "picomatch";
import path from "path";
import { getAnImportedSecret } from "../services/SecretImportService";
export const isValidScope = (
authPayload: IServiceTokenData,
@@ -622,13 +623,14 @@ export const getSecretHelper = async ({
environment,
type,
authData,
secretPath = "/"
secretPath = "/",
include_imports = true
}: GetSecretParams) => {
const secretBlindIndex = await generateSecretBlindIndexHelper({
secretName,
workspaceId: new Types.ObjectId(workspaceId)
});
let secret: ISecret | null = null;
let secret: ISecret | null | undefined = null;
// if using service token filter towards the folderId by secretpath
const folderId = await getFolderIdFromServiceToken(workspaceId, environment, secretPath);
@@ -655,6 +657,11 @@ export const getSecretHelper = async ({
}).lean();
}
if (!secret && include_imports) {
// if still no secret found search in imported secret and retreive
secret = await getAnImportedSecret(secretName, workspaceId.toString(), environment, folderId);
}
if (!secret) throw SecretNotFoundError();
// (EE) create (audit) log

View File

@@ -19,7 +19,7 @@ export interface CreateSecretParams {
secretPath: string;
metadata?: {
source?: string;
}
};
}
export interface GetSecretsParams {
@@ -37,6 +37,7 @@ export interface GetSecretParams {
environment: string;
type?: "shared" | "personal";
authData: AuthData;
include_imports?: boolean;
}
export interface UpdateSecretParams {

View File

@@ -1,9 +1,61 @@
import { Types } from "mongoose";
import { generateSecretBlindIndexHelper } from "../helpers";
import { Folder, ISecret, Secret, SecretImport } from "../models";
import { getFolderByPath } from "./FolderService";
type TSecretImportFid = { environment: string; folderId: string; secretPath: string };
export const getAnImportedSecret = async (
secretName: string,
workspaceId: string,
environment: string,
folderId = "root"
) => {
const secretBlindIndex = await generateSecretBlindIndexHelper({
secretName,
workspaceId: new Types.ObjectId(workspaceId)
});
const secImports = await SecretImport.findOne({
workspace: workspaceId,
environment,
folderId
});
if (!secImports) return;
if (secImports.imports.length === 0) return;
const folders = await Folder.find({
workspace: workspaceId,
environment: { $in: secImports.imports.map((el) => el.environment) }
});
const importedSecByFid: TSecretImportFid[] = [];
secImports.imports.forEach((el) => {
const folder = folders.find((fl) => fl.environment === el.environment);
if (folder) {
const secPathFolder = getFolderByPath(folder.nodes, el.secretPath);
if (secPathFolder)
importedSecByFid.push({
environment: el.environment,
folderId: secPathFolder.id,
secretPath: el.secretPath
});
} else {
if (el.secretPath === "/") {
// this happens when importing with a fresh env without any folders
importedSecByFid.push({ environment: el.environment, folderId: "root", secretPath: "/" });
}
}
});
if (importedSecByFid.length === 0) return;
const secret = await Secret.findOne({
workspace: workspaceId,
secretBlindIndex
}).or(importedSecByFid.map(({ environment, folderId }) => ({ environment, folder: folderId })));
return secret;
};
export const getAllImportedSecrets = async (
workspaceId: string,
environment: string,

View File

@@ -244,7 +244,11 @@ export const GetSecretByNameRawV3 = z.object({
workspaceId: z.string().trim(),
environment: z.string().trim(),
secretPath: z.string().trim().default("/"),
type: z.enum([SECRET_SHARED, SECRET_PERSONAL]).optional()
type: z.enum([SECRET_SHARED, SECRET_PERSONAL]).optional(),
include_imports: z
.enum(["true", "false"])
.default("true")
.transform((value) => value === "true")
})
});
@@ -305,7 +309,11 @@ export const GetSecretByNameV3 = z.object({
workspaceId: z.string().trim(),
environment: z.string().trim(),
secretPath: z.string().trim().default("/"),
type: z.enum([SECRET_SHARED, SECRET_PERSONAL]).optional()
type: z.enum([SECRET_SHARED, SECRET_PERSONAL]).optional(),
include_imports: z
.enum(["true", "false"])
.default("true")
.transform((value) => value === "true")
}),
params: z.object({
secretName: z.string().trim()