feat(server): added mysql dynamic secret server logic

This commit is contained in:
Akhil Mohan
2024-04-15 19:34:47 +05:30
parent fbc7b34786
commit 6410d51033
3 changed files with 41 additions and 11 deletions
@@ -249,7 +249,7 @@ export const dynamicSecretLeaseServiceFactory = ({
if ((revokeResponse as { error?: Error })?.error) { if ((revokeResponse as { error?: Error })?.error) {
const { error } = revokeResponse as { 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, { const deletedDynamicSecretLease = await dynamicSecretLeaseDAL.updateById(dynamicSecretLease.id, {
status: DynamicSecretLeaseStatus.FailedDeletion, status: DynamicSecretLeaseStatus.FailedDeletion,
statusDetails: error?.message?.slice(0, 255) statusDetails: error?.message?.slice(0, 255)
@@ -1,7 +1,8 @@
import { z } from "zod"; import { z } from "zod";
export enum SqlProviders { export enum SqlProviders {
Postgres = "postgres" Postgres = "postgres",
MySQL = "mysql2"
} }
export const DynamicSecretSqlDBSchema = z.object({ export const DynamicSecretSqlDBSchema = z.object({
@@ -13,7 +14,7 @@ export const DynamicSecretSqlDBSchema = z.object({
password: z.string(), password: z.string(),
creationStatement: z.string(), creationStatement: z.string(),
revocationStatement: z.string(), revocationStatement: z.string(),
renewStatement: z.string(), renewStatement: z.string().optional(),
ca: z.string().optional() ca: z.string().optional()
}); });
@@ -48,10 +48,10 @@ export const SqlDatabaseProvider = (): TDynamicProviderFns => {
host: providerInputs.host, host: providerInputs.host,
user: providerInputs.username, user: providerInputs.username,
password: providerInputs.password, password: providerInputs.password,
connectionTimeoutMillis: EXTERNAL_REQUEST_TIMEOUT,
ssl, ssl,
pool: { min: 0, max: 1 } pool: { min: 0, max: 1 }
} },
acquireConnectionTimeout: EXTERNAL_REQUEST_TIMEOUT
}); });
return db; return db;
}; };
@@ -73,15 +73,25 @@ export const SqlDatabaseProvider = (): TDynamicProviderFns => {
const username = alphaNumericNanoId(32); const username = alphaNumericNanoId(32);
const password = generatePassword(); const password = generatePassword();
const { database } = providerInputs;
const expiration = new Date(expireAt).toISOString(); const expiration = new Date(expireAt).toISOString();
const creationStatement = handlebars.compile(providerInputs.creationStatement, { noEscape: true })({ const creationStatement = handlebars.compile(providerInputs.creationStatement, { noEscape: true })({
username, username,
password, 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(); await db.destroy();
return { entityId: username, data: { DB_USERNAME: username, DB_PASSWORD: password } }; return { entityId: username, data: { DB_USERNAME: username, DB_PASSWORD: password } };
}; };
@@ -91,9 +101,18 @@ export const SqlDatabaseProvider = (): TDynamicProviderFns => {
const db = await getClient(providerInputs); const db = await getClient(providerInputs);
const username = entityId; const username = entityId;
const { database } = providerInputs;
const revokeStatement = handlebars.compile(providerInputs.revocationStatement)({ username }); const revokeStatement = handlebars.compile(providerInputs.revocationStatement)({ username, database });
await db.raw(revokeStatement); await db.transaction(async (tx) =>
Promise.all(
revokeStatement
.toString()
.split(";")
.filter(Boolean)
.map((query) => tx.raw(query))
)
);
await db.destroy(); await db.destroy();
return { entityId: username }; return { entityId: username };
@@ -105,9 +124,19 @@ export const SqlDatabaseProvider = (): TDynamicProviderFns => {
const username = entityId; const username = entityId;
const expiration = new Date(expireAt).toISOString(); const expiration = new Date(expireAt).toISOString();
const { database } = providerInputs;
const renewStatement = handlebars.compile(providerInputs.renewStatement)({ username, expiration }); const renewStatement = handlebars.compile(providerInputs.renewStatement)({ username, expiration, database });
await db.raw(renewStatement); if (renewStatement)
await db.transaction(async (tx) =>
Promise.all(
renewStatement
.toString()
.split(";")
.filter(Boolean)
.map((query) => tx.raw(query))
)
);
await db.destroy(); await db.destroy();
return { entityId: username }; return { entityId: username };