diff --git a/CHANGELOG.md b/CHANGELOG.md index 042f8a5ac53a..b7e9cff5c6e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) - [BUG][Discover] Allow saved sort from search embeddable to load in Dashboard ([#5934](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/5934)) - [BUG][Discover] Add key to index pattern options for support deplicate index pattern names([#5946](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/5946)) - [Discover] Fix table cell content overflowing in Safari ([#5948](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/5948)) +- [BUG][MD]Fix schema for test connection to separate validation based on auth type([#5997](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/5997)) ### 🚞 Infrastructure diff --git a/src/plugins/data_source/server/routes/test_connection.test.ts b/src/plugins/data_source/server/routes/test_connection.test.ts index 9ad414e28660..fb6146949084 100644 --- a/src/plugins/data_source/server/routes/test_connection.test.ts +++ b/src/plugins/data_source/server/routes/test_connection.test.ts @@ -42,6 +42,64 @@ describe(`Test connection ${URL}`, () => { }, }; + const dataSourceAttrMissingCredentialForNoAuth = { + endpoint: 'https://test.com', + auth: { + type: AuthType.NoAuth, + credentials: {}, + }, + }; + + const dataSourceAttrMissingCredentialForBasicAuth = { + endpoint: 'https://test.com', + auth: { + type: AuthType.UsernamePasswordType, + credentials: {}, + }, + }; + + const dataSourceAttrMissingCredentialForSigV4Auth = { + endpoint: 'https://test.com', + auth: { + type: AuthType.SigV4, + credentials: {}, + }, + }; + + const dataSourceAttrPartialCredentialForSigV4Auth = { + endpoint: 'https://test.com', + auth: { + type: AuthType.SigV4, + credentials: { + accessKey: 'testKey', + service: 'service', + }, + }, + }; + + const dataSourceAttrPartialCredentialForBasicAuth = { + endpoint: 'https://test.com', + auth: { + type: AuthType.UsernamePasswordType, + credentials: { + username: 'testName', + }, + }, + }; + + const dataSourceAttrForSigV4Auth = { + endpoint: 'https://test.com', + auth: { + type: AuthType.SigV4, + credentials: { + accessKey: 'testKey', + service: 'es', + secretKey: 'testSecret', + region: 'testRegion', + }, + }, + }; + beforeEach(async () => { ({ server, httpSetup, handlerContext } = await setupServer()); customApiSchemaRegistryPromise = Promise.resolve(customApiSchemaRegistry); @@ -91,4 +149,70 @@ describe(`Test connection ${URL}`, () => { }) ); }); + + it('no credential with no auth should succeed', async () => { + const result = await supertest(httpSetup.server.listener) + .post(URL) + .send({ + id: 'testId', + dataSourceAttr: dataSourceAttrMissingCredentialForNoAuth, + }) + .expect(200); + expect(result.body).toEqual({ success: true }); + }); + + it('no credential with basic auth should fail', async () => { + const result = await supertest(httpSetup.server.listener) + .post(URL) + .send({ + id: 'testId', + dataSourceAttr: dataSourceAttrMissingCredentialForBasicAuth, + }) + .expect(400); + expect(result.body.error).toEqual('Bad Request'); + }); + + it('no credential with sigv4 auth should fail', async () => { + const result = await supertest(httpSetup.server.listener) + .post(URL) + .send({ + id: 'testId', + dataSourceAttr: dataSourceAttrMissingCredentialForSigV4Auth, + }) + .expect(400); + expect(result.body.error).toEqual('Bad Request'); + }); + + it('partial credential with sigv4 auth should fail', async () => { + const result = await supertest(httpSetup.server.listener) + .post(URL) + .send({ + id: 'testId', + dataSourceAttr: dataSourceAttrPartialCredentialForSigV4Auth, + }) + .expect(400); + expect(result.body.error).toEqual('Bad Request'); + }); + + it('partial credential with basic auth should fail', async () => { + const result = await supertest(httpSetup.server.listener) + .post(URL) + .send({ + id: 'testId', + dataSourceAttr: dataSourceAttrPartialCredentialForBasicAuth, + }) + .expect(400); + expect(result.body.error).toEqual('Bad Request'); + }); + + it('full credential with sigV4 auth should success', async () => { + const result = await supertest(httpSetup.server.listener) + .post(URL) + .send({ + id: 'testId', + dataSourceAttr: dataSourceAttrForSigV4Auth, + }) + .expect(200); + expect(result.body).toEqual({ success: true }); + }); }); diff --git a/src/plugins/data_source/server/routes/test_connection.ts b/src/plugins/data_source/server/routes/test_connection.ts index b4c3d091aa35..ac6bc10ff39a 100644 --- a/src/plugins/data_source/server/routes/test_connection.ts +++ b/src/plugins/data_source/server/routes/test_connection.ts @@ -10,6 +10,7 @@ import { DataSourceConnectionValidator } from './data_source_connection_validato import { DataSourceServiceSetup } from '../data_source_service'; import { CryptographyServiceSetup } from '../cryptography_service'; import { IAuthenticationMethodRegistery } from '../auth_registry'; +import { CustomApiSchemaRegistry } from '../schema_registry/custom_api_schema_registry'; export const registerTestConnectionRoute = async ( router: IRouter, @@ -28,30 +29,31 @@ export const registerTestConnectionRoute = async ( dataSourceAttr: schema.object({ endpoint: schema.string(), auth: schema.maybe( - schema.object({ - type: schema.oneOf([ - schema.literal(AuthType.UsernamePasswordType), - schema.literal(AuthType.NoAuth), - schema.literal(AuthType.SigV4), - ]), - credentials: schema.maybe( - schema.oneOf([ - schema.object({ - username: schema.string(), - password: schema.string(), - }), - schema.object({ - region: schema.string(), - accessKey: schema.string(), - secretKey: schema.string(), - service: schema.oneOf([ - schema.literal(SigV4ServiceName.OpenSearch), - schema.literal(SigV4ServiceName.OpenSearchServerless), - ]), - }), - ]) - ), - }) + schema.oneOf([ + schema.object({ + type: schema.literal(AuthType.NoAuth), + credentials: schema.object({}), + }), + schema.object({ + type: schema.literal(AuthType.UsernamePasswordType), + credentials: schema.object({ + username: schema.string(), + password: schema.string(), + }), + }), + schema.object({ + type: schema.literal(AuthType.SigV4), + credentials: schema.object({ + region: schema.string(), + accessKey: schema.string(), + secretKey: schema.string(), + service: schema.oneOf([ + schema.literal(SigV4ServiceName.OpenSearch), + schema.literal(SigV4ServiceName.OpenSearchServerless), + ]), + }), + }), + ]) ), }), }),