From 31209b7acc153e3ac19fb1bcc47b255c3dd55861 Mon Sep 17 00:00:00 2001 From: Zhongnan Su Date: Thu, 23 May 2024 15:27:29 -0700 Subject: [PATCH] [MD] Fix server sider endpoint validation by passing in request when creating datasource client (#6822) * [MD] Fix endpoint validation by passing in request when creating data source client Signed-off-by: Zhongnan Su --- changelogs/fragments/6822.yml | 2 ++ ...ource_saved_objects_client_wrapper.test.ts | 20 ++++++++++++- ...ata_source_saved_objects_client_wrapper.ts | 30 ++++++++++++++----- 3 files changed, 44 insertions(+), 8 deletions(-) create mode 100644 changelogs/fragments/6822.yml diff --git a/changelogs/fragments/6822.yml b/changelogs/fragments/6822.yml new file mode 100644 index 000000000000..83df4b59675c --- /dev/null +++ b/changelogs/fragments/6822.yml @@ -0,0 +1,2 @@ +fix: +- Fix endpoint validation by passing in request when creating datasource client ([#6822](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6822)) \ No newline at end of file diff --git a/src/plugins/data_source/server/saved_objects/data_source_saved_objects_client_wrapper.test.ts b/src/plugins/data_source/server/saved_objects/data_source_saved_objects_client_wrapper.test.ts index 9b9fe899a7a7..d3d082a73391 100644 --- a/src/plugins/data_source/server/saved_objects/data_source_saved_objects_client_wrapper.test.ts +++ b/src/plugins/data_source/server/saved_objects/data_source_saved_objects_client_wrapper.test.ts @@ -40,6 +40,7 @@ describe('DataSourceSavedObjectsClientWrapper', () => { const customApiSchemaRegistry = new CustomApiSchemaRegistry(); const customApiSchemaRegistryPromise = Promise.resolve(customApiSchemaRegistry); const dataSourceServiceSetup = dataSourceServiceSetupMock.create(); + const requestMock = httpServerMock.createOpenSearchDashboardsRequest(); const wrapperInstance = new DataSourceSavedObjectsClientWrapper( dataSourceServiceSetup, cryptographyMock, @@ -52,7 +53,7 @@ describe('DataSourceSavedObjectsClientWrapper', () => { const wrapperClient = wrapperInstance.wrapperFactory({ client: mockedClient, typeRegistry: requestHandlerContext.savedObjects.typeRegistry, - request: httpServerMock.createOpenSearchDashboardsRequest(), + request: requestMock, }); const getSavedObject = (savedObject: Partial) => { @@ -204,6 +205,23 @@ describe('DataSourceSavedObjectsClientWrapper', () => { ).rejects.toThrowError(`Invalid auth type: 'not_in_registry': Bad Request`); }); + it('endpoint validator datasource client should be created with request as param', async () => { + const mockDataSourceAttributesWithNoAuth = attributes({ + auth: { + type: AuthType.NoAuth, + }, + }); + + await wrapperClient.create( + DATA_SOURCE_SAVED_OBJECT_TYPE, + mockDataSourceAttributesWithNoAuth, + {} + ); + expect(dataSourceServiceSetup.getDataSourceClient).toBeCalledWith( + expect.objectContaining({ request: requestMock }) + ); + }); + describe('createWithCredentialsEncryption: Error handling', () => { it('should throw error when title is empty', async () => { const mockDataSourceAttributes = attributes({ diff --git a/src/plugins/data_source/server/saved_objects/data_source_saved_objects_client_wrapper.ts b/src/plugins/data_source/server/saved_objects/data_source_saved_objects_client_wrapper.ts index e56536cb2aa5..35990f05777f 100644 --- a/src/plugins/data_source/server/saved_objects/data_source_saved_objects_client_wrapper.ts +++ b/src/plugins/data_source/server/saved_objects/data_source_saved_objects_client_wrapper.ts @@ -5,6 +5,7 @@ import { OpenSearchClient, + OpenSearchDashboardsRequest, SavedObjectsBulkCreateObject, SavedObjectsBulkResponse, SavedObjectsBulkUpdateObject, @@ -51,7 +52,10 @@ export class DataSourceSavedObjectsClientWrapper { return await wrapperOptions.client.create(type, attributes, options); } - const encryptedAttributes = await this.validateAndEncryptAttributes(attributes); + const encryptedAttributes = await this.validateAndEncryptAttributes( + attributes, + wrapperOptions.request + ); return await wrapperOptions.client.create(type, encryptedAttributes, options); }; @@ -70,7 +74,7 @@ export class DataSourceSavedObjectsClientWrapper { return { ...object, - attributes: await this.validateAndEncryptAttributes(attributes), + attributes: await this.validateAndEncryptAttributes(attributes, wrapperOptions.request), }; }) ); @@ -152,8 +156,11 @@ export class DataSourceSavedObjectsClientWrapper { private endpointBlockedIps?: string[] ) {} - private async validateAndEncryptAttributes(attributes: T) { - await this.validateAttributes(attributes); + private async validateAndEncryptAttributes( + attributes: T, + request?: OpenSearchDashboardsRequest + ) { + await this.validateAttributes(attributes, request); const { endpoint, auth } = attributes; @@ -257,11 +264,14 @@ export class DataSourceSavedObjectsClientWrapper { } } - private async validateAttributes(attributes: T) { + private async validateAttributes( + attributes: T, + request?: OpenSearchDashboardsRequest + ) { const { title, endpoint, auth } = attributes; this.validateTitle(title); - await this.validateEndpoint(endpoint, attributes as DataSourceAttributes); + await this.validateEndpoint(endpoint, attributes as DataSourceAttributes, request); await this.validateAuth(auth); } @@ -279,7 +289,11 @@ export class DataSourceSavedObjectsClientWrapper { } } - private async validateEndpoint(endpoint: string, attributes: DataSourceAttributes) { + private async validateEndpoint( + endpoint: string, + attributes: DataSourceAttributes, + request?: OpenSearchDashboardsRequest + ) { if (!isValidURL(endpoint, this.endpointBlockedIps)) { throw SavedObjectsErrorHelpers.createBadRequestError( '"endpoint" attribute is not valid or allowed' @@ -290,6 +304,7 @@ export class DataSourceSavedObjectsClientWrapper { savedObjects: {} as any, cryptography: this.cryptography, testClientDataSourceAttr: attributes as DataSourceAttributes, + request, authRegistry: await this.authRegistryPromise, customApiSchemaRegistryPromise: this.customApiSchemaRegistryPromise, }); @@ -298,6 +313,7 @@ export class DataSourceSavedObjectsClientWrapper { await dataSourceValidator.validate(); } catch (err: any) { + this.logger.error(err); throw SavedObjectsErrorHelpers.createBadRequestError( `endpoint is not valid OpenSearch endpoint` );