From e8fa690566c9b4123d86d27ed334e1a0509eac7b Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Fri, 12 May 2023 10:07:59 +0200 Subject: [PATCH 1/4] Add mongo checks --- packages/server/src/integrations/mongodb.ts | 10 +++ .../src/integrations/validators/mongo.spec.ts | 88 +++++++++++++++++++ 2 files changed, 98 insertions(+) create mode 100644 qa-core/src/integrations/validators/mongo.spec.ts diff --git a/packages/server/src/integrations/mongodb.ts b/packages/server/src/integrations/mongodb.ts index 38b3891fe4..77dc2ad7b2 100644 --- a/packages/server/src/integrations/mongodb.ts +++ b/packages/server/src/integrations/mongodb.ts @@ -631,8 +631,18 @@ class MongoIntegration implements IntegrationBase { } } } +async function validateConnection(config: MongoDBConfig) { + const integration = new MongoIntegration(config) + try { + await integration.connect() + return true + } catch (e: any) { + return { error: e.message as string } + } +} export default { schema: SCHEMA, integration: MongoIntegration, + validateConnection, } diff --git a/qa-core/src/integrations/validators/mongo.spec.ts b/qa-core/src/integrations/validators/mongo.spec.ts new file mode 100644 index 0000000000..1c4729513e --- /dev/null +++ b/qa-core/src/integrations/validators/mongo.spec.ts @@ -0,0 +1,88 @@ +import { GenericContainer } from "testcontainers" +import mongodb from "../../../../packages/server/src/integrations/mongodb" + +jest.unmock("mongodb") + +describe("datasource validators", () => { + describe("mongo", () => { + const validator = integrations.getValidator[SourceName.MONGODB] + + let connectionSettings: { + user: string + password: string + host: string + port: number + } + + function getConnectionString( + settings: Partial = {} + ) { + const { user, password, host, port } = { + ...connectionSettings, + ...settings, + } + return `mongodb://${user}:${password}@${host}:${port}` + } + + beforeAll(async () => { + const user = generator.name() + const password = generator.hash() + const container = await new GenericContainer("mongo") + .withExposedPorts(27017) + .withEnv("MONGO_INITDB_ROOT_USERNAME", user) + .withEnv("MONGO_INITDB_ROOT_PASSWORD", password) + .start() + + connectionSettings = { + user, + password, + host: container.getContainerIpAddress(), + port: container.getMappedPort(27017), + } + }) + + it("test valid connection string", async () => { + const result = await validator({ + connectionString: getConnectionString(), + db: "", + tlsCertificateFile: "", + tlsCertificateKeyFile: "", + tlsCAFile: "", + }) + expect(result).toBe(true) + }) + + it("test invalid password", async () => { + const result = await validator({ + connectionString: getConnectionString({ password: "wrong" }), + db: "", + tlsCertificateFile: "", + tlsCertificateKeyFile: "", + tlsCAFile: "", + }) + expect(result).toEqual({ error: "Authentication failed." }) + }) + + it("test invalid username", async () => { + const result = await validator({ + connectionString: getConnectionString({ user: "wrong" }), + db: "", + tlsCertificateFile: "", + tlsCertificateKeyFile: "", + tlsCAFile: "", + }) + expect(result).toEqual({ error: "Authentication failed." }) + }) + + it("test invalid connection", async () => { + const result = await validator({ + connectionString: getConnectionString({ host: "http://nothinghere" }), + db: "", + tlsCertificateFile: "", + tlsCertificateKeyFile: "", + tlsCAFile: "", + }) + expect(result).toEqual({ error: "Error: getaddrinfo ENOTFOUND http" }) + }) + }) +}) From 2f9b07638140473e45141ddad3c6da25a3b60fc6 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Fri, 12 May 2023 12:59:59 +0200 Subject: [PATCH 2/4] Implement the check as part of the integration --- packages/server/src/integrations/mongodb.ts | 19 +++++++++---------- .../src/integrations/validators/mongo.spec.ts | 17 ++++++++++------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/packages/server/src/integrations/mongodb.ts b/packages/server/src/integrations/mongodb.ts index 77dc2ad7b2..b8e4089411 100644 --- a/packages/server/src/integrations/mongodb.ts +++ b/packages/server/src/integrations/mongodb.ts @@ -358,6 +358,15 @@ class MongoIntegration implements IntegrationBase { this.client = new MongoClient(config.connectionString, options) } + async testConnection() { + try { + await this.connect() + return true + } catch (e: any) { + return { error: e.message as string } + } + } + async connect() { return this.client.connect() } @@ -631,18 +640,8 @@ class MongoIntegration implements IntegrationBase { } } } -async function validateConnection(config: MongoDBConfig) { - const integration = new MongoIntegration(config) - try { - await integration.connect() - return true - } catch (e: any) { - return { error: e.message as string } - } -} export default { schema: SCHEMA, integration: MongoIntegration, - validateConnection, } diff --git a/qa-core/src/integrations/validators/mongo.spec.ts b/qa-core/src/integrations/validators/mongo.spec.ts index 1c4729513e..dd8e188f27 100644 --- a/qa-core/src/integrations/validators/mongo.spec.ts +++ b/qa-core/src/integrations/validators/mongo.spec.ts @@ -1,12 +1,11 @@ import { GenericContainer } from "testcontainers" -import mongodb from "../../../../packages/server/src/integrations/mongodb" +import mongo from "../../../../packages/server/src/integrations/mongodb" +import { generator } from "../../shared" jest.unmock("mongodb") describe("datasource validators", () => { describe("mongo", () => { - const validator = integrations.getValidator[SourceName.MONGODB] - let connectionSettings: { user: string password: string @@ -42,46 +41,50 @@ describe("datasource validators", () => { }) it("test valid connection string", async () => { - const result = await validator({ + const integration = new mongo.integration({ connectionString: getConnectionString(), db: "", tlsCertificateFile: "", tlsCertificateKeyFile: "", tlsCAFile: "", }) + const result = await integration.testConnection() expect(result).toBe(true) }) it("test invalid password", async () => { - const result = await validator({ + const integration = new mongo.integration({ connectionString: getConnectionString({ password: "wrong" }), db: "", tlsCertificateFile: "", tlsCertificateKeyFile: "", tlsCAFile: "", }) + const result = await integration.testConnection() expect(result).toEqual({ error: "Authentication failed." }) }) it("test invalid username", async () => { - const result = await validator({ + const integration = new mongo.integration({ connectionString: getConnectionString({ user: "wrong" }), db: "", tlsCertificateFile: "", tlsCertificateKeyFile: "", tlsCAFile: "", }) + const result = await integration.testConnection() expect(result).toEqual({ error: "Authentication failed." }) }) it("test invalid connection", async () => { - const result = await validator({ + const integration = new mongo.integration({ connectionString: getConnectionString({ host: "http://nothinghere" }), db: "", tlsCertificateFile: "", tlsCertificateKeyFile: "", tlsCAFile: "", }) + const result = await integration.testConnection() expect(result).toEqual({ error: "Error: getaddrinfo ENOTFOUND http" }) }) }) From b41438c854df001b680ca1666ad4a7f799fa2fc6 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Fri, 12 May 2023 13:01:49 +0200 Subject: [PATCH 3/4] Clean code --- packages/pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pro b/packages/pro index 14345384f7..c57a98d246 160000 --- a/packages/pro +++ b/packages/pro @@ -1 +1 @@ -Subproject commit 14345384f7a6755d1e2de327104741e0f208f55d +Subproject commit c57a98d246a50a43905d8572a88c901ec598390c From 8b73b768953ad34434c812eeed24306c85417631 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Mon, 15 May 2023 16:39:33 +0200 Subject: [PATCH 4/4] Undo refs --- packages/pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pro b/packages/pro index c57a98d246..14345384f7 160000 --- a/packages/pro +++ b/packages/pro @@ -1 +1 @@ -Subproject commit c57a98d246a50a43905d8572a88c901ec598390c +Subproject commit 14345384f7a6755d1e2de327104741e0f208f55d