From e676acbadf4b8f1e006cf5d5bd885ab7b200a4d0 Mon Sep 17 00:00:00 2001 From: = Date: Fri, 8 Nov 2024 19:58:10 +0530 Subject: [PATCH 1/4] feat: added e2ee test for recursive secret operation --- .../routes/v3/secret-recursive.spec.ts | 78 +++++++++++++++++++ backend/e2e-test/testUtils/secrets.ts | 4 +- 2 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 backend/e2e-test/routes/v3/secret-recursive.spec.ts diff --git a/backend/e2e-test/routes/v3/secret-recursive.spec.ts b/backend/e2e-test/routes/v3/secret-recursive.spec.ts new file mode 100644 index 000000000..667cb1414 --- /dev/null +++ b/backend/e2e-test/routes/v3/secret-recursive.spec.ts @@ -0,0 +1,78 @@ +import { createFolder, deleteFolder } from "e2e-test/testUtils/folders"; +import { createSecretV2, deleteSecretV2, getSecretsV2 } from "e2e-test/testUtils/secrets"; + +import { seedData1 } from "@app/db/seed-data"; + +describe("Secret Recursive Testing", async () => { + const projectId = seedData1.projectV3.id; + const folderAndSecretNames = [ + { name: "deep1", path: "/", expectedSecretCount: 3 }, + { name: "deep2", path: "/deep1", expectedSecretCount: 2 }, + { name: "deep3", path: "/deep1/deep2", expectedSecretCount: 1 } + ]; + + beforeAll(async () => { + let rootFolderId = ""; + for (const folder of folderAndSecretNames) { + // eslint-disable-next-line no-await-in-loop + const createdFolder = await createFolder({ + authToken: jwtAuthToken, + environmentSlug: "prod", + workspaceId: projectId, + secretPath: folder.path, + name: folder.name + }); + + if (folder.path === "/") { + rootFolderId = createdFolder.id; + } + // eslint-disable-next-line no-await-in-loop + await createSecretV2({ + secretPath: folder.path, + authToken: jwtAuthToken, + environmentSlug: "prod", + workspaceId: projectId, + key: folder.name, + value: folder.name + }); + } + + return async () => { + await deleteFolder({ + authToken: jwtAuthToken, + secretPath: "/", + id: rootFolderId, + workspaceId: projectId, + environmentSlug: "prod" + }); + + await deleteSecretV2({ + authToken: jwtAuthToken, + secretPath: "/", + workspaceId: projectId, + environmentSlug: "prod", + key: folderAndSecretNames[0].name + }); + }; + }); + + test.each(folderAndSecretNames)("$path recursive secret fetching", async ({ path, expectedSecretCount }) => { + const secrets = await getSecretsV2({ + authToken: jwtAuthToken, + secretPath: path, + workspaceId: projectId, + environmentSlug: "prod", + recursive: true + }); + + expect(secrets.secrets.length).toEqual(expectedSecretCount); + expect(secrets.secrets).toEqual( + folderAndSecretNames.slice(-expectedSecretCount).map((el) => + expect.objectContaining({ + secretKey: el.name, + secretValue: el.name + }) + ) + ); + }); +}); diff --git a/backend/e2e-test/testUtils/secrets.ts b/backend/e2e-test/testUtils/secrets.ts index 96ecc91c6..69b47d60f 100644 --- a/backend/e2e-test/testUtils/secrets.ts +++ b/backend/e2e-test/testUtils/secrets.ts @@ -97,6 +97,7 @@ export const getSecretsV2 = async (dto: { environmentSlug: string; secretPath: string; authToken: string; + recursive?: boolean; }) => { const getSecretsResponse = await testServer.inject({ method: "GET", @@ -109,7 +110,8 @@ export const getSecretsV2 = async (dto: { environment: dto.environmentSlug, secretPath: dto.secretPath, expandSecretReferences: "true", - include_imports: "true" + include_imports: "true", + recursive: String(dto.recursive) } }); expect(getSecretsResponse.statusCode).toBe(200); From c5fded361c8c7b3a3c3adc2c5f5a78cf39c3e535 Mon Sep 17 00:00:00 2001 From: = Date: Fri, 8 Nov 2024 20:11:11 +0530 Subject: [PATCH 2/4] feat: added e2ee test for recursive secret operation --- .../routes/v3/secret-recursive.spec.ts | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/backend/e2e-test/routes/v3/secret-recursive.spec.ts b/backend/e2e-test/routes/v3/secret-recursive.spec.ts index 667cb1414..823caa3db 100644 --- a/backend/e2e-test/routes/v3/secret-recursive.spec.ts +++ b/backend/e2e-test/routes/v3/secret-recursive.spec.ts @@ -6,9 +6,10 @@ import { seedData1 } from "@app/db/seed-data"; describe("Secret Recursive Testing", async () => { const projectId = seedData1.projectV3.id; const folderAndSecretNames = [ - { name: "deep1", path: "/", expectedSecretCount: 3 }, - { name: "deep2", path: "/deep1", expectedSecretCount: 2 }, - { name: "deep3", path: "/deep1/deep2", expectedSecretCount: 1 } + { name: "deep1", path: "/", expectedSecretCount: 4 }, + { name: "deep21", path: "/deep1", expectedSecretCount: 2 }, + { name: "deep3", path: "/deep1/deep2", expectedSecretCount: 1 }, + { name: "deep22", path: "/deep2", expectedSecretCount: 1 } ]; beforeAll(async () => { @@ -66,13 +67,16 @@ describe("Secret Recursive Testing", async () => { }); expect(secrets.secrets.length).toEqual(expectedSecretCount); - expect(secrets.secrets).toEqual( - folderAndSecretNames.slice(-expectedSecretCount).map((el) => - expect.objectContaining({ - secretKey: el.name, - secretValue: el.name - }) - ) + expect(secrets.secrets.sort((a, b) => a.secretKey.localeCompare(b.secretKey))).toEqual( + folderAndSecretNames + .filter((el) => el.path.startsWith(path)) + .sort((a, b) => a.name.localeCompare(b.name)) + .map((el) => + expect.objectContaining({ + secretKey: el.name, + secretValue: el.name + }) + ) ); }); }); From b7fe3743db41ea6933dc86c32c66fd552ba0a9c2 Mon Sep 17 00:00:00 2001 From: = Date: Mon, 11 Nov 2024 12:16:24 +0530 Subject: [PATCH 3/4] feat: resolved recursive testcase change failing test --- .../routes/v3/secret-recursive.spec.ts | 22 +++++++++++-------- backend/e2e-test/testUtils/secrets.ts | 2 +- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/backend/e2e-test/routes/v3/secret-recursive.spec.ts b/backend/e2e-test/routes/v3/secret-recursive.spec.ts index 823caa3db..b28dff985 100644 --- a/backend/e2e-test/routes/v3/secret-recursive.spec.ts +++ b/backend/e2e-test/routes/v3/secret-recursive.spec.ts @@ -13,7 +13,7 @@ describe("Secret Recursive Testing", async () => { ]; beforeAll(async () => { - let rootFolderId = ""; + const rootFolderIds: string[] = []; for (const folder of folderAndSecretNames) { // eslint-disable-next-line no-await-in-loop const createdFolder = await createFolder({ @@ -25,7 +25,7 @@ describe("Secret Recursive Testing", async () => { }); if (folder.path === "/") { - rootFolderId = createdFolder.id; + rootFolderIds.push(createdFolder.id); } // eslint-disable-next-line no-await-in-loop await createSecretV2({ @@ -39,13 +39,17 @@ describe("Secret Recursive Testing", async () => { } return async () => { - await deleteFolder({ - authToken: jwtAuthToken, - secretPath: "/", - id: rootFolderId, - workspaceId: projectId, - environmentSlug: "prod" - }); + await Promise.all( + rootFolderIds.map((id) => + deleteFolder({ + authToken: jwtAuthToken, + secretPath: "/", + id, + workspaceId: projectId, + environmentSlug: "prod" + }) + ) + ); await deleteSecretV2({ authToken: jwtAuthToken, diff --git a/backend/e2e-test/testUtils/secrets.ts b/backend/e2e-test/testUtils/secrets.ts index 69b47d60f..8b9e47f2f 100644 --- a/backend/e2e-test/testUtils/secrets.ts +++ b/backend/e2e-test/testUtils/secrets.ts @@ -111,7 +111,7 @@ export const getSecretsV2 = async (dto: { secretPath: dto.secretPath, expandSecretReferences: "true", include_imports: "true", - recursive: String(dto.recursive) + recursive: String(dto.recursive || false) } }); expect(getSecretsResponse.statusCode).toBe(200); From 49133a044f092b2fdd9ebd1abc405e098b65ade4 Mon Sep 17 00:00:00 2001 From: = Date: Fri, 29 Nov 2024 19:59:34 +0530 Subject: [PATCH 4/4] feat: resolved an issue without recursive matching --- .../src/services/secret-v2-bridge/secret-v2-bridge-fns.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/backend/src/services/secret-v2-bridge/secret-v2-bridge-fns.ts b/backend/src/services/secret-v2-bridge/secret-v2-bridge-fns.ts index 95d2cdbf4..79aa22799 100644 --- a/backend/src/services/secret-v2-bridge/secret-v2-bridge-fns.ts +++ b/backend/src/services/secret-v2-bridge/secret-v2-bridge-fns.ts @@ -365,9 +365,8 @@ export const recursivelyGetSecretPaths = async ({ folderId: p.folderId })); - const pathsInCurrentDirectory = paths.filter((folder) => - folder.path.startsWith(currentPath === "/" ? "" : currentPath) - ); + // path relative will start with ../ if its outside directory + const pathsInCurrentDirectory = paths.filter((folder) => !path.relative(currentPath, folder.path).startsWith("..")); return pathsInCurrentDirectory; };