Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create global state object for async requests #493

Merged
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
1b688fe
[FEATURE] Create global state object for async requests #491
jovancvetkovic3006 Mar 24, 2023
9daf6d9
[FEATURE] Create global state object for async requests #491
jovancvetkovic3006 Mar 26, 2023
bb04a08
[FEATURE] Create global state object for async requests #491
jovancvetkovic3006 Mar 26, 2023
0d7362e
[FEATURE] Create global state object for async requests #491
jovancvetkovic3006 Mar 26, 2023
b952bb3
[FEATURE] Create global state object for async requests #491
jovancvetkovic3006 Mar 26, 2023
3d2a1f3
[FEATURE] Create global state object for async requests #491
jovancvetkovic3006 Mar 26, 2023
4e0b834
[FEATURE] Create global state object for async requests #491
jovancvetkovic3006 Mar 26, 2023
ee8afd9
[FEATURE] Create global state object for async requests #491
jovancvetkovic3006 Mar 27, 2023
dea7ddc
[FEATURE] Create global state object for async requests #491
jovancvetkovic3006 Mar 27, 2023
7649e8c
[FEATURE] Create global state object for async requests #491
jovancvetkovic3006 Mar 27, 2023
ebe7665
Merge branch 'main' of https://github.com/opensearch-project/security…
jovancvetkovic3006 Apr 5, 2023
9302003
[FEATURE] Create global state object for async requests #493
jovancvetkovic3006 Apr 6, 2023
43209b5
[FEATURE] Create global state object for async requests #493
jovancvetkovic3006 Apr 7, 2023
9612f85
[FEATURE] Create global state object for async requests #493
jovancvetkovic3006 Apr 7, 2023
5b6e227
Merge branch 'main' of https://github.com/opensearch-project/security…
jovancvetkovic3006 Apr 10, 2023
27bf2e2
Feature] update detector details component #504
jovancvetkovic3006 Apr 10, 2023
908c021
Merge branch 'main' of https://github.com/opensearch-project/security…
jovancvetkovic3006 Apr 11, 2023
ed5b213
Create global state object for async requests
jovancvetkovic3006 Apr 11, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
339 changes: 140 additions & 199 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 alerts');

// Type name of new trigger
cy.get(`input[placeholder="Enter a name for 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(dataSource);
cy.contains('Alert on 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 alerts');

// Type name of new trigger
cy.get(`input[placeholder="Enter a name for 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('Alert on 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,33 +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('.reviewFieldMappings').should('be.visible');
cy.get('.reviewFieldMappings').within(($el) => {
cy.get($el).contains('Automatically mapped fields (0)');
});

// Change input source
cy.get(`[data-test-subj="define-detector-select-data-source"]`)
.find('input')
.ospClear()
.focus()
.realType(cypressIndexDns)
.realPress('Enter');

cy.get('.reviewFieldMappings').should('be.visible');
cy.get('.reviewFieldMappings').within(($el) => {
cy.get($el).contains('Automatically mapped fields (1)');
});

// Save changes to detector details
cy.get(`[data-test-subj="save-basic-details-edits"]`).click({ force: true });
cy.get('.euiBadge__iconButton > .euiIcon').click({ force: true });
cy.get(`[data-test-subj="define-detector-select-data-source"]`).type(
`${cypressIndexWindows}{enter}`
);
});

it('...should update field mappings if rule selection is changed', () => {
Expand All @@ -393,61 +381,14 @@ 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');
cy.get('.reviewFieldMappings').should('be.visible');
cy.get('.reviewFieldMappings').within(($el) => {
cy.get($el).contains('Automatically mapped fields (0)');
});

//Suspicious DNS Query with B64 Encoded String
cy.get(`input[placeholder="Search..."]`).ospSearch(cypressDNSRule);
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.wait('@getMappingsView');
cy.get(`input[placeholder="Search..."]`).ospSearch(
'Suspicious DNS Query with B64 Encoded String'
);
cy.contains('table tr', 'Suspicious DNS Query with B64 Encoded String').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.wait('@getMappingsView');
cy.get('.reviewFieldMappings').should('be.visible');
cy.get('.reviewFieldMappings').within(($el) => {
cy.get($el).contains('Automatically mapped fields (1)');
});

cy.get(`input[placeholder="Search..."]`).ospSearch('High TXT Records Requests Rate');
cy.contains('table tr', 'High TXT Records Requests Rate').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.wait('@getMappingsView');
cy.get('.reviewFieldMappings').should('be.visible');
cy.get('.reviewFieldMappings').within(($el) => {
cy.get($el).contains('Automatically mapped fields (1)');
cy.get($el).contains('1 rule fields may need manual mapping');
});
});

it('...can be deleted', () => {
Expand Down
Loading