Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…-analytics-dashboards-plugin into Create_detector_Refactor_alert_triggers_per_mocks_#498

# Conflicts:
#	cypress/integration/1_detectors.spec.js
  • Loading branch information
jovancvetkovic3006 committed Apr 11, 2023
2 parents 7827452 + 24c8ec2 commit 899c724
Show file tree
Hide file tree
Showing 27 changed files with 1,053 additions and 832 deletions.
277 changes: 140 additions & 137 deletions cypress/integration/1_detectors.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,128 @@ const testMappings = {

const cypressDNSRule = dns_rule_data.title;

const createDetector = (detectorName, dataSource, expectFailure) => {
// Locate Create detector button click to start
cy.get('.euiButton').filter(':contains("Create detector")').click({ force: true });

// Check to ensure process started
cy.waitForPageLoad('create-detector', {
contains: 'Define detector',
});

// Enter a name for the detector in the appropriate input
cy.get(`input[placeholder="Enter a name for the detector."]`).focus().realType(detectorName);

// Select our pre-seeded data source (check cypressIndexDns)
cy.get(`[data-test-subj="define-detector-select-data-source"]`)
.find('input')
.focus()
.realType(dataSource);

cy.intercept({
pathname: '/_plugins/_security_analytics/rules/_search',
query: {
prePackaged: 'true',
},
}).as('getSigmaRules');

// Select threat detector type (Windows logs)
cy.get(`input[id="dns"]`).click({ force: true });

cy.wait('@getSigmaRules').then(() => {
// Open Detection rules accordion
cy.get('[data-test-subj="detection-rules-btn"]').click({ force: true, timeout: 5000 });

cy.contains('table tr', 'DNS', {
timeout: 120000,
});
});

// Check that correct page now showing
cy.contains('Configure field mapping');

if (!expectFailure) {
// Select appropriate names to map fields to
for (let field_name in testMappings.properties) {
const mappedTo = testMappings.properties[field_name].path;

cy.contains('tr', field_name).within(() => {
cy.get(`[data-test-subj="detector-field-mappings-select"]`).click().type(mappedTo);
});
}
}

// Click Next button to continue
cy.get('button').contains('Next').click({ force: true });

// Check that correct page now showing
cy.contains('Set up alert triggers');

// Type name of new trigger
cy.get(`input[placeholder="Enter a name to describe the alert condition"]`)
.focus()
.realType('test_trigger');

// Type in (or select) tags for the alert condition
cy.get(`[data-test-subj="alert-tags-combo-box"]`)
.find('input')
.focus()
.realType('attack.defense_evasion')
.realPress('Enter');

// Select applicable severity levels
cy.get(`[data-test-subj="security-levels-combo-box"]`).click({ force: true });
cy.contains('1 (Highest)').click({ force: true });

// Continue to next page
cy.contains('Next').click({ force: true });

// Confirm page is reached
cy.contains('Review and create');

// Confirm field mappings registered
cy.contains('Field mapping');

if (!expectFailure) {
for (let field in testMappings.properties) {
const mappedTo = testMappings.properties[field].path;

cy.contains(field);
cy.contains(mappedTo);
}
}

// Confirm entries user has made
cy.contains('Detector details');
cy.contains(detectorName);
cy.contains('dns');
cy.contains(cypressIndexDns);
cy.contains('test_trigger');

// Create the detector
cy.get('button').contains('Create').click({ force: true });
cy.waitForPageLoad('detector-details', {
contains: detectorName,
});

cy.contains('Attempting to create the detector.');

// Confirm detector active
cy.contains(detectorName);
cy.contains('Active');

if (!expectFailure) {
cy.contains('Actions');
}

cy.contains('Detector configuration');
cy.contains('Field mappings');
cy.contains('Alert triggers');
cy.contains('Detector details');
cy.contains('Created at');
cy.contains('Last updated time');
};

describe('Detectors', () => {
const cypressIndexDns = 'cypress-index-dns';
const cypressIndexWindows = 'cypress-index-windows';
Expand Down Expand Up @@ -86,130 +208,19 @@ describe('Detectors', () => {

cy.get('.euiCallOut')
.should('be.visible')
.contains('The selected log sources contain different log types');
.contains(
'To avoid issues with field mappings, we recommend creating separate detectors for different log types.'
);
});

it('...can be created', () => {
// Locate Create detector button click to start
cy.get('.euiButton').filter(':contains("Create detector")').click({ force: true });

// Check to ensure process started
cy.waitForPageLoad('create-detector', {
contains: 'Define detector',
});

// Enter a name for the detector in the appropriate input
cy.get(`input[placeholder="Enter a name for the detector."]`).focus().realType('test detector');

// Select our pre-seeded data source (check cypressIndexDns)
cy.get(`[data-test-subj="define-detector-select-data-source"]`)
.find('input')
.focus()
.realType(cypressIndexDns);

cy.intercept({
pathname: '/_plugins/_security_analytics/rules/_search',
query: {
prePackaged: 'true',
},
}).as('getSigmaRules');

// Select threat detector type (Windows logs)
cy.get(`input[id="dns"]`).click({ force: true });

cy.wait('@getSigmaRules').then(() => {
// Open Detection rules accordion
cy.get('[data-test-subj="detection-rules-btn"]').click({ force: true, timeout: 5000 });

cy.contains('table tr', 'DNS', {
timeout: 120000,
});

// find search, type USB
cy.get(`input[placeholder="Search..."]`).ospSearch(cypressDNSRule);

// Disable all rules
cy.contains('tr', cypressDNSRule, { timeout: 1000 });
cy.get('table th').within(() => {
cy.get('button').first().click({ force: true });
});

// Enable single rule
cy.contains('table tr', cypressDNSRule).within(() => {
cy.get('button').eq(1).click({ force: true, timeout: 2000 });
});
});

// Select appropriate names to map fields to
for (let field_name in testMappings.properties) {
const mappedTo = testMappings.properties[field_name].path;

cy.contains('tr', field_name).within(() => {
cy.get(`[data-test-subj="detector-field-mappings-select"]`).click().type(mappedTo);
});
}

// Click Next button to continue
cy.get('button').contains('Next').click({ force: true });

// Check that correct page now showing
cy.contains('Set up alert triggers');

// Type name of new trigger
cy.get(`input[placeholder="Enter a name to describe the alert condition"]`)
.focus()
.realType('test_trigger');

// Type in (or select) tags for the alert condition
cy.get(`[data-test-subj="alert-tags-combo-box"]`)
.find('input')
.focus()
.realType('attack.defense_evasion')
.realPress('Enter');

// Select applicable severity levels
cy.get(`[data-test-subj="security-levels-combo-box"]`).click({ force: true });
cy.contains('1 (Highest)').click({ force: true });

// Continue to next page
cy.contains('Next').click({ force: true });

// Confirm page is reached
cy.contains('Review and create');

// Confirm field mappings registered
cy.contains('Field mapping');

for (let field in testMappings.properties) {
const mappedTo = testMappings.properties[field].path;

cy.contains(field);
cy.contains(mappedTo);
}

// Confirm entries user has made
cy.contains('Detector details');
cy.contains(detectorName);
cy.contains('dns');
cy.contains(cypressIndexDns);
cy.contains('test_trigger');

// Create the detector
cy.get('button').contains('Create').click({ force: true });
cy.waitForPageLoad('detector-details', {
contains: detectorName,
});
createDetector(detectorName, cypressIndexDns, false);
cy.contains('Detector created successfully');
});

// Confirm detector active
cy.contains(detectorName);
cy.contains('Active');
cy.contains('Actions');
cy.contains('Detector configuration');
cy.contains('Field mappings');
cy.contains('Alert triggers');
cy.contains('Detector details');
cy.contains('Created at');
cy.contains('Last updated time');
it('...can fail creation', () => {
createDetector(`${detectorName}_fail`, '.kibana_1', true);
cy.contains('Create detector failed.');
});

it('...basic details can be edited', () => {
Expand Down Expand Up @@ -276,7 +287,7 @@ describe('Detectors', () => {
});

// Confirm number of rules before edit
cy.contains('Active rules (1)');
cy.contains('Active rules (13)');

// Click "Edit" button in Detector rules panel
cy.get(`[data-test-subj="edit-detector-rules"]`).click({ force: true });
Expand All @@ -300,7 +311,7 @@ describe('Detectors', () => {
cy.get(`[data-test-subj="save-detector-rules-edits"]`).click({ force: true });

// Confirm 1 rule has been removed from detector
cy.contains('Active rules (0)');
cy.contains('Active rules (12)');

// Click "Edit" button in Detector rules panel
cy.get(`[data-test-subj="edit-detector-rules"]`).click({ force: true });
Expand All @@ -326,7 +337,7 @@ describe('Detectors', () => {
});

// Confirm 1 rule has been added to detector
cy.contains('Active rules (1)');
cy.contains('Active rules (13)');
});

it('...should update field mappings if data source is changed', () => {
Expand All @@ -347,12 +358,10 @@ describe('Detectors', () => {
cy.get('.reviewFieldMappings').should('not.exist');

// Change input source
cy.get(`[data-test-subj="define-detector-select-data-source"]`)
.find('input')
.ospClear()
.focus()
.realType(cypressIndexWindows)
.realPress('Enter');
cy.get('.euiBadge__iconButton > .euiIcon').click({ force: true });
cy.get(`[data-test-subj="define-detector-select-data-source"]`).type(
`${cypressIndexWindows}{enter}`
);

cy.get('.reviewFieldMappings').should('be.visible');
});
Expand All @@ -374,16 +383,10 @@ describe('Detectors', () => {

cy.get('.reviewFieldMappings').should('not.exist');

// Search for specific rule
cy.get(`input[placeholder="Search..."]`).ospSearch(cypressDNSRule);

cy.intercept('mappings/view').as('getMappingsView');

// Toggle single search result to unchecked
cy.contains('table tr', cypressDNSRule).within(() => {
// Of note, timeout can sometimes work instead of wait here, but is very unreliable from case to case.
cy.wait(1000);
cy.get('button').eq(1).click();
cy.get('table th').within(() => {
cy.get('button').first().click({ force: true });
});

cy.wait('@getMappingsView');
Expand Down
5 changes: 5 additions & 0 deletions public/app.scss
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ $euiTextColor: $euiColorDarkestShade !default;

@import "./components/Charts/ChartContainer.scss";
@import "./pages/Overview/components/Widgets/WidgetContainer.scss";
@import "./pages/Main/components/Callout.scss";
@import "./pages/Detectors/components/ReviewFieldMappings/ReviewFieldMappings.scss";

.selected-radio-panel {
Expand Down Expand Up @@ -121,3 +122,7 @@ $euiTextColor: $euiColorDarkestShade !default;
.sa-overview-widget-empty tbody > .euiTableRow > .euiTableRowCell {
border-bottom: none;
}

.detailsFormRow {
width: auto !important;
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ exports[`<Alerts /> spec renders the component 1`] = `
Object {
"toasts": Object {
"addDanger": [MockFunction],
"addInfo": [MockFunction],
"addSuccess": [MockFunction],
"addWarning": [MockFunction],
},
}
}
Expand Down Expand Up @@ -138,6 +141,7 @@ exports[`<Alerts /> spec renders the component 1`] = `
"location": Object {
"pathname": "",
},
"push": [MockFunction],
"replace": [MockFunction],
}
}
Expand All @@ -158,6 +162,9 @@ exports[`<Alerts /> spec renders the component 1`] = `
Object {
"toasts": Object {
"addDanger": [MockFunction],
"addInfo": [MockFunction],
"addSuccess": [MockFunction],
"addWarning": [MockFunction],
},
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export default class FieldNameSelector extends Component<SIEMFieldNameProps, SIE
if (this.props.selectedField !== prevProps.selectedField) {
// if the props.selectedField is changed, update the state
this.setState({
selectedOptions: [{ label: this.props.selectedField }],
selectedOptions: this.props.selectedField ? [{ label: this.props.selectedField }] : [],
});
}
}
Expand Down
Loading

0 comments on commit 899c724

Please sign in to comment.