Skip to content

Commit

Permalink
[Security Solution][Detections] increases coverage of bulk edit rules…
Browse files Browse the repository at this point in the history
… action according to test plan (#141929) (#142978)

## Summary

- adds missing tests according to [test plan](https://docs.google.com/document/d/116x7ITTTJQ6cTiwaGK831_f6Ox7XB3qyLiHxC3Cmf8w/edit#heading=h.tzaw2977z8ue) (internal document)
- small refactoring of cypress tasks related to rule actions: create Email connector moved to common tasks from create_rule screen, as it used in bulk editing as well

(cherry picked from commit d07301f)

Co-authored-by: Vitalii Dmyterko <[email protected]>
  • Loading branch information
kibanamachine and vitaliidm authored Oct 10, 2022
1 parent 2ed5776 commit da2bd15
Show file tree
Hide file tree
Showing 19 changed files with 672 additions and 196 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
/*
* 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.
*/

import { ROLES } from '../../../common/test';

import {
RULES_BULK_EDIT_ACTIONS_INFO,
RULES_BULK_EDIT_ACTIONS_WARNING,
ADD_RULE_ACTIONS_MENU_ITEM,
} from '../../screens/rules_bulk_edit';
import { actionFormSelector } from '../../screens/common/rule_actions';

import { cleanKibana, deleteAlertsAndRules, deleteConnectors } from '../../tasks/common';
import {
addSlackRuleAction,
assertSlackRuleAction,
addEmailConnectorAndRuleAction,
assertEmailRuleAction,
} from '../../tasks/common/rule_actions';
import {
waitForRulesTableToBeLoaded,
selectNumberOfRules,
loadPrebuiltDetectionRulesFromHeaderBtn,
goToEditRuleActionsSettingsOf,
} from '../../tasks/alerts_detection_rules';
import {
waitForBulkEditActionToFinish,
submitBulkEditForm,
checkOverwriteRuleActionsCheckbox,
openBulkEditRuleActionsForm,
pickActionFrequency,
openBulkActionsMenu,
} from '../../tasks/rules_bulk_edit';
import { assertSelectedActionFrequency } from '../../tasks/edit_rule';
import { login, visitWithoutDateRange } from '../../tasks/login';
import { esArchiverResetKibana } from '../../tasks/es_archiver';

import { SECURITY_DETECTIONS_RULES_URL } from '../../urls/navigation';

import {
createMachineLearningRule,
createCustomIndicatorRule,
createEventCorrelationRule,
createThresholdRule,
createNewTermsRule,
createSavedQueryRule,
createCustomRuleEnabled,
} from '../../tasks/api_calls/rules';
import { createSlackConnector } from '../../tasks/api_calls/connectors';

import {
getEqlRule,
getNewThreatIndicatorRule,
getNewRule,
getNewThresholdRule,
getMachineLearningRule,
getNewTermsRule,
} from '../../objects/rule';

const ruleNameToAssert = 'Custom rule name with actions';
const expectedNumberOfCustomRulesToBeEdited = 7;
// 7 custom rules of different types + 3 prebuilt.
// number of selected rules doesn't matter, we only want to make sure they will be edited an no modal window displayed as for other actions
const expectedNumberOfRulesToBeEdited = expectedNumberOfCustomRulesToBeEdited + 3;

const expectedExistingSlackMessage = 'Existing slack action';
const expectedSlackMessage = 'Slack action test message';

describe('Detection rules, bulk edit of rule actions', () => {
before(() => {
cleanKibana();
login();
});

beforeEach(() => {
deleteAlertsAndRules();
deleteConnectors();
esArchiverResetKibana();

createSlackConnector().then(({ body }) => {
const actions = [
{
id: body.id,
action_type_id: '.slack',
group: 'default',
params: {
message: expectedExistingSlackMessage,
},
},
];

createCustomRuleEnabled(
{
...getNewRule(),
name: ruleNameToAssert,
},
'1',
'100m',
500,
actions
);
});

createEventCorrelationRule(getEqlRule(), '2');
createMachineLearningRule(getMachineLearningRule(), '3');
createCustomIndicatorRule(getNewThreatIndicatorRule(), '4');
createThresholdRule(getNewThresholdRule(), '5');
createNewTermsRule(getNewTermsRule(), '6');
createSavedQueryRule({ ...getNewRule(), savedId: 'mocked' }, '7');

createSlackConnector();
});

context('Restricted action privileges', () => {
it("User with no privileges can't add rule actions", () => {
login(ROLES.hunter_no_actions);
visitWithoutDateRange(SECURITY_DETECTIONS_RULES_URL, ROLES.hunter_no_actions);
waitForRulesTableToBeLoaded();

selectNumberOfRules(expectedNumberOfCustomRulesToBeEdited);

openBulkActionsMenu();

cy.get(ADD_RULE_ACTIONS_MENU_ITEM).should('be.disabled');
});
});

context('All actions privileges', () => {
beforeEach(() => {
visitWithoutDateRange(SECURITY_DETECTIONS_RULES_URL);
waitForRulesTableToBeLoaded();
});

it('Add a rule action to rules (existing connector)', () => {
const expectedActionFrequency = 'Daily';

loadPrebuiltDetectionRulesFromHeaderBtn();

// select both custom and prebuilt rules
selectNumberOfRules(expectedNumberOfRulesToBeEdited);
openBulkEditRuleActionsForm();

// ensure rule actions info callout displayed on the form
cy.get(RULES_BULK_EDIT_ACTIONS_INFO).should('be.visible');

pickActionFrequency(expectedActionFrequency);
addSlackRuleAction(expectedSlackMessage);

submitBulkEditForm();
waitForBulkEditActionToFinish({ rulesCount: expectedNumberOfRulesToBeEdited });

// check if rule has been updated
goToEditRuleActionsSettingsOf(ruleNameToAssert);

assertSelectedActionFrequency(expectedActionFrequency);
assertSlackRuleAction(expectedExistingSlackMessage, 0);
assertSlackRuleAction(expectedSlackMessage, 1);
// ensure there is no third action
cy.get(actionFormSelector(2)).should('not.exist');
});

it('Overwrite rule actions in rules', () => {
const expectedActionFrequency = 'On each rule execution';

loadPrebuiltDetectionRulesFromHeaderBtn();

// select both custom and prebuilt rules
selectNumberOfRules(expectedNumberOfRulesToBeEdited);
openBulkEditRuleActionsForm();

pickActionFrequency(expectedActionFrequency);
addSlackRuleAction(expectedSlackMessage);

// check overwrite box, ensure warning is displayed
checkOverwriteRuleActionsCheckbox();
cy.get(RULES_BULK_EDIT_ACTIONS_WARNING).contains(
`You're about to overwrite rule actions for ${expectedNumberOfRulesToBeEdited} selected rules`
);

submitBulkEditForm();
waitForBulkEditActionToFinish({ rulesCount: expectedNumberOfRulesToBeEdited });

// check if rule has been updated
goToEditRuleActionsSettingsOf(ruleNameToAssert);

assertSelectedActionFrequency(expectedActionFrequency);
assertSlackRuleAction(expectedSlackMessage);
// ensure existing action was overwritten
cy.get(actionFormSelector(1)).should('not.exist');
});

it('Add a rule action to rules (new connector)', () => {
const expectedActionFrequency = 'Hourly';
const expectedEmail = '[email protected]';
const expectedSubject = 'Subject';

selectNumberOfRules(expectedNumberOfCustomRulesToBeEdited);
openBulkEditRuleActionsForm();

pickActionFrequency(expectedActionFrequency);
addEmailConnectorAndRuleAction(expectedEmail, expectedSubject);

submitBulkEditForm();
waitForBulkEditActionToFinish({ rulesCount: expectedNumberOfCustomRulesToBeEdited });

// check if rule has been updated
goToEditRuleActionsSettingsOf(ruleNameToAssert);

assertSelectedActionFrequency(expectedActionFrequency);
assertEmailRuleAction(expectedEmail, expectedSubject);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,10 @@ import {
RULE_NAME_INPUT,
SCHEDULE_INTERVAL_AMOUNT_INPUT,
SCHEDULE_INTERVAL_UNITS_INPUT,
SCHEDULE_CONTINUE_BUTTON,
SEVERITY_DROPDOWN,
TAGS_CLEAR_BUTTON,
TAGS_FIELD,
EMAIL_ACTION_BTN,
CREATE_ACTION_CONNECTOR_BTN,
SAVE_ACTION_CONNECTOR_BTN,
FROM_VALIDATION_ERROR,
EMAIL_ACTION_TO_INPUT,
EMAIL_ACTION_SUBJECT_INPUT,
SCHEDULE_CONTINUE_BUTTON,
} from '../../screens/create_new_rule';
import {
ADDITIONAL_LOOK_BACK_DETAILS,
Expand Down Expand Up @@ -86,12 +80,12 @@ import {
import { createCustomRuleEnabled } from '../../tasks/api_calls/rules';
import { createTimeline } from '../../tasks/api_calls/timelines';
import { cleanKibana, deleteAlertsAndRules } from '../../tasks/common';
import { addEmailConnectorAndRuleAction } from '../../tasks/common/rule_actions';
import {
createAndEnableRule,
fillAboutRule,
fillAboutRuleAndContinue,
fillDefineCustomRuleAndContinue,
fillEmailConnectorForm,
fillScheduleRuleAndContinue,
goToAboutStepTab,
goToActionsStepTab,
Expand Down Expand Up @@ -377,15 +371,8 @@ describe('Custom query rules', () => {
cy.get(ACTIONS_THROTTLE_INPUT).invoke('val').should('eql', 'no_actions');

cy.get(ACTIONS_THROTTLE_INPUT).select('Weekly');
cy.get(EMAIL_ACTION_BTN).click();
cy.get(CREATE_ACTION_CONNECTOR_BTN).click();
fillEmailConnectorForm();
cy.get(SAVE_ACTION_CONNECTOR_BTN).click();

cy.get(EMAIL_ACTION_TO_INPUT).type('[email protected]');
cy.get(EMAIL_ACTION_SUBJECT_INPUT).type('Subject');

cy.get(FROM_VALIDATION_ERROR).should('not.exist');
addEmailConnectorAndRuleAction('[email protected]', 'Subject');

goToAboutStepTab();
cy.get(TAGS_CLEAR_BUTTON).click({ force: true });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,7 @@ export const TIMELINE_SEARCHBOX = '[data-test-subj="timeline-super-select-search
export const EUI_FILTER_SELECT_ITEM = '.euiFilterSelectItem';

export const EUI_CHECKBOX = '.euiCheckbox__input';

export const COMBO_BOX_INPUT = '[data-test-subj="comboBoxInput"]';

export const COMBO_BOX_SELECTION = '.euiMark';
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* 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.
*/

export const EMAIL_ACTION_BTN = '[data-test-subj=".email-siem-ActionTypeSelectOption"]';

export const CREATE_ACTION_CONNECTOR_BTN = '[data-test-subj="createActionConnectorButton-0"]';

export const SAVE_ACTION_CONNECTOR_BTN = '[data-test-subj="saveActionButtonModal"]';

export const EMAIL_ACTION_TO_INPUT = '[data-test-subj="toEmailAddressInput"]';

export const EMAIL_ACTION_SUBJECT_INPUT = '[data-test-subj="subjectInput"]';

export const SLACK_ACTION_BTN = '[data-test-subj=".slack-siem-ActionTypeSelectOption"]';

export const SLACK_ACTION_MESSAGE_TEXTAREA = '[data-test-subj="messageTextArea"]';

export const CONNECTOR_NAME_INPUT = '[data-test-subj="nameInput"]';

export const EMAIL_CONNECTOR_FROM_INPUT = '[data-test-subj="emailFromInput"]';

export const EMAIL_CONNECTOR_HOST_INPUT = '[data-test-subj="emailHostInput"]';

export const EMAIL_CONNECTOR_PORT_INPUT = '[data-test-subj="emailPortInput"]';

export const EMAIL_CONNECTOR_USER_INPUT = '[data-test-subj="emailUserInput"]';

export const EMAIL_CONNECTOR_PASSWORD_INPUT = '[data-test-subj="emailPasswordInput"]';

export const EMAIL_CONNECTOR_SERVICE_SELECTOR = '[data-test-subj="emailServiceSelectInput"]';

export const FORM_VALIDATION_ERROR = '.euiFormErrorText';

export const JSON_EDITOR = "[data-test-subj='actionJsonEditor']";

export const INDEX_SELECTOR = "[data-test-subj='.index-siem-ActionTypeSelectOption']";

export const actionFormSelector = (position: number) =>
`[data-test-subj="alertActionAccordion-${position}"]`;
Original file line number Diff line number Diff line change
Expand Up @@ -16,34 +16,6 @@ export const ACTIONS_EDIT_TAB = '[data-test-subj="edit-rule-actions-tab"]';
export const ACTIONS_THROTTLE_INPUT =
'[data-test-subj="stepRuleActions"] [data-test-subj="select"]';

export const EMAIL_ACTION_BTN = '[data-test-subj=".email-siem-ActionTypeSelectOption"]';

export const CREATE_ACTION_CONNECTOR_BTN = '[data-test-subj="createActionConnectorButton-0"]';

export const SAVE_ACTION_CONNECTOR_BTN = '[data-test-subj="saveActionButtonModal"]';

export const EMAIL_ACTION_TO_INPUT = '[data-test-subj="toEmailAddressInput"]';

export const EMAIL_ACTION_SUBJECT_INPUT = '[data-test-subj="subjectInput"]';

export const FROM_VALIDATION_ERROR = '.euiFormErrorText';

export const CONNECTOR_NAME_INPUT = '[data-test-subj="nameInput"]';

export const EMAIL_CONNECTOR_FROM_INPUT = '[data-test-subj="emailFromInput"]';

export const EMAIL_CONNECTOR_HOST_INPUT = '[data-test-subj="emailHostInput"]';

export const EMAIL_CONNECTOR_PORT_INPUT = '[data-test-subj="emailPortInput"]';

export const EMAIL_CONNECTOR_USER_INPUT = '[data-test-subj="emailUserInput"]';

export const EMAIL_CONNECTOR_PASSWORD_INPUT = '[data-test-subj="emailPasswordInput"]';

export const EMAIL_CONNECTOR_SERVICE_SELECTOR = '[data-test-subj="emailServiceSelectInput"]';

export const JSON_EDITOR = "[data-test-subj='actionJsonEditor']";

export const ADD_FALSE_POSITIVE_BTN =
'[data-test-subj="detectionEngineStepAboutRuleFalsePositives"] .euiButtonEmpty__text';

Expand All @@ -58,10 +30,6 @@ export const BACK_TO_ALL_RULES_LINK = '[data-test-subj="ruleDetailsBackToAllRule

export const COMBO_BOX_CLEAR_BTN = '[data-test-subj="comboBoxClearButton"]';

export const COMBO_BOX_INPUT = '[data-test-subj="comboBoxInput"]';

export const COMBO_BOX_SELECTION = '.euiMark';

export const CREATE_AND_ENABLE_BTN = '[data-test-subj="create-enable"]';

export const CUSTOM_QUERY_INPUT = '[data-test-subj="queryInput"]';
Expand Down Expand Up @@ -260,7 +228,3 @@ export const savedQueryByName = (savedQueryName: string) =>

export const APPLY_SELECTED_SAVED_QUERY_BUTTON =
'[data-test-subj="saved-query-management-apply-changes-button"]';

export const INDEX_SELECTOR = "[data-test-subj='.index-siem-ActionTypeSelectOption']";

export const CREATE_CONNECTOR_BTN = "[data-test-subj='createActionConnectorButton-0']";
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,5 @@ export const BACK_TO_RULES = '[data-test-subj="ruleDetailsBackToAllRules"]';

export const DEFINE_RULE_PANEL_PROGRESS =
'[data-test-subj="defineRule"] [data-test-subj="stepPanelProgress"]';

export const EDIT_RULE_SETTINGS_LINK = '[data-test-subj="editRuleSettingsLink"]';
Loading

0 comments on commit da2bd15

Please sign in to comment.