Skip to content

Commit

Permalink
[SIEM] Adds rule override Cypress tests (elastic#74367) (elastic#74535)
Browse files Browse the repository at this point in the history
* implements rule override test

* refactors the code

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
  • Loading branch information
MadameSheema and elasticmachine authored Aug 10, 2020
1 parent 2ddaff0 commit 9ac2084
Show file tree
Hide file tree
Showing 8 changed files with 364 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import { newOverrideRule } from '../objects/rule';

import {
CUSTOM_RULES_BTN,
RISK_SCORE,
RULE_NAME,
RULES_ROW,
RULES_TABLE,
SEVERITY,
} from '../screens/alerts_detection_rules';
import {
ABOUT_INVESTIGATION_NOTES,
ABOUT_OVERRIDE_FALSE_POSITIVES,
ABOUT_OVERRIDE_MITRE,
ABOUT_OVERRIDE_NAME_OVERRIDE,
ABOUT_OVERRIDE_RISK,
ABOUT_OVERRIDE_RISK_OVERRIDE,
ABOUT_OVERRIDE_SEVERITY_OVERRIDE,
ABOUT_OVERRIDE_TAGS,
ABOUT_OVERRIDE_TIMESTAMP_OVERRIDE,
ABOUT_OVERRIDE_URLS,
ABOUT_RULE_DESCRIPTION,
ABOUT_SEVERITY,
ABOUT_STEP,
DEFINITION_CUSTOM_QUERY,
DEFINITION_INDEX_PATTERNS,
DEFINITION_TIMELINE,
DEFINITION_STEP,
INVESTIGATION_NOTES_MARKDOWN,
INVESTIGATION_NOTES_TOGGLE,
RULE_ABOUT_DETAILS_HEADER_TOGGLE,
RULE_NAME_HEADER,
SCHEDULE_LOOPBACK,
SCHEDULE_RUNS,
SCHEDULE_STEP,
} from '../screens/rule_details';

import {
goToManageAlertsDetectionRules,
waitForAlertsIndexToBeCreated,
waitForAlertsPanelToBeLoaded,
} from '../tasks/alerts';
import {
changeToThreeHundredRowsPerPage,
filterByCustomRules,
goToCreateNewRule,
goToRuleDetails,
waitForLoadElasticPrebuiltDetectionRulesTableToBeLoaded,
waitForRulesToBeLoaded,
} from '../tasks/alerts_detection_rules';
import {
createAndActivateRule,
fillAboutRuleWithOverrideAndContinue,
fillDefineCustomRuleWithImportedQueryAndContinue,
} from '../tasks/create_new_rule';
import { esArchiverLoad, esArchiverUnload } from '../tasks/es_archiver';
import { loginAndWaitForPageWithoutDateRange } from '../tasks/login';

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

describe('Detection rules, override', () => {
before(() => {
esArchiverLoad('timeline');
});

after(() => {
esArchiverUnload('timeline');
});

it('Creates and activates a new custom rule with override option', () => {
loginAndWaitForPageWithoutDateRange(DETECTIONS_URL);
waitForAlertsPanelToBeLoaded();
waitForAlertsIndexToBeCreated();
goToManageAlertsDetectionRules();
waitForLoadElasticPrebuiltDetectionRulesTableToBeLoaded();
goToCreateNewRule();
fillDefineCustomRuleWithImportedQueryAndContinue(newOverrideRule);
fillAboutRuleWithOverrideAndContinue(newOverrideRule);
createAndActivateRule();

cy.get(CUSTOM_RULES_BTN).invoke('text').should('eql', 'Custom rules (1)');

changeToThreeHundredRowsPerPage();
waitForRulesToBeLoaded();

const expectedNumberOfRules = 1;
cy.get(RULES_TABLE).then(($table) => {
cy.wrap($table.find(RULES_ROW).length).should('eql', expectedNumberOfRules);
});

filterByCustomRules();

cy.get(RULES_TABLE).then(($table) => {
cy.wrap($table.find(RULES_ROW).length).should('eql', 1);
});
cy.get(RULE_NAME).invoke('text').should('eql', newOverrideRule.name);
cy.get(RISK_SCORE).invoke('text').should('eql', newOverrideRule.riskScore);
cy.get(SEVERITY).invoke('text').should('eql', newOverrideRule.severity);
cy.get('[data-test-subj="rule-switch"]').should('have.attr', 'aria-checked', 'true');

goToRuleDetails();

let expectedUrls = '';
newOverrideRule.referenceUrls.forEach((url) => {
expectedUrls = expectedUrls + url;
});
let expectedFalsePositives = '';
newOverrideRule.falsePositivesExamples.forEach((falsePositive) => {
expectedFalsePositives = expectedFalsePositives + falsePositive;
});
let expectedTags = '';
newOverrideRule.tags.forEach((tag) => {
expectedTags = expectedTags + tag;
});
let expectedMitre = '';
newOverrideRule.mitre.forEach((mitre) => {
expectedMitre = expectedMitre + mitre.tactic;
mitre.techniques.forEach((technique) => {
expectedMitre = expectedMitre + technique;
});
});
const expectedIndexPatterns = [
'apm-*-transaction*',
'auditbeat-*',
'endgame-*',
'filebeat-*',
'logs-*',
'packetbeat-*',
'winlogbeat-*',
];

cy.get(RULE_NAME_HEADER).invoke('text').should('eql', `${newOverrideRule.name} Beta`);

cy.get(ABOUT_RULE_DESCRIPTION).invoke('text').should('eql', newOverrideRule.description);

const expectedOverrideSeverities = ['Low', 'Medium', 'High', 'Critical'];

cy.get(ABOUT_STEP).eq(ABOUT_SEVERITY).invoke('text').should('eql', newOverrideRule.severity);
newOverrideRule.severityOverride.forEach((severity, i) => {
cy.get(ABOUT_STEP)
.eq(ABOUT_OVERRIDE_SEVERITY_OVERRIDE + i)
.invoke('text')
.should(
'eql',
`${severity.sourceField}:${severity.sourceValue}${expectedOverrideSeverities[i]}`
);
});

cy.get(ABOUT_STEP)
.eq(ABOUT_OVERRIDE_RISK)
.invoke('text')
.should('eql', newOverrideRule.riskScore);
cy.get(ABOUT_STEP)
.eq(ABOUT_OVERRIDE_RISK_OVERRIDE)
.invoke('text')
.should('eql', `${newOverrideRule.riskOverride}signal.rule.risk_score`);
cy.get(ABOUT_STEP).eq(ABOUT_OVERRIDE_URLS).invoke('text').should('eql', expectedUrls);
cy.get(ABOUT_STEP)
.eq(ABOUT_OVERRIDE_FALSE_POSITIVES)
.invoke('text')
.should('eql', expectedFalsePositives);
cy.get(ABOUT_STEP)
.eq(ABOUT_OVERRIDE_NAME_OVERRIDE)
.invoke('text')
.should('eql', newOverrideRule.nameOverride);
cy.get(ABOUT_STEP).eq(ABOUT_OVERRIDE_MITRE).invoke('text').should('eql', expectedMitre);
cy.get(ABOUT_STEP)
.eq(ABOUT_OVERRIDE_TIMESTAMP_OVERRIDE)
.invoke('text')
.should('eql', newOverrideRule.timestampOverride);
cy.get(ABOUT_STEP).eq(ABOUT_OVERRIDE_TAGS).invoke('text').should('eql', expectedTags);

cy.get(RULE_ABOUT_DETAILS_HEADER_TOGGLE).eq(INVESTIGATION_NOTES_TOGGLE).click({ force: true });
cy.get(ABOUT_INVESTIGATION_NOTES).invoke('text').should('eql', INVESTIGATION_NOTES_MARKDOWN);

cy.get(DEFINITION_INDEX_PATTERNS).then((patterns) => {
cy.wrap(patterns).each((pattern, index) => {
cy.wrap(pattern).invoke('text').should('eql', expectedIndexPatterns[index]);
});
});
cy.get(DEFINITION_STEP)
.eq(DEFINITION_CUSTOM_QUERY)
.invoke('text')
.should('eql', `${newOverrideRule.customQuery} `);
cy.get(DEFINITION_STEP).eq(DEFINITION_TIMELINE).invoke('text').should('eql', 'None');

cy.get(SCHEDULE_STEP).eq(SCHEDULE_RUNS).invoke('text').should('eql', '5m');
cy.get(SCHEDULE_STEP).eq(SCHEDULE_LOOPBACK).invoke('text').should('eql', '1m');
});
});
50 changes: 50 additions & 0 deletions x-pack/plugins/security_solution/cypress/objects/rule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ interface Mitre {
techniques: string[];
}

interface SeverityOverride {
sourceField: string;
sourceValue: string;
}

export interface CustomRule {
customQuery: string;
name: string;
Expand All @@ -36,6 +41,13 @@ export interface ThresholdRule extends CustomRule {
threshold: string;
}

export interface OverrideRule extends CustomRule {
severityOverride: SeverityOverride[];
riskOverride: string;
nameOverride: string;
timestampOverride: string;
}

export interface MachineLearningRule {
machineLearningJob: string;
anomalyScoreThreshold: string;
Expand All @@ -61,6 +73,26 @@ const mitre2: Mitre = {
techniques: ['CMSTP (T1191)'],
};

const severityOverride1: SeverityOverride = {
sourceField: 'host.name',
sourceValue: 'host',
};

const severityOverride2: SeverityOverride = {
sourceField: 'agent.type',
sourceValue: 'endpoint',
};

const severityOverride3: SeverityOverride = {
sourceField: 'host.geo.name',
sourceValue: 'atack',
};

const severityOverride4: SeverityOverride = {
sourceField: '@timestamp',
sourceValue: '10/02/2020',
};

export const newRule: CustomRule = {
customQuery: 'host.name: *',
name: 'New Rule Test',
Expand All @@ -75,6 +107,24 @@ export const newRule: CustomRule = {
timelineId: '352c6110-9ffb-11ea-b3d8-857d6042d9bd',
};

export const newOverrideRule: OverrideRule = {
customQuery: 'host.name:*',
name: 'New Rule Test',
description: 'The new rule description.',
severity: 'High',
riskScore: '17',
tags: ['test', 'newRule'],
referenceUrls: ['https://www.google.com/', 'https://elastic.co/'],
falsePositivesExamples: ['False1', 'False2'],
mitre: [mitre1, mitre2],
note: '# test markdown',
timelineId: '0162c130-78be-11ea-9718-118a926974a4',
severityOverride: [severityOverride1, severityOverride2, severityOverride3, severityOverride4],
riskOverride: 'destination.port',
nameOverride: 'agent.type',
timestampOverride: '@timestamp',
};

export const newThresholdRule: ThresholdRule = {
customQuery: 'host.name:*',
name: 'New Rule Test',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ export const MITRE_BTN = '[data-test-subj="addMitre"]';

export const ADVANCED_SETTINGS_BTN = '[data-test-subj="advancedSettings"] .euiAccordion__button';

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

export const CREATE_AND_ACTIVATE_BTN = '[data-test-subj="create-activate"]';

export const CUSTOM_QUERY_INPUT = '[data-test-subj="queryInput"]';
Expand Down Expand Up @@ -53,17 +55,31 @@ export const REFERENCE_URLS_INPUT =

export const RISK_INPUT = '.euiRangeInput';

export const RISK_MAPPING_OVERRIDE_OPTION = '#risk_score-mapping-override';

export const RISK_OVERRIDE =
'[data-test-subj="detectionEngineStepAboutRuleRiskScore-riskOverride"]';

export const RULE_DESCRIPTION_INPUT =
'[data-test-subj="detectionEngineStepAboutRuleDescription"] [data-test-subj="input"]';

export const RULE_NAME_INPUT =
'[data-test-subj="detectionEngineStepAboutRuleName"] [data-test-subj="input"]';

export const RULE_NAME_OVERRIDE = '[data-test-subj="detectionEngineStepAboutRuleRuleNameOverride"]';

export const RULE_TIMESTAMP_OVERRIDE =
'[data-test-subj="detectionEngineStepAboutRuleTimestampOverride"]';

export const SCHEDULE_CONTINUE_BUTTON = '[data-test-subj="schedule-continue"]';

export const SEVERITY_DROPDOWN =
'[data-test-subj="detectionEngineStepAboutRuleSeverity"] [data-test-subj="select"]';

export const SEVERITY_MAPPING_OVERRIDE_OPTION = '#severity-mapping-override';

export const SEVERITY_OVERRIDE_ROW = '[data-test-subj="severityOverrideRow"]';

export const TAGS_INPUT =
'[data-test-subj="detectionEngineStepAboutRuleTags"] [data-test-subj="comboBoxSearchInput"]';

Expand Down
18 changes: 18 additions & 0 deletions x-pack/plugins/security_solution/cypress/screens/rule_details.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,24 @@ export const ABOUT_INVESTIGATION_NOTES = '[data-test-subj="stepAboutDetailsNoteC

export const ABOUT_MITRE = 4;

export const ABOUT_OVERRIDE_FALSE_POSITIVES = 8;

export const ABOUT_OVERRIDE_MITRE = 10;

export const ABOUT_OVERRIDE_NAME_OVERRIDE = 9;

export const ABOUT_OVERRIDE_RISK = 5;

export const ABOUT_OVERRIDE_RISK_OVERRIDE = 6;

export const ABOUT_OVERRIDE_SEVERITY_OVERRIDE = 1;

export const ABOUT_OVERRIDE_TAGS = 12;

export const ABOUT_OVERRIDE_TIMESTAMP_OVERRIDE = 11;

export const ABOUT_OVERRIDE_URLS = 7;

export const ABOUT_RULE_DESCRIPTION = '[data-test-subj=stepAboutRuleDetailsToggleDescriptionText]';

export const ABOUT_RISK = 1;
Expand Down
Loading

0 comments on commit 9ac2084

Please sign in to comment.