mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[Security Solution][Connectors] Torq connector allow EU hooks hostname (#212563)
## Summary From: https://github.com/elastic/kibana/issues/212511 Add support for EU domains --------- Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
parent
5041031b5d
commit
723a33b7de
5 changed files with 68 additions and 5 deletions
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
const hostNameRegExp = /^hooks\.(eu\.)?torq\.io$/;
|
||||
|
||||
export const isValidTorqHostName = (hostName: string) => {
|
||||
return hostNameRegExp.test(hostName);
|
||||
};
|
|
@ -93,6 +93,41 @@ describe('TorqActionConnectorFields renders', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('connector validation succeeds when using a EU torq webhook URL', async () => {
|
||||
const connector = {
|
||||
...actionConnector,
|
||||
config: { webhookIntegrationUrl: 'https://hooks.eu.torq.io/v1/webhooks/fjdksla' },
|
||||
};
|
||||
const { getByTestId } = render(
|
||||
<ConnectorFormTestProvider connector={connector} onSubmit={onSubmit}>
|
||||
<TorqActionConnectorFields
|
||||
readOnly={false}
|
||||
isEdit={false}
|
||||
registerPreSubmitValidator={EMPTY_FUNC}
|
||||
/>
|
||||
</ConnectorFormTestProvider>
|
||||
);
|
||||
|
||||
await act(async () => {
|
||||
await userEvent.click(getByTestId('form-test-provide-submit'));
|
||||
});
|
||||
|
||||
expect(onSubmit).toBeCalledWith({
|
||||
data: {
|
||||
actionTypeId: '.torq',
|
||||
name: 'torq',
|
||||
config: {
|
||||
webhookIntegrationUrl: 'https://hooks.eu.torq.io/v1/webhooks/fjdksla',
|
||||
},
|
||||
secrets: {
|
||||
token: 'testtoken',
|
||||
},
|
||||
isDeprecated: false,
|
||||
},
|
||||
isValid: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('connector validation fails when there is no token', async () => {
|
||||
const connector = {
|
||||
...actionConnector,
|
||||
|
@ -153,7 +188,7 @@ describe('TorqActionConnectorFields renders', () => {
|
|||
const connector = {
|
||||
...actionConnector,
|
||||
config: {
|
||||
webhookIntegrationUrl: 'https://test.com',
|
||||
webhookIntegrationUrl: 'https://hooks.not-torq.io/v1/webhooks/fjdksla',
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ import {
|
|||
import { isUrl } from '@kbn/es-ui-shared-plugin/static/validators/string';
|
||||
import { ActionConnectorFieldsProps } from '@kbn/triggers-actions-ui-plugin/public';
|
||||
import React from 'react';
|
||||
import { isValidTorqHostName } from '../../../common/torq';
|
||||
import * as i18n from './translations';
|
||||
|
||||
const { urlField, emptyField } = fieldValidators;
|
||||
|
@ -42,7 +43,7 @@ const torqWebhookEndpoint =
|
|||
};
|
||||
if (!isUrl(value)) return error;
|
||||
const hostname = new URL(value).hostname;
|
||||
return hostname === 'hooks.torq.io' ? undefined : error;
|
||||
return isValidTorqHostName(hostname) ? undefined : error;
|
||||
};
|
||||
|
||||
const TorqActionConnectorFields: React.FunctionComponent<ActionConnectorFieldsProps> = ({
|
||||
|
|
|
@ -85,6 +85,15 @@ describe('config validation', () => {
|
|||
...config,
|
||||
});
|
||||
});
|
||||
test('config validation passes with the EU endpoint', () => {
|
||||
const config: Record<string, string | boolean> = {
|
||||
webhookIntegrationUrl: 'https://hooks.eu.torq.io/v1/test',
|
||||
};
|
||||
expect(validateConfig(actionType, config, { configurationUtilities })).toEqual({
|
||||
...defaultValues,
|
||||
...config,
|
||||
});
|
||||
});
|
||||
|
||||
const errorCases: Array<{ name: string; url: string; errorMsg: string }> = [
|
||||
{
|
||||
|
@ -100,7 +109,12 @@ describe('config validation', () => {
|
|||
{
|
||||
name: 'fails when URL is not a Torq webhook endpoint',
|
||||
url: 'http://mylisteningserver:9200/endpoint',
|
||||
errorMsg: `"error validating action type config: error configuring send to Torq action: url must begin with https://hooks.torq.io"`,
|
||||
errorMsg: `"error validating action type config: error configuring send to Torq action: url must begin with https://hooks.torq.io or https://hooks.eu.torq.io"`,
|
||||
},
|
||||
{
|
||||
name: 'fails when URL is an unsupported Torq webhook subdomain',
|
||||
url: 'https://hooks.anothersubdomain.torq.io/v1/test',
|
||||
errorMsg: `"error validating action type config: error configuring send to Torq action: url must begin with https://hooks.torq.io or https://hooks.eu.torq.io"`,
|
||||
},
|
||||
];
|
||||
errorCases.forEach(({ name, url, errorMsg }) => {
|
||||
|
|
|
@ -21,6 +21,7 @@ import {
|
|||
import { renderMustacheObject } from '@kbn/actions-plugin/server/lib/mustache_renderer';
|
||||
import { request } from '@kbn/actions-plugin/server/lib/axios_utils';
|
||||
import { ActionTypeExecutorResult, ValidatorServices } from '@kbn/actions-plugin/server/types';
|
||||
import { isValidTorqHostName } from '../../../common/torq';
|
||||
import { getRetryAfterIntervalFromHeaders } from '../lib/http_response_retry_header';
|
||||
import { promiseResult, isOk, Result } from '../lib/result_type';
|
||||
|
||||
|
@ -127,11 +128,11 @@ function validateActionTypeConfig(
|
|||
);
|
||||
}
|
||||
|
||||
if (configureUrlObj.hostname !== 'hooks.torq.io' && configureUrlObj.hostname !== 'localhost') {
|
||||
if (!isValidTorqHostName(configureUrlObj.hostname) && configureUrlObj.hostname !== 'localhost') {
|
||||
throw new Error(
|
||||
i18n.translate('xpack.stackConnectors.torq.torqConfigurationErrorInvalidHostname', {
|
||||
defaultMessage:
|
||||
'error configuring send to Torq action: url must begin with https://hooks.torq.io',
|
||||
'error configuring send to Torq action: url must begin with https://hooks.torq.io or https://hooks.eu.torq.io',
|
||||
})
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue