From 6410d51033d179141c9c55acd762d2d186111345 Mon Sep 17 00:00:00 2001 From: Akhil Mohan Date: Mon, 15 Apr 2024 19:34:47 +0530 Subject: [PATCH] feat(server): added mysql dynamic secret server logic --- .../dynamic-secret-lease-service.ts | 2 +- .../dynamic-secret/providers/models.ts | 5 ++- .../dynamic-secret/providers/sql-database.ts | 45 +++++++++++++++---- 3 files changed, 41 insertions(+), 11 deletions(-) diff --git a/backend/src/ee/services/dynamic-secret-lease/dynamic-secret-lease-service.ts b/backend/src/ee/services/dynamic-secret-lease/dynamic-secret-lease-service.ts index e46c3c6ee..1e5487d22 100644 --- a/backend/src/ee/services/dynamic-secret-lease/dynamic-secret-lease-service.ts +++ b/backend/src/ee/services/dynamic-secret-lease/dynamic-secret-lease-service.ts @@ -249,7 +249,7 @@ export const dynamicSecretLeaseServiceFactory = ({ if ((revokeResponse as { error?: Error })?.error) { const { error } = revokeResponse as { error?: Error }; - logger.error("Failed to revoke lease", { error: error?.message }); + logger.error(error?.message, "Failed to revoke lease"); const deletedDynamicSecretLease = await dynamicSecretLeaseDAL.updateById(dynamicSecretLease.id, { status: DynamicSecretLeaseStatus.FailedDeletion, statusDetails: error?.message?.slice(0, 255) diff --git a/backend/src/ee/services/dynamic-secret/providers/models.ts b/backend/src/ee/services/dynamic-secret/providers/models.ts index 2932fd924..9d45a7401 100644 --- a/backend/src/ee/services/dynamic-secret/providers/models.ts +++ b/backend/src/ee/services/dynamic-secret/providers/models.ts @@ -1,7 +1,8 @@ import { z } from "zod"; export enum SqlProviders { - Postgres = "postgres" + Postgres = "postgres", + MySQL = "mysql2" } export const DynamicSecretSqlDBSchema = z.object({ @@ -13,7 +14,7 @@ export const DynamicSecretSqlDBSchema = z.object({ password: z.string(), creationStatement: z.string(), revocationStatement: z.string(), - renewStatement: z.string(), + renewStatement: z.string().optional(), ca: z.string().optional() }); diff --git a/backend/src/ee/services/dynamic-secret/providers/sql-database.ts b/backend/src/ee/services/dynamic-secret/providers/sql-database.ts index 7107fe3a3..ae61fa011 100644 --- a/backend/src/ee/services/dynamic-secret/providers/sql-database.ts +++ b/backend/src/ee/services/dynamic-secret/providers/sql-database.ts @@ -48,10 +48,10 @@ export const SqlDatabaseProvider = (): TDynamicProviderFns => { host: providerInputs.host, user: providerInputs.username, password: providerInputs.password, - connectionTimeoutMillis: EXTERNAL_REQUEST_TIMEOUT, ssl, pool: { min: 0, max: 1 } - } + }, + acquireConnectionTimeout: EXTERNAL_REQUEST_TIMEOUT }); return db; }; @@ -73,15 +73,25 @@ export const SqlDatabaseProvider = (): TDynamicProviderFns => { const username = alphaNumericNanoId(32); const password = generatePassword(); + const { database } = providerInputs; const expiration = new Date(expireAt).toISOString(); const creationStatement = handlebars.compile(providerInputs.creationStatement, { noEscape: true })({ username, password, - expiration + expiration, + database }); - await db.raw(creationStatement.toString()); + await db.transaction(async (tx) => + Promise.all( + creationStatement + .toString() + .split(";") + .filter(Boolean) + .map((query) => tx.raw(query)) + ) + ); await db.destroy(); return { entityId: username, data: { DB_USERNAME: username, DB_PASSWORD: password } }; }; @@ -91,9 +101,18 @@ export const SqlDatabaseProvider = (): TDynamicProviderFns => { const db = await getClient(providerInputs); const username = entityId; + const { database } = providerInputs; - const revokeStatement = handlebars.compile(providerInputs.revocationStatement)({ username }); - await db.raw(revokeStatement); + const revokeStatement = handlebars.compile(providerInputs.revocationStatement)({ username, database }); + await db.transaction(async (tx) => + Promise.all( + revokeStatement + .toString() + .split(";") + .filter(Boolean) + .map((query) => tx.raw(query)) + ) + ); await db.destroy(); return { entityId: username }; @@ -105,9 +124,19 @@ export const SqlDatabaseProvider = (): TDynamicProviderFns => { const username = entityId; const expiration = new Date(expireAt).toISOString(); + const { database } = providerInputs; - const renewStatement = handlebars.compile(providerInputs.renewStatement)({ username, expiration }); - await db.raw(renewStatement); + const renewStatement = handlebars.compile(providerInputs.renewStatement)({ username, expiration, database }); + if (renewStatement) + await db.transaction(async (tx) => + Promise.all( + renewStatement + .toString() + .split(";") + .filter(Boolean) + .map((query) => tx.raw(query)) + ) + ); await db.destroy(); return { entityId: username };