diff --git a/x-pack/plugins/actions/server/builtin_action_types/webhook.test.ts b/x-pack/plugins/actions/server/builtin_action_types/webhook.test.ts index 74feb8ee57d485..23ce527d4ae0d2 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/webhook.test.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/webhook.test.ts @@ -90,9 +90,8 @@ describe('config validation', () => { }; test('config validation passes when only required fields are provided', () => { - const config: Record = { + const config: Record = { url: 'http://mylisteningserver:9200/endpoint', - hasAuth: true, }; expect(validateConfig(actionType, config)).toEqual({ ...defaultValues, @@ -102,10 +101,9 @@ describe('config validation', () => { test('config validation passes when valid methods are provided', () => { ['post', 'put'].forEach((method) => { - const config: Record = { + const config: Record = { url: 'http://mylisteningserver:9200/endpoint', method, - hasAuth: true, }; expect(validateConfig(actionType, config)).toEqual({ ...defaultValues, @@ -129,9 +127,8 @@ describe('config validation', () => { }); test('config validation passes when a url is specified', () => { - const config: Record = { + const config: Record = { url: 'http://mylisteningserver:9200/endpoint', - hasAuth: true, }; expect(validateConfig(actionType, config)).toEqual({ ...defaultValues, @@ -158,7 +155,6 @@ describe('config validation', () => { headers: { 'Content-Type': 'application/json', }, - hasAuth: true, }; expect(validateConfig(actionType, config)).toEqual({ ...defaultValues, @@ -188,7 +184,6 @@ describe('config validation', () => { headers: { 'Content-Type': 'application/json', }, - hasAuth: true, }; expect(validateConfig(actionType, config)).toEqual({ @@ -268,7 +263,6 @@ describe('execute()', () => { headers: { aheader: 'a value', }, - hasAuth: true, }; await actionType.executor({ actionId: 'some-id', @@ -326,7 +320,6 @@ describe('execute()', () => { headers: { aheader: 'a value', }, - hasAuth: false, }; const secrets: ActionTypeSecretsType = { user: null, password: null }; await actionType.executor({ diff --git a/x-pack/plugins/actions/server/builtin_action_types/webhook.ts b/x-pack/plugins/actions/server/builtin_action_types/webhook.ts index dc9de86d3d951b..d0ec31721685e3 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/webhook.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/webhook.ts @@ -42,7 +42,6 @@ const configSchemaProps = { defaultValue: WebhookMethods.POST, }), headers: nullableType(HeadersSchema), - hasAuth: schema.boolean({ defaultValue: true }), }; const ConfigSchema = schema.object(configSchemaProps); export type ActionTypeConfigType = TypeOf; @@ -129,12 +128,12 @@ export async function executor( execOptions: WebhookActionTypeExecutorOptions ): Promise> { const actionId = execOptions.actionId; - const { method, url, headers = {}, hasAuth } = execOptions.config; + const { method, url, headers = {} } = execOptions.config; const { body: data } = execOptions.params; const secrets: ActionTypeSecretsType = execOptions.secrets; const basicAuth = - hasAuth && isString(secrets.user) && isString(secrets.password) + isString(secrets.user) && isString(secrets.password) ? { auth: { username: secrets.user, password: secrets.password } } : {}; diff --git a/x-pack/plugins/actions/server/saved_objects/migrations.test.ts b/x-pack/plugins/actions/server/saved_objects/migrations.test.ts index f1bd1ba2aeb609..947d84fcfc638f 100644 --- a/x-pack/plugins/actions/server/saved_objects/migrations.test.ts +++ b/x-pack/plugins/actions/server/saved_objects/migrations.test.ts @@ -58,63 +58,6 @@ describe('7.10.0', () => { }); }); -describe('7.11.0', () => { - beforeEach(() => { - jest.resetAllMocks(); - encryptedSavedObjectsSetup.createMigration.mockImplementation( - (shouldMigrateWhenPredicate, migration) => migration - ); - }); - - test('add hasAuth = true for .webhook actions with user and password', () => { - const migration711 = getMigrations(encryptedSavedObjectsSetup)['7.11.0']; - const action = getMockDataForWebhook({}, true); - expect(migration711(action, context)).toMatchObject({ - ...action, - attributes: { - ...action.attributes, - config: { - hasAuth: true, - }, - }, - }); - }); - - test('add hasAuth = false for .webhook actions without user and password', () => { - const migration711 = getMigrations(encryptedSavedObjectsSetup)['7.11.0']; - const action = getMockDataForWebhook({}, false); - expect(migration711(action, context)).toMatchObject({ - ...action, - attributes: { - ...action.attributes, - config: { - hasAuth: false, - }, - }, - }); - }); -}); - -function getMockDataForWebhook( - overwrites: Record = {}, - hasUserAndPassword: boolean -): SavedObjectUnsanitizedDoc { - const secrets = hasUserAndPassword - ? { user: 'test', password: '123' } - : { user: '', password: '' }; - return { - attributes: { - name: 'abc', - actionTypeId: '.webhook', - config: {}, - secrets, - ...overwrites, - }, - id: uuid.v4(), - type: 'action', - }; -} - function getMockDataForEmail( overwrites: Record = {} ): SavedObjectUnsanitizedDoc { diff --git a/x-pack/plugins/actions/server/saved_objects/migrations.ts b/x-pack/plugins/actions/server/saved_objects/migrations.ts index 48e572f24e6ce6..35d30accecedb5 100644 --- a/x-pack/plugins/actions/server/saved_objects/migrations.ts +++ b/x-pack/plugins/actions/server/saved_objects/migrations.ts @@ -25,18 +25,8 @@ export function getMigrations( pipeMigrations(renameCasesConfigurationObject, addHasAuthConfigurationObject) ); - const migrationWebhookConnectorHasAuth = encryptedSavedObjects.createMigration< - RawAction, - RawAction - >( - (doc): doc is SavedObjectUnsanitizedDoc => - doc.attributes.actionTypeId === '.webhook', - pipeMigrations(addHasAuthConfigurationObject) - ); - return { '7.10.0': executeMigrationWithErrorHandling(migrationActions, '7.10.0'), - '7.11.0': executeMigrationWithErrorHandling(migrationWebhookConnectorHasAuth, '7.11.0'), }; } diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 2ee357ec6bc740..d5142175befc8d 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -20244,6 +20244,7 @@ "xpack.triggersActionsUI.sections.actionsConnectorsList.unableToLoadActionTypesMessage": "アクションタイプを読み込めません", "xpack.triggersActionsUI.sections.addAction.webhookAction.error.requiredHeaderKeyText": "キーが必要です。", "xpack.triggersActionsUI.sections.addAction.webhookAction.error.requiredHeaderValueText": "値が必要です。", + "xpack.triggersActionsUI.sections.addAction.webhookAction.error.requiredHostText": "ユーザー名が必要です。", "xpack.triggersActionsUI.sections.addAction.webhookAction.error.requiredMethodText": "メソッドが必要です", "xpack.triggersActionsUI.sections.addAction.webhookAction.error.requiredPasswordText": "パスワードが必要です。", "xpack.triggersActionsUI.sections.addAlert.error.greaterThenThreshold0Text": "しきい値 1 はしきい値 0 よりも大きい値にしてください。", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index e91c95a1c9307f..f04f9e17017c11 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -20264,6 +20264,7 @@ "xpack.triggersActionsUI.sections.actionsConnectorsList.unableToLoadActionTypesMessage": "无法加载操作类型", "xpack.triggersActionsUI.sections.addAction.webhookAction.error.requiredHeaderKeyText": "“键”必填。", "xpack.triggersActionsUI.sections.addAction.webhookAction.error.requiredHeaderValueText": "“值”必填。", + "xpack.triggersActionsUI.sections.addAction.webhookAction.error.requiredHostText": "“用户名”必填。", "xpack.triggersActionsUI.sections.addAction.webhookAction.error.requiredMethodText": "“方法”必填", "xpack.triggersActionsUI.sections.addAction.webhookAction.error.requiredPasswordText": "“密码”必填。", "xpack.triggersActionsUI.sections.addAlert.error.greaterThenThreshold0Text": "阈值 1 应 > 阈值 0。", diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/types.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/types.ts index e22cd268f9bc5b..958d77a11c883f 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/types.ts @@ -110,7 +110,6 @@ export interface WebhookConfig { method: string; url: string; headers: Record; - hasAuth: boolean; } export interface WebhookSecrets { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook/webhook.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook/webhook.test.tsx index e4d9d3f009c7e0..337c1f0f18a932 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook/webhook.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook/webhook.test.tsx @@ -28,7 +28,7 @@ describe('actionTypeRegistry.get() works', () => { }); describe('webhook connector validation', () => { - test('connector validation succeeds when hasAuth is true and connector config is valid', () => { + test('connector validation succeeds when connector config is valid', () => { const actionConnector = { secrets: { user: 'user', @@ -42,35 +42,6 @@ describe('webhook connector validation', () => { method: 'PUT', url: 'http://test.com', headers: { 'content-type': 'text' }, - hasAuth: true, - }, - } as WebhookActionConnector; - - expect(actionTypeModel.validateConnector(actionConnector)).toEqual({ - errors: { - url: [], - method: [], - user: [], - password: [], - }, - }); - }); - - test('connector validation succeeds when hasAuth is false and connector config is valid', () => { - const actionConnector = { - secrets: { - user: '', - password: '', - }, - id: 'test', - actionTypeId: '.webhook', - name: 'webhook', - isPreconfigured: false, - config: { - method: 'PUT', - url: 'http://test.com', - headers: { 'content-type': 'text' }, - hasAuth: false, }, } as WebhookActionConnector; @@ -94,7 +65,6 @@ describe('webhook connector validation', () => { name: 'webhook', config: { method: 'PUT', - hasAuth: true, }, } as WebhookActionConnector; @@ -103,7 +73,7 @@ describe('webhook connector validation', () => { url: ['URL is required.'], method: [], user: [], - password: ['Password is required when username is used.'], + password: ['Password is required.'], }, }); }); @@ -120,7 +90,6 @@ describe('webhook connector validation', () => { config: { method: 'PUT', url: 'invalid.url', - hasAuth: true, }, } as WebhookActionConnector; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook/webhook.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook/webhook.tsx index db3ba9b78cee6c..04077738e6015e 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook/webhook.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook/webhook.tsx @@ -74,42 +74,22 @@ export function getActionType(): ActionTypeModel< ) ); } - if (action.config.hasAuth && !action.secrets.user && !action.secrets.password) { + if (!action.secrets.user && action.secrets.password) { errors.user.push( i18n.translate( - 'xpack.triggersActionsUI.sections.addAction.webhookAction.error.requiredAuthUserNameText', + 'xpack.triggersActionsUI.sections.addAction.webhookAction.error.requiredHostText', { defaultMessage: 'Username is required.', } ) ); } - if (action.config.hasAuth && !action.secrets.user && !action.secrets.password) { - errors.password.push( - i18n.translate( - 'xpack.triggersActionsUI.sections.addAction.webhookAction.error.requiredAuthPasswordText', - { - defaultMessage: 'Password is required.', - } - ) - ); - } - if (action.secrets.user && !action.secrets.password) { + if (!action.secrets.password && action.secrets.user) { errors.password.push( i18n.translate( 'xpack.triggersActionsUI.sections.addAction.webhookAction.error.requiredPasswordText', { - defaultMessage: 'Password is required when username is used.', - } - ) - ); - } - if (!action.secrets.user && action.secrets.password) { - errors.user.push( - i18n.translate( - 'xpack.triggersActionsUI.sections.addAction.webhookAction.error.requiredUserText', - { - defaultMessage: 'Username is required when password is used.', + defaultMessage: 'Password is required.', } ) ); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook/webhook_connectors.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook/webhook_connectors.test.tsx index 4c5e78670f0c43..45e4c566f7a27f 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook/webhook_connectors.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook/webhook_connectors.test.tsx @@ -24,7 +24,6 @@ describe('WebhookActionConnectorFields renders', () => { method: 'PUT', url: 'http:\\test', headers: { 'content-type': 'text' }, - hasAuth: true, }, } as WebhookActionConnector; const wrapper = mountWithIntl( @@ -51,9 +50,7 @@ describe('WebhookActionConnectorFields renders', () => { secrets: {}, actionTypeId: '.webhook', isPreconfigured: false, - config: { - hasAuth: true, - }, + config: {}, } as WebhookActionConnector; const wrapper = mountWithIntl( { method: 'PUT', url: 'http:\\test', headers: { 'content-type': 'text' }, - hasAuth: true, }, } as WebhookActionConnector; const wrapper = mountWithIntl( diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook/webhook_connectors.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook/webhook_connectors.tsx index 15d4c6c30450e7..e4f5ef023a5296 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook/webhook_connectors.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook/webhook_connectors.tsx @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import React, { Fragment, useEffect, useState } from 'react'; +import React, { Fragment, useState } from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; import { @@ -34,19 +34,12 @@ const WebhookActionConnectorFields: React.FunctionComponent> = ({ action, editActionConfig, editActionSecrets, errors, readOnly }) => { const { user, password } = action.secrets; - const { method, url, headers, hasAuth } = action.config; + const { method, url, headers } = action.config; const [httpHeaderKey, setHttpHeaderKey] = useState(''); const [httpHeaderValue, setHttpHeaderValue] = useState(''); const [hasHeaders, setHasHeaders] = useState(false); - useEffect(() => { - if (!action.id) { - editActionConfig('hasAuth', true); - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - if (!method) { editActionConfig('method', 'post'); // set method to POST by default } @@ -275,9 +268,9 @@ const WebhookActionConnectorFields: React.FunctionComponent + -

- - +
+ + + + {getEncryptedFieldNotifyLabel(!action.id)} + + + + + + 0 && user !== undefined} label={i18n.translate( - 'xpack.triggersActionsUI.components.builtinActionTypes.webhookAction.hasAuthSwitchLabel', + 'xpack.triggersActionsUI.components.builtinActionTypes.webhookAction.userTextFieldLabel', { - defaultMessage: 'Require authentication for this webhook', + defaultMessage: 'Username', } )} - disabled={readOnly} - checked={hasAuth} - onChange={(e) => { - editActionConfig('hasAuth', e.target.checked); - if (!e.target.checked) { - editActionSecrets('user', null); - editActionSecrets('password', null); + > + 0 && user !== undefined} + name="user" + readOnly={readOnly} + value={user || ''} + data-test-subj="webhookUserInput" + onChange={(e) => { + editActionSecrets('user', e.target.value); + }} + onBlur={() => { + if (!user) { + editActionSecrets('user', ''); + } + }} + /> + + + + 0 && password !== undefined} + label={i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.webhookAction.passwordTextFieldLabel', + { + defaultMessage: 'Password', } - }} - /> + )} + > + 0 && password !== undefined} + value={password || ''} + data-test-subj="webhookPasswordInput" + onChange={(e) => { + editActionSecrets('password', e.target.value); + }} + onBlur={() => { + if (!password) { + editActionSecrets('password', ''); + } + }} + /> + - {hasAuth ? ( - <> - {getEncryptedFieldNotifyLabel(!action.id)} - - - 0 && user !== undefined} - label={i18n.translate( - 'xpack.triggersActionsUI.components.builtinActionTypes.webhookAction.userTextFieldLabel', - { - defaultMessage: 'Username', - } - )} - > - 0 && user !== undefined} - name="user" - readOnly={readOnly} - value={user || ''} - data-test-subj="webhookUserInput" - onChange={(e) => { - editActionSecrets('user', e.target.value); - }} - onBlur={() => { - if (!user) { - editActionSecrets('user', ''); - } - }} - /> - - - - 0 && password !== undefined} - label={i18n.translate( - 'xpack.triggersActionsUI.components.builtinActionTypes.webhookAction.passwordTextFieldLabel', - { - defaultMessage: 'Password', - } - )} - > - 0 && password !== undefined} - value={password || ''} - data-test-subj="webhookPasswordInput" - onChange={(e) => { - editActionSecrets('password', e.target.value); - }} - onBlur={() => { - if (!password) { - editActionSecrets('password', ''); - } - }} - /> - - - - - ) : null} + - - - - - - + + + ); } return ( - - - - - + ); } diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/webhook.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/webhook.ts index 64d9711730c7be..ef14dd9ec2eff7 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/webhook.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/webhook.ts @@ -20,7 +20,6 @@ import { const defaultValues: Record = { headers: null, method: 'post', - hasAuth: true, }; function parsePort(url: Record): Record { diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/migrations.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/migrations.ts index d46d60905da1ce..5992bb54c81fd7 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/migrations.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/migrations.ts @@ -55,22 +55,5 @@ export default function createGetTests({ getService }: FtrProviderContext) { projectKey: 'CK', }); }); - - it('7.11.0 migrates webhook connector configurations to have `hasAuth` property', async () => { - const responseWithAuth = await supertest.get( - `${getUrlPrefix(``)}/api/actions/action/949f909b-20a0-46e3-aadb-6a4d117bb592` - ); - - expect(responseWithAuth.status).to.eql(200); - expect(responseWithAuth.body.config).key('hasAuth'); - expect(responseWithAuth.body.config.hasAuth).to.eql(true); - - const responseNoAuth = await supertest.get( - `${getUrlPrefix(``)}/api/actions/action/7434121e-045a-47d6-a0a6-0b6da752397a` - ); - expect(responseNoAuth.status).to.eql(200); - expect(responseNoAuth.body.config).key('hasAuth'); - expect(responseNoAuth.body.config.hasAuth).to.eql(false); - }); }); } diff --git a/x-pack/test/functional/es_archives/actions/data.json b/x-pack/test/functional/es_archives/actions/data.json index 18d67da1752bc8..aeeca87deb9ffd 100644 --- a/x-pack/test/functional/es_archives/actions/data.json +++ b/x-pack/test/functional/es_archives/actions/data.json @@ -56,57 +56,3 @@ "type": "_doc" } } - -{ - "type": "doc", - "value": { - "id": "action:949f909b-20a0-46e3-aadb-6a4d117bb592", - "index": ".kibana_1", - "source": { - "action": { - "actionTypeId": ".webhook", - "config": { - "headers": null, - "method": "post", - "url": "http://localhost" - }, - "name": "A webhook with auth", - "secrets": "LUqlrITACjqPmcWGlbl+H4RsGGOlw8LM0Urq8r7y6jNT7Igv3J7FjKJ2NXfNTaghVBO7e9x3wZOtiycwyoAdviTyYm1pspni24vH+OT70xaSuXcDoxfGwiLEcaG04INDnUJX4dtmRerxqR9ChktC70LNtOU3sqjYI2tWt2vOqGeq" - }, - "migrationVersion": { - "action": "7.10.0" - }, - "references": [ - ], - "type": "action", - "updated_at": "2020-10-26T21:29:47.380Z" - } - } -} - -{ - "type": "doc", - "value": { - "id": "action:7434121e-045a-47d6-a0a6-0b6da752397a", - "index": ".kibana_1", - "source": { - "action": { - "actionTypeId": ".webhook", - "config": { - "headers": null, - "method": "post", - "url": "http://localhost" - }, - "name": "A webhook with no auth", - "secrets": "tOwFq20hbUrcp3FX7stKB5aJaQQdLNQwomSNym8BgnFaBBafPOASv5T0tGdGsTr/CA7VK+N/wYBHQPzt0apF8Z/UYl63ZXqck5tSoFDnQW77zv1VVQ5wEwN1qkAQQcfrXTXU2wYVAYZNSuHkbeRjcasfG0ty1K+J7A==" - }, - "migrationVersion": { - "action": "7.10.0" - }, - "references": [ - ], - "type": "action", - "updated_at": "2020-10-26T21:30:35.146Z" - } - } -}