Skip to content

Commit

Permalink
Backport/backport 494 to 2.x fix conflicts (#517)
Browse files Browse the repository at this point in the history
* Refactor and move field mapping to first the page of create detector feature (#501) (#506)

* [FEATURE] Create detector \ Refactor and move field mapping to first the page of create detector feature #495

Signed-off-by: Jovan Cvetkovic <jovanca.cvetkovic@gmail.com>

* [FEATURE] Create detector \ Refactor and move field mapping to first the page of create detector feature #495

Signed-off-by: Jovan Cvetkovic <jovanca.cvetkovic@gmail.com>

* [FEATURE] Create detector \ Refactor and move field mapping to first the page of create detector feature #495

Signed-off-by: Jovan Cvetkovic <jovanca.cvetkovic@gmail.com>

* [FEATURE] Create detector \ Refactor and move field mapping to first the page of create detector feature #495

Signed-off-by: Jovan Cvetkovic <jovanca.cvetkovic@gmail.com>

* [FEATURE] Create detector \ Refactor and move field mapping to first the page of create detector feature #495

Signed-off-by: Jovan Cvetkovic <jovanca.cvetkovic@gmail.com>

* [FEATURE] Create detector \ Refactor and move field mapping to first the page of create detector feature #495

Signed-off-by: Jovan Cvetkovic <jovanca.cvetkovic@gmail.com>

* [FEATURE] Create detector \ Refactor and move field mapping to first the page of create detector feature #495

Signed-off-by: Jovan Cvetkovic <jovanca.cvetkovic@gmail.com>

---------

Signed-off-by: Jovan Cvetkovic <jovanca.cvetkovic@gmail.com>
(cherry picked from commit 5425b9b)

Co-authored-by: Jovan Cvetkovic <jovanca.cvetkovic@gmail.com>

* Bumped version to 2.7. (#508) (#510)

Signed-off-by: AWSHurneyt <hurneyt@amazon.com>
(cherry picked from commit 1f10991)

Co-authored-by: AWSHurneyt <hurneyt@amazon.com>

* Create global state object for async requests (#493) (#513)

* [FEATURE] Create global state object for async requests #491

Signed-off-by: Jovan Cvetkovic <jovanca.cvetkovic@gmail.com>

* [FEATURE] Create global state object for async requests #491

Signed-off-by: Jovan Cvetkovic <jovanca.cvetkovic@gmail.com>

* [FEATURE] Create global state object for async requests #491

Signed-off-by: Jovan Cvetkovic <jovanca.cvetkovic@gmail.com>

* [FEATURE] Create global state object for async requests #491

Signed-off-by: Jovan Cvetkovic <jovanca.cvetkovic@gmail.com>

* [FEATURE] Create global state object for async requests #491

Signed-off-by: Jovan Cvetkovic <jovanca.cvetkovic@gmail.com>

* [FEATURE] Create global state object for async requests #491

Signed-off-by: Jovan Cvetkovic <jovanca.cvetkovic@gmail.com>

* [FEATURE] Create global state object for async requests #491

Signed-off-by: Jovan Cvetkovic <jovanca.cvetkovic@gmail.com>

* [FEATURE] Create global state object for async requests #491

Signed-off-by: Jovan Cvetkovic <jovanca.cvetkovic@gmail.com>

* [FEATURE] Create global state object for async requests #491

Signed-off-by: Jovan Cvetkovic <jovanca.cvetkovic@gmail.com>

* [FEATURE] Create global state object for async requests #491

Signed-off-by: Jovan Cvetkovic <jovanca.cvetkovic@gmail.com>

* [FEATURE] Create global state object for async requests #493

Signed-off-by: Jovan Cvetkovic <jovanca.cvetkovic@gmail.com>

* [FEATURE] Create global state object for async requests #493

Signed-off-by: Jovan Cvetkovic <jovanca.cvetkovic@gmail.com>

* [FEATURE] Create global state object for async requests #493

Signed-off-by: Jovan Cvetkovic <jovanca.cvetkovic@gmail.com>

* Feature] update detector details component #504

Signed-off-by: Jovan Cvetkovic <jovanca.cvetkovic@gmail.com>

* Create global state object for async requests
#493

Signed-off-by: Jovan Cvetkovic <jovanca.cvetkovic@gmail.com>

---------

Signed-off-by: Jovan Cvetkovic <jovanca.cvetkovic@gmail.com>
(cherry picked from commit 24c8ec2)

Co-authored-by: Jovan Cvetkovic <jovanca.cvetkovic@gmail.com>

---------

Co-authored-by: opensearch-trigger-bot[bot] <98922864+opensearch-trigger-bot[bot]@users.noreply.github.com>
Co-authored-by: AWSHurneyt <hurneyt@amazon.com>
  • Loading branch information
3 people committed Apr 13, 2023
1 parent 0a6eb85 commit fb0b9f1
Show file tree
Hide file tree
Showing 40 changed files with 1,130 additions and 785 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/cypress-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ on:
branches:
- "*"
env:
OPENSEARCH_DASHBOARDS_VERSION: '2.6'
OPENSEARCH_VERSION: '2.6.0-SNAPSHOT'
SECURITY_ANALYTICS_BRANCH: '2.6'
OPENSEARCH_DASHBOARDS_VERSION: '2.x'
OPENSEARCH_VERSION: '2.7.0-SNAPSHOT'
SECURITY_ANALYTICS_BRANCH: '2.x'
jobs:
tests:
name: Run Cypress E2E tests
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/unit-tests-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ on:
branches:
- "*"
env:
OPENSEARCH_DASHBOARDS_VERSION: '2.6'
OPENSEARCH_DASHBOARDS_VERSION: '2.x'
jobs:
tests:
name: Run unit tests
Expand Down
294 changes: 144 additions & 150 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,136 +208,19 @@ describe('Detectors', () => {

cy.get('.euiCallOut')
.should('be.visible')
.contains('The selected log sources contain different types of logs');
.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 });
});
});

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

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

// 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);
});
}

// Continue to next page
cy.get('button').contains('Next').click({ force: true, timeout: 2000 });

// 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 @@ -245,11 +250,10 @@ describe('Detectors', () => {
.realType('Edited description');

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

// Change detector scheduling
cy.get(`[data-test-subj="detector-schedule-number-select"]`).ospClear().focus().realType('10');
Expand Down Expand Up @@ -283,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 @@ -307,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 @@ -333,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 @@ -354,14 +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('.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 @@ -381,16 +381,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
4 changes: 2 additions & 2 deletions opensearch_dashboards.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"id": "securityAnalyticsDashboards",
"version": "2.6.0.0",
"opensearchDashboardsVersion": "2.6.0",
"version": "2.7.0.0",
"opensearchDashboardsVersion": "2.7.0",
"configPath": ["opensearch_security_analytics"],
"requiredPlugins": ["data"],
"server": true,
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "opensearch_security_analytics_dashboards",
"version": "2.6.0.0",
"version": "2.7.0.0",
"description": "OpenSearch Dashboards plugin for Security Analytics",
"main": "index.js",
"license": "Apache-2.0",
Expand Down
Loading

0 comments on commit fb0b9f1

Please sign in to comment.