Merge pull request #1285 from Infisical/query-by-secret-version

Add version query param to GET secret raw and regular endpoints
This commit is contained in:
Maidul Islam
2024-01-07 16:07:49 -05:00
committed by GitHub
5 changed files with 102 additions and 26 deletions
@@ -348,7 +348,7 @@ export const getSecretByNameRaw = async (req: Request, res: Response) => {
} }
*/ */
const { const {
query: { secretPath, environment, workspaceId, type, include_imports }, query: { secretPath, environment, workspaceId, type, include_imports, version },
params: { secretName } params: { secretName }
} = await validateRequest(reqValidator.GetSecretByNameRawV3, req); } = await validateRequest(reqValidator.GetSecretByNameRawV3, req);
@@ -371,7 +371,8 @@ export const getSecretByNameRaw = async (req: Request, res: Response) => {
type, type,
secretPath, secretPath,
authData: req.authData, authData: req.authData,
include_imports include_imports,
version
}); });
const key = await BotService.getWorkspaceKeyWithBot({ const key = await BotService.getWorkspaceKeyWithBot({
@@ -865,7 +866,7 @@ export const getSecrets = async (req: Request, res: Response) => {
*/ */
export const getSecretByName = async (req: Request, res: Response) => { export const getSecretByName = async (req: Request, res: Response) => {
const { const {
query: { secretPath, environment, workspaceId, type, include_imports }, query: { secretPath, environment, workspaceId, type, include_imports, version },
params: { secretName } params: { secretName }
} = await validateRequest(reqValidator.GetSecretByNameV3, req); } = await validateRequest(reqValidator.GetSecretByNameV3, req);
@@ -888,7 +889,8 @@ export const getSecretByName = async (req: Request, res: Response) => {
type, type,
secretPath, secretPath,
authData: req.authData, authData: req.authData,
include_imports include_imports,
version
}); });
return res.status(200).send({ return res.status(200).send({
+54 -15
View File
@@ -611,42 +611,81 @@ export const getSecretHelper = async ({
type, type,
authData, authData,
secretPath = "/", secretPath = "/",
include_imports = true include_imports = true,
version
}: GetSecretParams) => { }: GetSecretParams) => {
const secretBlindIndex = await generateSecretBlindIndexHelper({ const secretBlindIndex = await generateSecretBlindIndexHelper({
secretName, secretName,
workspaceId: new Types.ObjectId(workspaceId) workspaceId: new Types.ObjectId(workspaceId)
}); });
let secret: ISecret | null | undefined = null; let secret: ISecret | null | undefined = null;
// if using service token filter towards the folderId by secretpath // if using service token filter towards the folderId by secretpath
const folderId = await getFolderIdFromServiceToken(workspaceId, environment, secretPath); const folderId = await getFolderIdFromServiceToken(workspaceId, environment, secretPath);
// try getting personal secret first (if exists) // try getting personal secret first (if exists)
secret = await Secret.findOne({ if (version === undefined) {
secretBlindIndex,
workspace: new Types.ObjectId(workspaceId),
environment,
folder: folderId,
type: type ?? SECRET_PERSONAL,
...(type === SECRET_PERSONAL ? getAuthDataPayloadUserObj(authData) : {})
}).lean();
if (!secret) {
// case: failed to find personal secret matching criteria
// -> find shared secret matching criteria
secret = await Secret.findOne({ secret = await Secret.findOne({
secretBlindIndex, secretBlindIndex,
workspace: new Types.ObjectId(workspaceId), workspace: new Types.ObjectId(workspaceId),
environment, environment,
folder: folderId, folder: folderId,
type: SECRET_SHARED type: type ?? SECRET_PERSONAL,
...(type === SECRET_PERSONAL ? getAuthDataPayloadUserObj(authData) : {})
}).lean(); }).lean();
} else {
const secretVersion = await SecretVersion.findOne({
secretBlindIndex,
workspace: new Types.ObjectId(workspaceId),
environment,
folder: folderId,
type: type ?? SECRET_PERSONAL,
version
}).lean();
if (secretVersion) {
secret = await new Secret({
...secretVersion,
_id: secretVersion?.secret
});
}
}
if (!secret) {
// case: failed to find personal secret matching criteria
// -> find shared secret matching criteria
if (version === undefined) {
secret = await Secret.findOne({
secretBlindIndex,
workspace: new Types.ObjectId(workspaceId),
environment,
folder: folderId,
type: SECRET_SHARED
}).lean();
} else {
const secretVersion = await SecretVersion.findOne({
secretBlindIndex,
workspace: new Types.ObjectId(workspaceId),
environment,
folder: folderId,
type: SECRET_SHARED,
version
}).lean();
if (secretVersion) {
secret = await new Secret({
...secretVersion,
_id: secretVersion?.secret
});
}
}
} }
if (!secret && include_imports) { if (!secret && include_imports) {
// if still no secret found search in imported secret and retreive // if still no secret found search in imported secret and retreive
secret = await getAnImportedSecret(secretName, workspaceId.toString(), environment, folderId); secret = await getAnImportedSecret(secretName, workspaceId.toString(), environment, folderId, version);
} }
if (!secret) throw SecretNotFoundError(); if (!secret) throw SecretNotFoundError();
@@ -38,6 +38,7 @@ export interface GetSecretParams {
type?: "shared" | "personal"; type?: "shared" | "personal";
authData: AuthData; authData: AuthData;
include_imports?: boolean; include_imports?: boolean;
version?: number;
} }
export interface UpdateSecretParams { export interface UpdateSecretParams {
+23 -5
View File
@@ -1,5 +1,6 @@
import { Types } from "mongoose"; import { Types } from "mongoose";
import { generateSecretBlindIndexHelper } from "../helpers"; import { generateSecretBlindIndexHelper } from "../helpers";
import { SecretVersion } from "../ee/models";
import { Folder, ISecret, Secret, SecretImport } from "../models"; import { Folder, ISecret, Secret, SecretImport } from "../models";
import { getFolderByPath } from "./FolderService"; import { getFolderByPath } from "./FolderService";
@@ -9,7 +10,8 @@ export const getAnImportedSecret = async (
secretName: string, secretName: string,
workspaceId: string, workspaceId: string,
environment: string, environment: string,
folderId = "root" folderId = "root",
version?: number
) => { ) => {
const secretBlindIndex = await generateSecretBlindIndexHelper({ const secretBlindIndex = await generateSecretBlindIndexHelper({
secretName, secretName,
@@ -48,10 +50,26 @@ export const getAnImportedSecret = async (
}); });
if (importedSecByFid.length === 0) return; if (importedSecByFid.length === 0) return;
const secret = await Secret.findOne({ let secret;
workspace: workspaceId, if (version === undefined) {
secretBlindIndex secret = await Secret.findOne({
}).or(importedSecByFid.map(({ environment, folderId }) => ({ environment, folder: folderId }))).lean() workspace: workspaceId,
secretBlindIndex
}).or(importedSecByFid.map(({ environment, folderId }) => ({ environment, folder: folderId }))).lean()
} else {
const secretVersion = await SecretVersion.findOne({
workspace: workspaceId,
secretBlindIndex,
version
}).or(importedSecByFid.map(({ environment, folderId }) => ({ environment, folder: folderId }))).lean();
if (secretVersion) {
secret = await new Secret({
...secretVersion,
_id: secretVersion.secret,
});
}
}
return secret; return secret;
}; };
+18 -2
View File
@@ -246,7 +246,15 @@ export const GetSecretByNameRawV3 = z.object({
include_imports: z include_imports: z
.enum(["true", "false"]) .enum(["true", "false"])
.default("true") .default("true")
.transform((value) => value === "true") .transform((value) => value === "true"),
version: z
.string()
.trim()
.optional()
.transform((value) => value === undefined ? undefined : parseInt(value, 10))
.refine((value) => value === undefined || !isNaN(value), {
message: "Version must be a number",
})
}) })
}); });
@@ -318,7 +326,15 @@ export const GetSecretByNameV3 = z.object({
include_imports: z include_imports: z
.enum(["true", "false"]) .enum(["true", "false"])
.default("true") .default("true")
.transform((value) => value === "true") .transform((value) => value === "true"),
version: z
.string()
.trim()
.optional()
.transform((value) => value === undefined ? undefined : parseInt(value, 10))
.refine((value) => value === undefined || !isNaN(value), {
message: "Version must be a number",
})
}), }),
params: z.object({ params: z.object({
secretName: z.string().trim() secretName: z.string().trim()