Skip to content

Commit

Permalink
Add missing backports 2.x (#887)
Browse files Browse the repository at this point in the history
* Make notifications optional (#796)

* Make notifications optional 2.11 (#770)

* Threat intel feed support for detector creation (#762)

* added threat intel feed support for detector creation

Signed-off-by: Amardeepsingh Siglani <amardeep7194@gmail.com>

* updated cypress workflow file

Signed-off-by: Amardeepsingh Siglani <amardeep7194@gmail.com>

* updated alerts; findings UX

Signed-off-by: Amardeepsingh Siglani <amardeep7194@gmail.com>

* refactored alert condition panel; update detector for intel feeds

Signed-off-by: Amardeepsingh Siglani <amardeep7194@gmail.com>

* updated snapshots, mocks

Signed-off-by: Amardeepsingh Siglani <amardeep7194@gmail.com>

* updated workflow

Signed-off-by: Amardeepsingh Siglani <amardeep7194@gmail.com>

* updated tests

Signed-off-by: Amardeepsingh Siglani <amardeep7194@gmail.com>

* updated snapshot

Signed-off-by: Amardeepsingh Siglani <amardeep7194@gmail.com>

* updated UI; tests

Signed-off-by: Amardeepsingh Siglani <amardeep7194@gmail.com>

---------

Signed-off-by: Amardeepsingh Siglani <amardeep7194@gmail.com>

* fixed tests; make notification optional

Signed-off-by: Amardeepsingh Siglani <amardeep7194@gmail.com>

---------

Signed-off-by: Amardeepsingh Siglani <amardeep7194@gmail.com>

* revert notification change

Signed-off-by: Amardeepsingh Siglani <amardeep7194@gmail.com>

---------

Signed-off-by: Amardeepsingh Siglani <amardeep7194@gmail.com>

* supporting array of key/value under selection (#803)

Signed-off-by: Amardeepsingh Siglani <amardeep7194@gmail.com>

* Correlation rules field matching and time window support (#804)

* added ux for group by field and time window

Signed-off-by: Amardeepsingh Siglani <amardeep7194@gmail.com>

* improved validation

Signed-off-by: Amardeepsingh Siglani <amardeep7194@gmail.com>

* check for null values

Signed-off-by: Amardeepsingh Siglani <amardeep7194@gmail.com>

* addressed PR comments

Signed-off-by: Amardeepsingh Siglani <amardeep7194@gmail.com>

---------

Signed-off-by: Amardeepsingh Siglani <amardeep7194@gmail.com>

* validate fields only when group by enabled; update default window to 5 min (#810)

Signed-off-by: Amardeepsingh Siglani <amardeep7194@gmail.com>

* do not send fields if empty (#817)

Signed-off-by: Amardeepsingh Siglani <amardeep7194@gmail.com>

* Allow empty field name for supporting timeframe and keywords when validating rule during creation/update (#823)

* allow empty field name for supporting timeframe and keywords

Signed-off-by: Amardeepsingh Siglani <amardeep7194@gmail.com>

* fixed cypress test

Signed-off-by: Amardeepsingh Siglani <amardeep7194@gmail.com>

---------

Signed-off-by: Amardeepsingh Siglani <amardeep7194@gmail.com>

* fixed update payload (#838)

Signed-off-by: Amardeepsingh Siglani <amardeep7194@gmail.com>

---------

Signed-off-by: Amardeepsingh Siglani <amardeep7194@gmail.com>
  • Loading branch information
amsiglan committed Feb 14, 2024
1 parent ffa49b2 commit 3fb9021
Show file tree
Hide file tree
Showing 12 changed files with 650 additions and 370 deletions.
291 changes: 133 additions & 158 deletions cypress/integration/1_detectors.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ const cypressIndexDns = 'cypress-index-dns';
const cypressIndexWindows = 'cypress-index-windows';
const detectorName = 'test detector';
const cypressLogTypeDns = 'dns';
const sampleNotificationChannel = 'sample_chime_channel';
const creationFailedMessage = 'Create detector failed.';

const cypressDNSRule = dns_name_rule_data.title;
Expand All @@ -43,10 +42,6 @@ const logTypeLabel = 'Log type';

const getLogTypeField = () => cy.getFieldByLabel(logTypeLabel);

const notificationLabel = 'Notification channel';

const getNotificationField = () => cy.getFieldByLabel(notificationLabel);

const openDetectorDetails = (detectorName) => {
cy.getInputByPlaceholder('Search threat detectors').type(`${detectorName}`).pressEnterKey();
cy.getElementByText('.euiTableCellContent button', detectorName).click();
Expand Down Expand Up @@ -162,8 +157,6 @@ const createDetector = (detectorName, dataSource, expectFailure) => {
.focus()
.blur();

getNotificationField().selectComboboxItem(`[Channel] ${sampleNotificationChannel}`);

cy.intercept('POST', '/_plugins/_security_analytics/mappings').as('createMappingsRequest');
cy.intercept('POST', '/_plugins/_security_analytics/detectors').as('createDetectorRequest');

Expand Down Expand Up @@ -227,155 +220,141 @@ describe('Detectors', () => {

cy.createRule(dns_name_rule_data);
cy.createRule(dns_type_rule_data);

cy.request('POST', 'http://localhost:9200/_plugins/_notifications/configs/', {
config_id: 'sa_notification-channel_id',
name: sampleNotificationChannel,
config: {
name: sampleNotificationChannel,
description: 'This is a sample chime channel',
config_type: 'chime',
is_enabled: true,
chime: {
url: 'https://sample-chime-webhook',
},
},
}).should('have.property', 'status', 200);
});

// describe('...should validate form fields', () => {
// beforeEach(() => {
// cy.intercept('/_plugins/_security_analytics/detectors/_search').as('detectorsSearch');

// // Visit Detectors page before any test
// cy.visit(`${OPENSEARCH_DASHBOARDS_URL}/detectors`);
// cy.wait('@detectorsSearch').should('have.property', 'state', 'Complete');

// openCreateForm();
// });

// it('...should validate name field', () => {
// getNameField().should('be.empty');
// getNameField().focus().blur();
// getNameField().parentsUntil('.euiFormRow__fieldWrapper').siblings().contains('Enter a name.');

// getNameField().type('text').focus().blur();

// getNameField()
// .parents('.euiFormRow__fieldWrapper')
// .find('.euiFormErrorText')
// .contains(
// 'Name should only consist of upper and lowercase letters, numbers 0-9, hyphens, spaces, and underscores. Use between 5 and 50 characters.'
// );

// getNameField().type('{selectall}').type('{backspace}').type('tex&').focus().blur();

// getNameField()
// .parents('.euiFormRow__fieldWrapper')
// .find('.euiFormErrorText')
// .contains(
// 'Name should only consist of upper and lowercase letters, numbers 0-9, hyphens, spaces, and underscores. Use between 5 and 50 characters.'
// );

// getNameField()
// .type('{selectall}')
// .type('{backspace}')
// .type('Detector name')
// .focus()
// .blur()
// .parents('.euiFormRow__fieldWrapper')
// .find('.euiFormErrorText')
// .should('not.exist');
// });

// it('...should validate description field', () => {
// const longDescriptionText =
// 'This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text.';

// getDescriptionField().should('be.empty');

// getDescriptionField().type(longDescriptionText).focus().blur();

// getDescriptionField()
// .parents('.euiFormRow__fieldWrapper')
// .find('.euiFormErrorText')
// .contains(
// 'Description should only consist of upper and lowercase letters, numbers 0-9, commas, hyphens, periods, spaces, and underscores. Max limit of 500 characters.'
// );

// getDescriptionField()
// .type('{selectall}')
// .type('{backspace}')
// .type('Detector description...')
// .focus()
// .blur();

// getDescriptionField()
// .type('{selectall}')
// .type('{backspace}')
// .type('Detector name')
// .focus()
// .blur()
// .parents('.euiFormRow__fieldWrapper')
// .find('.euiFormErrorText')
// .should('not.exist');
// });

// it('...should validate data source field', () => {
// getDataSourceField()
// .focus()
// .blur()
// .parentsUntil('.euiFormRow__fieldWrapper')
// .siblings()
// .contains('Select an input source.');

// getDataSourceField().selectComboboxItem(cypressIndexDns);
// getDataSourceField()
// .focus()
// .blur()
// .parentsUntil('.euiFormRow__fieldWrapper')
// .find('.euiFormErrorText')
// .should('not.exist');
// });

// it('...should validate next button', () => {
// getNextButton().should('be.disabled');

// fillDetailsForm(detectorName, cypressIndexDns);
// getNextButton().should('be.enabled');
// });

// it('...should validate alerts page', () => {
// fillDetailsForm(detectorName, cypressIndexDns);
// getNextButton().click({ force: true });
// // Open the trigger details accordion
// cy.get('[data-test-subj="trigger-details-btn"]').click({ force: true });
// getTriggerNameField().should('have.value', 'Trigger 1');
// getTriggerNameField()
// .parents('.euiFormRow__fieldWrapper')
// .find('.euiFormErrorText')
// .should('not.exist');

// getTriggerNameField().type('{selectall}').type('{backspace}').focus().blur();
// getCreateDetectorButton().should('be.disabled');

// cy.getButtonByText('Remove').click({ force: true });
// getCreateDetectorButton().should('be.enabled');
// });

// it('...should show mappings warning', () => {
// fillDetailsForm(detectorName, cypressIndexDns);

// getDataSourceField().selectComboboxItem(cypressIndexWindows);
// getDataSourceField().focus().blur();

// cy.get('[data-test-subj="define-detector-diff-log-types-warning"]')
// .should('be.visible')
// .contains(
// 'To avoid issues with field mappings, we recommend creating separate detectors for different log types.'
// );
// });
// });
describe('...should validate form fields', () => {
beforeEach(() => {
cy.intercept('/_plugins/_security_analytics/detectors/_search').as('detectorsSearch');

// Visit Detectors page before any test
cy.visit(`${OPENSEARCH_DASHBOARDS_URL}/detectors`);
cy.wait('@detectorsSearch').should('have.property', 'state', 'Complete');

openCreateForm();
});

it('...should validate name field', () => {
getNameField().should('be.empty');
getNameField().focus().blur();
getNameField().parentsUntil('.euiFormRow__fieldWrapper').siblings().contains('Enter a name.');

getNameField().type('text').focus().blur();

getNameField()
.parents('.euiFormRow__fieldWrapper')
.find('.euiFormErrorText')
.contains(
'Name should only consist of upper and lowercase letters, numbers 0-9, hyphens, spaces, and underscores. Use between 5 and 50 characters.'
);

getNameField().type('{selectall}').type('{backspace}').type('tex&').focus().blur();

getNameField()
.parents('.euiFormRow__fieldWrapper')
.find('.euiFormErrorText')
.contains(
'Name should only consist of upper and lowercase letters, numbers 0-9, hyphens, spaces, and underscores. Use between 5 and 50 characters.'
);

getNameField()
.type('{selectall}')
.type('{backspace}')
.type('Detector name')
.focus()
.blur()
.parents('.euiFormRow__fieldWrapper')
.find('.euiFormErrorText')
.should('not.exist');
});

it('...should validate description field', () => {
const longDescriptionText =
'This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text. This is a long text.';

getDescriptionField().should('be.empty');

getDescriptionField().type(longDescriptionText).focus().blur();

getDescriptionField()
.parents('.euiFormRow__fieldWrapper')
.find('.euiFormErrorText')
.contains(
'Description should only consist of upper and lowercase letters, numbers 0-9, commas, hyphens, periods, spaces, and underscores. Max limit of 500 characters.'
);

getDescriptionField()
.type('{selectall}')
.type('{backspace}')
.type('Detector description...')
.focus()
.blur();

getDescriptionField()
.type('{selectall}')
.type('{backspace}')
.type('Detector name')
.focus()
.blur()
.parents('.euiFormRow__fieldWrapper')
.find('.euiFormErrorText')
.should('not.exist');
});

it('...should validate data source field', () => {
getDataSourceField()
.focus()
.blur()
.parentsUntil('.euiFormRow__fieldWrapper')
.siblings()
.contains('Select an input source.');

getDataSourceField().selectComboboxItem(cypressIndexDns);
getDataSourceField()
.focus()
.blur()
.parentsUntil('.euiFormRow__fieldWrapper')
.find('.euiFormErrorText')
.should('not.exist');
});

it('...should validate next button', () => {
getNextButton().should('be.disabled');

fillDetailsForm(detectorName, cypressIndexDns);
getNextButton().should('be.enabled');
});

it('...should validate alerts page', () => {
fillDetailsForm(detectorName, cypressIndexDns);
getNextButton().click({ force: true });
// Open the trigger details accordion
cy.get('[data-test-subj="trigger-details-btn"]').click({ force: true });
getTriggerNameField().should('have.value', 'Trigger 1');
getTriggerNameField()
.parents('.euiFormRow__fieldWrapper')
.find('.euiFormErrorText')
.should('not.exist');

getTriggerNameField().type('{selectall}').type('{backspace}').focus().blur();
getCreateDetectorButton().should('be.disabled');

cy.getButtonByText('Remove').click({ force: true });
getCreateDetectorButton().should('be.enabled');
});

it('...should show mappings warning', () => {
fillDetailsForm(detectorName, cypressIndexDns);

getDataSourceField().selectComboboxItem(cypressIndexWindows);
getDataSourceField().focus().blur();

cy.get('[data-test-subj="define-detector-diff-log-types-warning"]')
.should('be.visible')
.contains(
'To avoid issues with field mappings, we recommend creating separate detectors for different log types.'
);
});
});

describe('...validate create detector flow', () => {
beforeEach(() => {
Expand Down Expand Up @@ -521,9 +500,5 @@ describe('Detectors', () => {

after(() => {
cy.cleanUpTests();
cy.request(
'DELETE',
'http://localhost:9200/_plugins/_notifications/configs/sa_notification-channel_id'
);
});
});
12 changes: 9 additions & 3 deletions cypress/integration/2_rules.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -330,13 +330,20 @@ describe('Rules', () => {
it('...should validate selection map key field', () => {
getSelectionPanelByIndex(0).within(() => {
getMapKeyField().should('be.empty');
getMapKeyField().focus().blur();
getMapKeyField()
.focus()
.blur()
.parents('.euiFormRow__fieldWrapper')
.find('.euiFormErrorText')
.should('not.exist');

getMapKeyField().type('hello@');
getMapKeyField()
.parentsUntil('.euiFormRow__fieldWrapper')
.siblings()
.contains('Invalid key name');

getMapKeyField().type('FieldKey');
getMapKeyField().focus().type('{selectall}').type('FieldKey');
getMapKeyField()
.focus()
.blur()
Expand Down Expand Up @@ -446,7 +453,6 @@ describe('Rules', () => {
getSelectionPanelByIndex(0).within(() =>
getMapKeyField().type('{selectall}').type('{backspace}')
);
toastShouldExist();
getSelectionPanelByIndex(0).within(() => getMapKeyField().type('FieldKey'));

// selection map value field
Expand Down
4 changes: 2 additions & 2 deletions public/components/ContentPanel/ContentPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const renderSubTitleText = (subTitleText: string | JSX.Element): JSX.Element | n
return subTitleText;
};

const ContentPanel: React.SFC<ContentPanelProps> = ({
const ContentPanel = ({
title = '',
titleSize = 'm',
subTitleText = '',
Expand All @@ -48,7 +48,7 @@ const ContentPanel: React.SFC<ContentPanelProps> = ({
children,
hideHeaderBorder = false,
className = '',
}) => (
}: ContentPanelProps): JSX.Element => (
<EuiPanel
style={{ paddingLeft: '0px', paddingRight: '0px', ...panelStyles }}
className={className}
Expand Down
4 changes: 2 additions & 2 deletions public/components/FormFieldHeader/FormFieldHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ export interface FormFieldHeaderProps {
toolTipText?: string;
}

export const FormFieldHeader: React.FC<FormFieldHeaderProps> = ({
export const FormFieldHeader = ({
headerTitle = '',
optionalField = false,
toolTipIconType = 'questionInCircle',
toolTipPosition = 'top',
toolTipText = '',
}) => {
}: FormFieldHeaderProps): JSX.Element => {
return (
<EuiText size={'s'}>
<strong>{headerTitle}</strong>
Expand Down
Loading

0 comments on commit 3fb9021

Please sign in to comment.