Skip to content

Commit 54b5eb5

Browse files
authored
[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 <[email protected]>
1 parent 972cf10 commit 54b5eb5

File tree

3 files changed

+44
-8
lines changed

3 files changed

+44
-8
lines changed

changelogs/fragments/6822.yml

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
fix:
2+
- Fix endpoint validation by passing in request when creating datasource client ([#6822](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6822))

src/plugins/data_source/server/saved_objects/data_source_saved_objects_client_wrapper.test.ts

+19-1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ describe('DataSourceSavedObjectsClientWrapper', () => {
4040
const customApiSchemaRegistry = new CustomApiSchemaRegistry();
4141
const customApiSchemaRegistryPromise = Promise.resolve(customApiSchemaRegistry);
4242
const dataSourceServiceSetup = dataSourceServiceSetupMock.create();
43+
const requestMock = httpServerMock.createOpenSearchDashboardsRequest();
4344
const wrapperInstance = new DataSourceSavedObjectsClientWrapper(
4445
dataSourceServiceSetup,
4546
cryptographyMock,
@@ -52,7 +53,7 @@ describe('DataSourceSavedObjectsClientWrapper', () => {
5253
const wrapperClient = wrapperInstance.wrapperFactory({
5354
client: mockedClient,
5455
typeRegistry: requestHandlerContext.savedObjects.typeRegistry,
55-
request: httpServerMock.createOpenSearchDashboardsRequest(),
56+
request: requestMock,
5657
});
5758

5859
const getSavedObject = (savedObject: Partial<SavedObject>) => {
@@ -204,6 +205,23 @@ describe('DataSourceSavedObjectsClientWrapper', () => {
204205
).rejects.toThrowError(`Invalid auth type: 'not_in_registry': Bad Request`);
205206
});
206207

208+
it('endpoint validator datasource client should be created with request as param', async () => {
209+
const mockDataSourceAttributesWithNoAuth = attributes({
210+
auth: {
211+
type: AuthType.NoAuth,
212+
},
213+
});
214+
215+
await wrapperClient.create(
216+
DATA_SOURCE_SAVED_OBJECT_TYPE,
217+
mockDataSourceAttributesWithNoAuth,
218+
{}
219+
);
220+
expect(dataSourceServiceSetup.getDataSourceClient).toBeCalledWith(
221+
expect.objectContaining({ request: requestMock })
222+
);
223+
});
224+
207225
describe('createWithCredentialsEncryption: Error handling', () => {
208226
it('should throw error when title is empty', async () => {
209227
const mockDataSourceAttributes = attributes({

src/plugins/data_source/server/saved_objects/data_source_saved_objects_client_wrapper.ts

+23-7
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import {
77
OpenSearchClient,
8+
OpenSearchDashboardsRequest,
89
SavedObjectsBulkCreateObject,
910
SavedObjectsBulkResponse,
1011
SavedObjectsBulkUpdateObject,
@@ -51,7 +52,10 @@ export class DataSourceSavedObjectsClientWrapper {
5152
return await wrapperOptions.client.create(type, attributes, options);
5253
}
5354

54-
const encryptedAttributes = await this.validateAndEncryptAttributes(attributes);
55+
const encryptedAttributes = await this.validateAndEncryptAttributes(
56+
attributes,
57+
wrapperOptions.request
58+
);
5559

5660
return await wrapperOptions.client.create(type, encryptedAttributes, options);
5761
};
@@ -70,7 +74,7 @@ export class DataSourceSavedObjectsClientWrapper {
7074

7175
return {
7276
...object,
73-
attributes: await this.validateAndEncryptAttributes(attributes),
77+
attributes: await this.validateAndEncryptAttributes(attributes, wrapperOptions.request),
7478
};
7579
})
7680
);
@@ -152,8 +156,11 @@ export class DataSourceSavedObjectsClientWrapper {
152156
private endpointBlockedIps?: string[]
153157
) {}
154158

155-
private async validateAndEncryptAttributes<T = unknown>(attributes: T) {
156-
await this.validateAttributes(attributes);
159+
private async validateAndEncryptAttributes<T = unknown>(
160+
attributes: T,
161+
request?: OpenSearchDashboardsRequest
162+
) {
163+
await this.validateAttributes(attributes, request);
157164

158165
const { endpoint, auth } = attributes;
159166

@@ -257,11 +264,14 @@ export class DataSourceSavedObjectsClientWrapper {
257264
}
258265
}
259266

260-
private async validateAttributes<T = unknown>(attributes: T) {
267+
private async validateAttributes<T = unknown>(
268+
attributes: T,
269+
request?: OpenSearchDashboardsRequest
270+
) {
261271
const { title, endpoint, auth } = attributes;
262272

263273
this.validateTitle(title);
264-
await this.validateEndpoint(endpoint, attributes as DataSourceAttributes);
274+
await this.validateEndpoint(endpoint, attributes as DataSourceAttributes, request);
265275
await this.validateAuth(auth);
266276
}
267277

@@ -279,7 +289,11 @@ export class DataSourceSavedObjectsClientWrapper {
279289
}
280290
}
281291

282-
private async validateEndpoint(endpoint: string, attributes: DataSourceAttributes) {
292+
private async validateEndpoint(
293+
endpoint: string,
294+
attributes: DataSourceAttributes,
295+
request?: OpenSearchDashboardsRequest
296+
) {
283297
if (!isValidURL(endpoint, this.endpointBlockedIps)) {
284298
throw SavedObjectsErrorHelpers.createBadRequestError(
285299
'"endpoint" attribute is not valid or allowed'
@@ -290,6 +304,7 @@ export class DataSourceSavedObjectsClientWrapper {
290304
savedObjects: {} as any,
291305
cryptography: this.cryptography,
292306
testClientDataSourceAttr: attributes as DataSourceAttributes,
307+
request,
293308
authRegistry: await this.authRegistryPromise,
294309
customApiSchemaRegistryPromise: this.customApiSchemaRegistryPromise,
295310
});
@@ -298,6 +313,7 @@ export class DataSourceSavedObjectsClientWrapper {
298313

299314
await dataSourceValidator.validate();
300315
} catch (err: any) {
316+
this.logger.error(err);
301317
throw SavedObjectsErrorHelpers.createBadRequestError(
302318
`endpoint is not valid OpenSearch endpoint`
303319
);

0 commit comments

Comments
 (0)