From 25901f699c1e42b3d75349645f57a10a48e7ba68 Mon Sep 17 00:00:00 2001 From: "opensearch-trigger-bot[bot]" <98922864+opensearch-trigger-bot[bot]@users.noreply.github.com> Date: Wed, 25 Oct 2023 14:01:04 -0700 Subject: [PATCH] [Backport 2.11] Improved display of log types. (#766) * Improved display of log types. (#753) * Improved display of log types. Signed-off-by: AWSHurneyt * Fixed cypress tests. Signed-off-by: AWSHurneyt * Updated cypress workflow. Signed-off-by: AWSHurneyt * Fixed cypress tests. Fixed flyout. Fixed rule form. Signed-off-by: AWSHurneyt * Updated snapshots. Signed-off-by: AWSHurneyt * Updated log type labels usage. Adjusted cypress tests. Signed-off-by: AWSHurneyt * Updated snapshots. Signed-off-by: AWSHurneyt --------- Signed-off-by: AWSHurneyt (cherry picked from commit 7d90bb1301a3067164f4462291fa5a7d016b20e3) * Update cypress-workflow.yml Signed-off-by: AWSHurneyt --------- Signed-off-by: AWSHurneyt Co-authored-by: AWSHurneyt --- .github/workflows/cypress-workflow.yml | 6 +- cypress/integration/1_detectors.spec.js | 9 +- cypress/integration/2_rules.spec.js | 17 ++- cypress/integration/3_alerts.spec.js | 9 +- cypress/integration/4_findings.spec.js | 3 +- cypress/integration/5_integrations.spec.js | 142 ------------------ .../containers/CreateCorrelationRule.tsx | 2 +- public/pages/Correlations/utils/constants.tsx | 4 +- .../DetectionRules/utils/constants.tsx | 3 +- .../components/DetectorType/DetectorType.tsx | 7 +- .../DetectorBasicDetailsView.tsx | 3 +- .../DetectorBasicDetailsView.test.tsx.snap | 4 +- .../DetectorDetails.test.tsx.snap | 2 +- .../DetectorDetailsView.test.tsx.snap | 2 +- .../components/FindingDetailsFlyout.tsx | 5 +- public/pages/LogTypes/utils/constants.ts | 18 +++ public/pages/LogTypes/utils/helpers.tsx | 11 +- .../Overview/components/Widgets/Summary.tsx | 5 +- .../RuleContentViewer/RuleContentViewer.tsx | 5 +- .../RuleContentViewer.test.tsx.snap | 2 +- .../components/RuleEditor/RuleEditorForm.tsx | 10 +- public/store/LogTypeStore.ts | 3 +- public/store/RulesStore.ts | 2 +- public/utils/helpers.tsx | 9 +- 24 files changed, 96 insertions(+), 187 deletions(-) delete mode 100644 cypress/integration/5_integrations.spec.js diff --git a/.github/workflows/cypress-workflow.yml b/.github/workflows/cypress-workflow.yml index bc680ce68..6dcef19f2 100644 --- a/.github/workflows/cypress-workflow.yml +++ b/.github/workflows/cypress-workflow.yml @@ -7,8 +7,8 @@ on: branches: - "*" env: - OPENSEARCH_DASHBOARDS_VERSION: '2.x' - SECURITY_ANALYTICS_BRANCH: '2.x' + OPENSEARCH_DASHBOARDS_VERSION: '2.11.0' + SECURITY_ANALYTICS_BRANCH: '2.11.0.0' jobs: tests: name: Run Cypress E2E tests @@ -87,7 +87,7 @@ jobs: - name: Run OpenSearch-Dashboards server run: | cd OpenSearch-Dashboards - yarn start --no-base-path --no-watch & + yarn start --no-base-path --no-watch --server.host="0.0.0.0" & shell: bash # Window is slow so wait longer diff --git a/cypress/integration/1_detectors.spec.js b/cypress/integration/1_detectors.spec.js index cf68e69ae..be8ea2e5a 100644 --- a/cypress/integration/1_detectors.spec.js +++ b/cypress/integration/1_detectors.spec.js @@ -10,6 +10,7 @@ import dns_name_rule_data from '../fixtures/integration_tests/rule/create_dns_ru import dns_type_rule_data from '../fixtures/integration_tests/rule/create_dns_rule_with_type_selection.json'; import _ from 'lodash'; import { getMappingFields } from '../../public/pages/Detectors/utils/helpers'; +import { getLogTypeLabel } from '../../public/pages/LogTypes/utils/helpers'; const cypressIndexDns = 'cypress-index-dns'; const cypressIndexWindows = 'cypress-index-windows'; @@ -114,9 +115,9 @@ const validatePendingFieldMappingsPanel = (mappings) => { const fillDetailsForm = (detectorName, dataSource) => { getNameField().type(detectorName); getDataSourceField().selectComboboxItem(dataSource); - getDataSourceField().blur(); - getLogTypeField().selectComboboxItem(cypressLogTypeDns); - getLogTypeField().blur(); + getDataSourceField().focus().blur(); + getLogTypeField().selectComboboxItem(getLogTypeLabel(cypressLogTypeDns)); + getLogTypeField().focus().blur(); }; const createDetector = (detectorName, dataSource, expectFailure) => { @@ -126,7 +127,7 @@ const createDetector = (detectorName, dataSource, expectFailure) => { cy.getElementByText('.euiAccordion .euiTitle', 'Detection rules (14 selected)') .click({ force: true, timeout: 5000 }) - .then(() => cy.contains('.euiTable .euiTableRow', 'Dns')); + .then(() => cy.contains('.euiTable .euiTableRow', getLogTypeLabel(cypressLogTypeDns))); cy.getElementByText('.euiAccordion .euiTitle', 'Field mapping - optional'); cy.get('[aria-controls="mappedTitleFieldsAccordion"]').then(($btn) => { diff --git a/cypress/integration/2_rules.spec.js b/cypress/integration/2_rules.spec.js index 89544f177..b09a9d385 100644 --- a/cypress/integration/2_rules.spec.js +++ b/cypress/integration/2_rules.spec.js @@ -4,6 +4,7 @@ */ import { OPENSEARCH_DASHBOARDS_URL } from '../support/constants'; +import { getLogTypeLabel } from '../../public/pages/LogTypes/utils/helpers'; const uniqueId = Cypress._.random(0, 1e6); const SAMPLE_RULE = { @@ -55,7 +56,9 @@ const checkRulesFlyout = () => { cy.get('[data-test-subj="rule_flyout_rule_name"]').contains(SAMPLE_RULE.name); // Validate log type - cy.get('[data-test-subj="rule_flyout_rule_log_type"]').contains(SAMPLE_RULE.logType); + cy.get('[data-test-subj="rule_flyout_rule_log_type"]').contains( + getLogTypeLabel(SAMPLE_RULE.logType) + ); // Validate description cy.get('[data-test-subj="rule_flyout_rule_description"]').contains(SAMPLE_RULE.description); @@ -161,7 +164,7 @@ const fillCreateForm = () => { getAuthorField().type(`${SAMPLE_RULE.author}`); // rule details - getLogTypeField().selectComboboxItem(SAMPLE_RULE.logType); + getLogTypeField().selectComboboxItem(getLogTypeLabel(SAMPLE_RULE.logType)); getRuleLevelField().selectComboboxItem(SAMPLE_RULE.severity); // rule detection @@ -284,7 +287,7 @@ describe('Rules', () => { getLogTypeField().focus().blur(); getLogTypeField().containsError('Log type is required'); - getLogTypeField().selectComboboxItem(SAMPLE_RULE.logType); + getLogTypeField().selectComboboxItem(getLogTypeLabel(SAMPLE_RULE.logType)); getLogTypeField().focus().blur().shouldNotHaveError(); }); @@ -425,7 +428,7 @@ describe('Rules', () => { // log field getLogTypeField().clearCombobox(); toastShouldExist(); - getLogTypeField().selectComboboxItem(SAMPLE_RULE.logType); + getLogTypeField().selectComboboxItem(getLogTypeLabel(SAMPLE_RULE.logType)); // severity field getRuleLevelField().clearCombobox(); @@ -550,8 +553,10 @@ describe('Rules', () => { SAMPLE_RULE.logType = 'dns'; YAML_RULE_LINES[2] = `product: ${SAMPLE_RULE.logType}`; YAML_RULE_LINES[3] = `title: ${SAMPLE_RULE.name}`; - getLogTypeField().selectComboboxItem(SAMPLE_RULE.logType); - getLogTypeField().containsValue(SAMPLE_RULE.logType).contains(SAMPLE_RULE.logType); + getLogTypeField().selectComboboxItem(getLogTypeLabel(SAMPLE_RULE.logType)); + getLogTypeField() + .containsValue(SAMPLE_RULE.logType) + .contains(getLogTypeLabel(SAMPLE_RULE.logType)); SAMPLE_RULE.description += ' edited'; YAML_RULE_LINES[4] = `description: ${SAMPLE_RULE.description}`; diff --git a/cypress/integration/3_alerts.spec.js b/cypress/integration/3_alerts.spec.js index 81341897f..f9ed43372 100644 --- a/cypress/integration/3_alerts.spec.js +++ b/cypress/integration/3_alerts.spec.js @@ -10,6 +10,7 @@ import aliasMappings from '../fixtures/sample_alias_mappings.json'; import indexDoc from '../fixtures/sample_document.json'; import ruleSettings from '../fixtures/integration_tests/rule/create_windows_usb_rule.json'; import { createDetector } from '../support/helpers'; +import { getLogTypeLabel } from '../../public/pages/LogTypes/utils/helpers'; const indexName = 'test-index'; const detectorName = 'test-detector'; @@ -118,7 +119,9 @@ describe('Alerts', () => { expect($tr, `timestamp`).to.contain(date); expect($tr, `rule name`).to.contain('Cypress USB Rule'); expect($tr, `detector name`).to.contain(testDetector.name); - expect($tr, `log type`).to.contain('System Activity: Windows'); + expect($tr, `log type`).to.contain( + `System Activity: ${getLogTypeLabel(testDetector.detector_type)}` + ); }); // Close the flyout @@ -189,7 +192,9 @@ describe('Alerts', () => { cy.get('[data-test-subj="finding-details-flyout-rule-severity"]').contains('High'); // Confirm the rule category - cy.get('[data-test-subj="finding-details-flyout-rule-category"]').contains('Windows'); + cy.get('[data-test-subj="finding-details-flyout-rule-category"]').contains( + getLogTypeLabel(testDetector.detector_type) + ); // Confirm the rule description cy.get('[data-test-subj="finding-details-flyout-rule-description"]').contains( diff --git a/cypress/integration/4_findings.spec.js b/cypress/integration/4_findings.spec.js index a2a2787bb..3fa12d608 100644 --- a/cypress/integration/4_findings.spec.js +++ b/cypress/integration/4_findings.spec.js @@ -9,6 +9,7 @@ import aliasMappings from '../fixtures/sample_alias_mappings.json'; import indexDoc from '../fixtures/sample_document.json'; import ruleSettings from '../fixtures/integration_tests/rule/create_windows_usb_rule.json'; import { createDetector } from '../support/helpers'; +import { getLogTypeLabel } from '../../public/pages/LogTypes/utils/helpers'; const indexName = 'test-index'; const detectorName = 'test-detector'; @@ -52,7 +53,7 @@ describe('Findings', () => { cy.contains('No items found').should('not.exist'); // Check for expected findings - cy.contains('System Activity: Windows'); + cy.contains(`System Activity: ${getLogTypeLabel(testDetector.detector_type)}`); cy.contains('High'); }); diff --git a/cypress/integration/5_integrations.spec.js b/cypress/integration/5_integrations.spec.js deleted file mode 100644 index 054295d7a..000000000 --- a/cypress/integration/5_integrations.spec.js +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - */ - -import { DETECTOR_TRIGGER_TIMEOUT, OPENSEARCH_DASHBOARDS_URL } from '../support/constants'; -import sample_index_settings from '../fixtures/sample_windows_index_settings.json'; -import sample_dns_settings from '../fixtures/integration_tests/index/create_dns_settings.json'; -import windows_usb_rule_data from '../fixtures/integration_tests/rule/create_windows_usb_rule.json'; -import dns_rule_data from '../fixtures/integration_tests/rule/create_dns_rule_with_name_selection.json'; -import usb_detector_data from '../fixtures/integration_tests/detector/create_usb_detector_data.json'; -import usb_detector_data_mappings from '../fixtures/integration_tests/detector/create_usb_detector_mappings_data.json'; -import dns_detector_data_mappings from '../fixtures/integration_tests/detector/create_dns_detector_mappings_data.json'; -import dns_detector_data from '../fixtures/integration_tests/detector/create_dns_detector_data.json'; -import add_windows_index_data from '../fixtures/integration_tests/index/add_windows_index_data.json'; -import add_dns_index_data from '../fixtures/integration_tests/index/add_dns_index_data.json'; - -describe('Integration tests', () => { - const indexName = 'cypress-index-windows'; - const dnsName = 'cypress-index-dns'; - - before(() => { - cy.cleanUpTests(); - - // Create custom rules - cy.createRule(windows_usb_rule_data).then((response) => { - usb_detector_data.inputs[0].detector_input.custom_rules[0].id = response.body.response._id; - usb_detector_data.triggers[0].ids.push(response.body.response._id); - }); - cy.createRule(dns_rule_data).then((response) => { - dns_detector_data.inputs[0].detector_input.custom_rules[0].id = response.body.response._id; - dns_detector_data.triggers[0].ids.push(response.body.response._id); - }); - - // Create test index - cy.createIndex(indexName, sample_index_settings); - cy.createIndex(dnsName, sample_dns_settings); - - // Create detectors - cy.createAliasMappings( - indexName, - usb_detector_data.detector_type, - usb_detector_data_mappings, - true - ).then(() => cy.createDetector(usb_detector_data)); - - cy.createAliasMappings( - dnsName, - dns_detector_data.detector_type, - dns_detector_data_mappings, - true - ).then(() => cy.createDetector(dns_detector_data)); - - // Ingest docs - cy.request( - 'POST', - `${Cypress.env('opensearch')}/${indexName}/_doc/101`, - add_windows_index_data - ); - cy.request('POST', `${Cypress.env('opensearch')}/${dnsName}/_doc/101`, add_dns_index_data); - - // Wait for detector interval to pass - cy.wait(DETECTOR_TRIGGER_TIMEOUT); - }); - - beforeEach(() => { - // Visit Detectors page - cy.visit(`${OPENSEARCH_DASHBOARDS_URL}/detectors`); - - // Wait for page to load - cy.waitForPageLoad('detectors', 'Threat detectors'); - }); - - xit('...can navigate to findings page', () => { - cy.intercept({ - method: 'GET', - pathname: '/_plugins/_security_analytics/findings/_search', - }).as('getFindings'); - - // Cypress USB Detector - cy.contains('Cypress USB Detector') - .click() - .then(() => { - cy.contains('View Findings') - .click() - .then(() => { - cy.hash() - .should('match', /findings\/.+$/) - .then((hash) => { - const detectorId = hash.replace('#/findings/', ''); - if (!detectorId) { - throw new Error('Navigating to findings page should contain detector ID'); - } else { - cy.wait('@getFindings').then((interception) => { - const url = new URL(interception.request.url); - // The request query param detectorId should match the hash param from the url - expect(url.searchParams.get('detectorId')).to.eq(detectorId); - }); - - // There should be only one call to the API - cy.get('@getFindings.all').should('have.length', 1); - } - }); - }); - }); - }); - xit('...can navigate to alerts page', () => { - cy.intercept({ - method: 'GET', - pathname: '/_plugins/_security_analytics/alerts', - }).as('getAlerts'); - - // Cypress USB Detector - cy.contains('Cypress USB Detector') - .click() - .then(() => { - cy.contains('View Alerts') - .click() - .then(() => { - cy.hash() - .should('match', /alerts\/.+$/) - .then((hash) => { - const detectorId = hash.replace('#/alerts/', ''); - if (!detectorId) { - throw new Error('Navigating to alerts page should contain detector ID'); - } else { - cy.wait('@getAlerts').then((interception) => { - const url = new URL(interception.request.url); - // The request query param detectorId should match the hash param from the url - expect(url.searchParams.get('detector_id')).to.eq(detectorId); - }); - - // There should be only one call to the API - cy.get('@getAlerts.all').should('have.length', 1); - } - }); - }); - }); - }); - - after(() => cy.cleanUpTests()); -}); diff --git a/public/pages/Correlations/containers/CreateCorrelationRule.tsx b/public/pages/Correlations/containers/CreateCorrelationRule.tsx index c986eb4d1..95d7c5d36 100644 --- a/public/pages/Correlations/containers/CreateCorrelationRule.tsx +++ b/public/pages/Correlations/containers/CreateCorrelationRule.tsx @@ -297,7 +297,7 @@ export const CreateCorrelationRule: React.FC = ( label: ruleTypes.find( (logType) => - logType.label.toLowerCase() === query.logType.toLowerCase() + logType.value.toLowerCase() === query.logType.toLowerCase() )?.label || query.logType, }, ] diff --git a/public/pages/Correlations/utils/constants.tsx b/public/pages/Correlations/utils/constants.tsx index 8c140ee62..f54889285 100644 --- a/public/pages/Correlations/utils/constants.tsx +++ b/public/pages/Correlations/utils/constants.tsx @@ -9,7 +9,7 @@ import { ruleSeverity, ruleTypes } from '../../Rules/utils/constants'; import { FilterItem } from '../components/FilterGroup'; import { EuiIcon, EuiTitle } from '@elastic/eui'; import { logTypeCategories, logTypesByCategories } from '../../../utils/constants'; -import _ from 'lodash'; +import { getLogTypeLabel } from '../../LogTypes/utils/helpers'; export const graphRenderOptions = { nodes: { @@ -67,7 +67,7 @@ export const getDefaultLogTypeFilterItemOptions: () => FilterItem[] = () => { logTypes.forEach(({ name }) => { options.push({ - name: _.capitalize(name), + name: getLogTypeLabel(name), id: name, checked: 'on', visible: true, diff --git a/public/pages/CreateDetector/components/DefineDetector/components/DetectionRules/utils/constants.tsx b/public/pages/CreateDetector/components/DefineDetector/components/DetectionRules/utils/constants.tsx index 1b7132f44..9eaa48e4b 100644 --- a/public/pages/CreateDetector/components/DefineDetector/components/DetectionRules/utils/constants.tsx +++ b/public/pages/CreateDetector/components/DefineDetector/components/DetectionRules/utils/constants.tsx @@ -7,6 +7,7 @@ import { EuiBasicTableColumn, EuiLink, EuiSwitch } from '@elastic/eui'; import { capitalizeFirstLetter } from '../../../../../../../utils/helpers'; import React, { ReactNode } from 'react'; import { RuleItem } from '../types/interfaces'; +import { getLogTypeLabel } from '../../../../../../LogTypes/utils/helpers'; export type ActiveToggleOnChangeEvent = React.BaseSyntheticEvent< React.MouseEvent, @@ -51,7 +52,7 @@ export const getRulesColumns = ( name: 'Log type', width: '10%', sortable: true, - render: (logType: string) => capitalizeFirstLetter(logType), + render: (logType: string) => getLogTypeLabel(logType), }, { field: 'library', diff --git a/public/pages/CreateDetector/components/DefineDetector/components/DetectorType/DetectorType.tsx b/public/pages/CreateDetector/components/DefineDetector/components/DetectorType/DetectorType.tsx index 0b98da1f9..c00959a7f 100644 --- a/public/pages/CreateDetector/components/DefineDetector/components/DetectorType/DetectorType.tsx +++ b/public/pages/CreateDetector/components/DefineDetector/components/DetectorType/DetectorType.tsx @@ -13,6 +13,7 @@ import { ruleTypes } from '../../../../../Rules/utils/constants'; import ConfigureFieldMapping from '../../../ConfigureFieldMapping'; import { ConfigureFieldMappingProps } from '../../../ConfigureFieldMapping/containers/ConfigureFieldMapping'; import { getLogTypeOptions } from '../../../../../../utils/helpers'; +import { getLogTypeLabel } from '../../../../../LogTypes/utils/helpers'; interface DetectorTypeProps { detectorType: string; @@ -97,9 +98,11 @@ export default class DetectorType extends Component { - this.onChange(e[0]?.label || ''); + this.onChange(e[0]?.value || ''); }} - selectedOptions={detectorType ? [{ value: detectorType, label: detectorType }] : []} + selectedOptions={ + detectorType ? [{ value: detectorType, label: getLogTypeLabel(detectorType) }] : [] + } /> diff --git a/public/pages/Detectors/components/DetectorBasicDetailsView/DetectorBasicDetailsView.tsx b/public/pages/Detectors/components/DetectorBasicDetailsView/DetectorBasicDetailsView.tsx index 79a3eb6c5..8ff9c0a84 100644 --- a/public/pages/Detectors/components/DetectorBasicDetailsView/DetectorBasicDetailsView.tsx +++ b/public/pages/Detectors/components/DetectorBasicDetailsView/DetectorBasicDetailsView.tsx @@ -10,6 +10,7 @@ import { createTextDetailsGroup, parseSchedule } from '../../../../utils/helpers import moment from 'moment'; import { DEFAULT_EMPTY_DATA, logTypesWithDashboards } from '../../../../utils/constants'; import { Detector } from '../../../../../types'; +import { getLogTypeLabel } from '../../../LogTypes/utils/helpers'; export interface DetectorBasicDetailsViewProps { detector: Detector; @@ -77,7 +78,7 @@ export const DetectorBasicDetailsView: React.FC = ), }, - { label: 'Log type', content: detector_type.toLowerCase() }, + { label: 'Log type', content: getLogTypeLabel(detector_type.toLowerCase()) }, { label: 'Detector dashboard', content: (dashboardId ? ( diff --git a/public/pages/Detectors/components/DetectorBasicDetailsView/__snapshots__/DetectorBasicDetailsView.test.tsx.snap b/public/pages/Detectors/components/DetectorBasicDetailsView/__snapshots__/DetectorBasicDetailsView.test.tsx.snap index d91290cfb..5ec82f39e 100644 --- a/public/pages/Detectors/components/DetectorBasicDetailsView/__snapshots__/DetectorBasicDetailsView.test.tsx.snap +++ b/public/pages/Detectors/components/DetectorBasicDetailsView/__snapshots__/DetectorBasicDetailsView.test.tsx.snap @@ -258,7 +258,7 @@ Object { data-test-subj="text-details-group-content-log-type" id="some_html_id" > - detector_type + Detector Type @@ -684,7 +684,7 @@ Object { data-test-subj="text-details-group-content-log-type" id="some_html_id" > - detector_type + Detector Type diff --git a/public/pages/Detectors/containers/Detector/__snapshots__/DetectorDetails.test.tsx.snap b/public/pages/Detectors/containers/Detector/__snapshots__/DetectorDetails.test.tsx.snap index c65cd5c4a..387feca5c 100644 --- a/public/pages/Detectors/containers/Detector/__snapshots__/DetectorDetails.test.tsx.snap +++ b/public/pages/Detectors/containers/Detector/__snapshots__/DetectorDetails.test.tsx.snap @@ -1945,7 +1945,7 @@ exports[` spec renders the component 1`] = ` onBlur={[Function]} onFocus={[Function]} > - detector_type + Detector Type diff --git a/public/pages/Detectors/containers/DetectorDetailsView/__snapshots__/DetectorDetailsView.test.tsx.snap b/public/pages/Detectors/containers/DetectorDetailsView/__snapshots__/DetectorDetailsView.test.tsx.snap index 18ef95196..1ffe9ed13 100644 --- a/public/pages/Detectors/containers/DetectorDetailsView/__snapshots__/DetectorDetailsView.test.tsx.snap +++ b/public/pages/Detectors/containers/DetectorDetailsView/__snapshots__/DetectorDetailsView.test.tsx.snap @@ -988,7 +988,7 @@ exports[` spec renders the component 1`] = ` onBlur={[Function]} onFocus={[Function]} > - detector_type + Detector Type diff --git a/public/pages/Findings/components/FindingDetailsFlyout.tsx b/public/pages/Findings/components/FindingDetailsFlyout.tsx index 9adba27e8..74518b31e 100644 --- a/public/pages/Findings/components/FindingDetailsFlyout.tsx +++ b/public/pages/Findings/components/FindingDetailsFlyout.tsx @@ -45,6 +45,7 @@ import { CorrelationFinding, RuleItemInfoBase } from '../../../../types'; import { FindingFlyoutTabId, FindingFlyoutTabs } from '../utils/constants'; import { DataStore } from '../../../store/DataStore'; import { CorrelationsTable } from './CorrelationsTable/CorrelationsTable'; +import { getLogTypeLabel } from '../../LogTypes/utils/helpers'; export interface FindingDetailsFlyoutBaseProps { finding: FindingItemType; @@ -249,9 +250,7 @@ export default class FindingDetailsFlyout extends Component< label={'Log type'} data-test-subj={'finding-details-flyout-rule-category'} > - - {capitalizeFirstLetter(fullRule.category) || DEFAULT_EMPTY_DATA} - + {getLogTypeLabel(fullRule.category) || DEFAULT_EMPTY_DATA} diff --git a/public/pages/LogTypes/utils/constants.ts b/public/pages/LogTypes/utils/constants.ts index 5f672935d..3c180aa52 100644 --- a/public/pages/LogTypes/utils/constants.ts +++ b/public/pages/LogTypes/utils/constants.ts @@ -23,3 +23,21 @@ export const defaultLogType: LogTypeBase = { tags: null, category: '', }; + +export const logTypeLabels: { [value: string]: string } = { + cloudtrail: 'AWS Cloudtrail', + dns: 'DNS', + vpcflow: 'VPC Flow', + ad_ldap: 'AD/LDAP', + apache_access: 'Apache Access', + m365: 'Microsoft 365', + okta: 'Okta', + waf: 'WAF', + s3: 'AWS S3', + github: 'Github', + gworkspace: 'Google Workspace', + windows: 'Microsoft Windows', + network: 'Network', + linux: 'Linux System Logs', + azure: 'Microsoft Azure', +}; diff --git a/public/pages/LogTypes/utils/helpers.tsx b/public/pages/LogTypes/utils/helpers.tsx index 4826ff4e1..99e24fb13 100644 --- a/public/pages/LogTypes/utils/helpers.tsx +++ b/public/pages/LogTypes/utils/helpers.tsx @@ -6,10 +6,11 @@ import React from 'react'; import { EuiButtonIcon, EuiLink, EuiToolTip } from '@elastic/eui'; import { LogType } from '../../../../types'; -import { capitalize } from 'lodash'; +import { capitalize, startCase } from 'lodash'; import { Search } from '@opensearch-project/oui/src/eui_components/basic_table'; import { ruleSource } from '../../Rules/utils/constants'; -import { logTypeCategories } from '../../../utils/constants'; +import { DEFAULT_EMPTY_DATA, logTypeCategories } from '../../../utils/constants'; +import { logTypeLabels } from './constants'; export const getLogTypesTableColumns = ( showDetails: (id: string) => void, @@ -20,7 +21,7 @@ export const getLogTypesTableColumns = ( name: 'Name', sortable: true, render: (name: string, item: LogType) => { - return showDetails(item.id)}>{name}; + return showDetails(item.id)}>{getLogTypeLabel(name)}; }, }, { @@ -87,3 +88,7 @@ export const getLogTypesTableSearchConfig = (): Search => { ], }; }; + +export const getLogTypeLabel = (name: string) => { + return !name ? DEFAULT_EMPTY_DATA : logTypeLabels[name.toLowerCase()] || startCase(name); +}; diff --git a/public/pages/Overview/components/Widgets/Summary.tsx b/public/pages/Overview/components/Widgets/Summary.tsx index c73b5b135..1eda65018 100644 --- a/public/pages/Overview/components/Widgets/Summary.tsx +++ b/public/pages/Overview/components/Widgets/Summary.tsx @@ -26,6 +26,7 @@ import { AlertItem, FindingItem } from '../../models/interfaces'; import { createSelectComponent, renderVisualization } from '../../../../utils/helpers'; import { PLUGIN_NAME, ROUTES } from '../../../../utils/constants'; import { ChartContainer } from '../../../../components/Charts/ChartContainer'; +import { getLogTypeLabel } from '../../../LogTypes/utils/helpers'; export interface SummaryProps { findings: FindingItem[]; @@ -97,7 +98,7 @@ export const Summary: React.FC = ({ time: getTimeWithMinPrecision(alert.time), alert: 1, finding: 0, - logType: alert.logType, + logType: getLogTypeLabel(alert.logType), }); }); @@ -106,7 +107,7 @@ export const Summary: React.FC = ({ time: getTimeWithMinPrecision(finding.time), alert: 0, finding: 1, - logType: finding.logType, + logType: getLogTypeLabel(finding.logType), }); }); diff --git a/public/pages/Rules/components/RuleContentViewer/RuleContentViewer.tsx b/public/pages/Rules/components/RuleContentViewer/RuleContentViewer.tsx index e38440245..18084f77d 100644 --- a/public/pages/Rules/components/RuleContentViewer/RuleContentViewer.tsx +++ b/public/pages/Rules/components/RuleContentViewer/RuleContentViewer.tsx @@ -20,6 +20,7 @@ import { DEFAULT_EMPTY_DATA } from '../../../../utils/constants'; import React, { useState } from 'react'; import { RuleContentYamlViewer } from './RuleContentYamlViewer'; import { RuleItemInfoBase } from '../../../../../types'; +import { getLogTypeLabel } from '../../../LogTypes/utils/helpers'; export interface RuleContentViewerProps { rule: RuleItemInfoBase; @@ -67,7 +68,9 @@ export const RuleContentViewer: React.FC = ({ Log Type - {ruleData.category} + + {getLogTypeLabel(ruleData.category)} + diff --git a/public/pages/Rules/components/RuleContentViewer/__snapshots__/RuleContentViewer.test.tsx.snap b/public/pages/Rules/components/RuleContentViewer/__snapshots__/RuleContentViewer.test.tsx.snap index 891a04d01..11d488f58 100644 --- a/public/pages/Rules/components/RuleContentViewer/__snapshots__/RuleContentViewer.test.tsx.snap +++ b/public/pages/Rules/components/RuleContentViewer/__snapshots__/RuleContentViewer.test.tsx.snap @@ -103,7 +103,7 @@ exports[` spec renders the component 1`] = ` class="euiText euiText--medium" data-test-subj="rule_flyout_rule_log_type" > - dns + DNS diff --git a/public/pages/Rules/components/RuleEditor/RuleEditorForm.tsx b/public/pages/Rules/components/RuleEditor/RuleEditorForm.tsx index 5f883e3d2..863456cf9 100644 --- a/public/pages/Rules/components/RuleEditor/RuleEditorForm.tsx +++ b/public/pages/Rules/components/RuleEditor/RuleEditorForm.tsx @@ -32,6 +32,7 @@ import { mapFormToRule, mapRuleToForm } from './mappers'; import { DetectionVisualEditor } from './DetectionVisualEditor'; import { useCallback } from 'react'; import { getLogTypeOptions } from '../../../../utils/helpers'; +import { getLogTypeLabel } from '../../../LogTypes/utils/helpers'; export interface VisualRuleEditorProps { initialValue: RuleEditorFormModel; @@ -282,13 +283,18 @@ export const RuleEditorForm: React.FC = ({ options={logTypeOptions} singleSelection={{ asPlainText: true }} onChange={(e) => { - props.handleChange('logType')(e[0]?.label ? e[0].label : ''); + props.handleChange('logType')(e[0]?.value ? e[0].value : ''); }} onFocus={refreshLogTypeOptions} onBlur={props.handleBlur('logType')} selectedOptions={ props.values.logType - ? [{ value: props.values.logType, label: props.values.logType }] + ? [ + { + value: props.values.logType, + label: getLogTypeLabel(props.values.logType), + }, + ] : [] } /> diff --git a/public/store/LogTypeStore.ts b/public/store/LogTypeStore.ts index 3528406df..701b57d3a 100644 --- a/public/store/LogTypeStore.ts +++ b/public/store/LogTypeStore.ts @@ -10,6 +10,7 @@ import { errorNotificationToast } from '../utils/helpers'; import { DataStore } from './DataStore'; import { ruleTypes } from '../pages/Rules/utils/constants'; import { logTypeCategories, logTypesByCategories } from '../utils/constants'; +import { getLogTypeLabel } from '../pages/LogTypes/utils/helpers'; export class LogTypeStore { constructor(private service: LogTypeService, private notifications: NotificationsStart) {} @@ -55,7 +56,7 @@ export class LogTypeStore { ruleTypes.length, ...logTypes .map(({ category, id, name }) => ({ - label: name, + label: getLogTypeLabel(name), value: name, id, category, diff --git a/public/store/RulesStore.ts b/public/store/RulesStore.ts index 0678ee196..5a9e285e9 100644 --- a/public/store/RulesStore.ts +++ b/public/store/RulesStore.ts @@ -112,7 +112,7 @@ export class RulesStore implements IRulesStore { if (!terms) { terms = { - 'rule.category': ruleTypes.map(({ label }) => label.toLowerCase()), + 'rule.category': ruleTypes.map(({ value }) => value.toLowerCase()), }; } else if (terms['rule.category']) { terms['rule.category'] = terms['rule.category'].map((category) => category.toLowerCase()); diff --git a/public/utils/helpers.tsx b/public/utils/helpers.tsx index ef30e0019..6ef3636f9 100644 --- a/public/utils/helpers.tsx +++ b/public/utils/helpers.tsx @@ -40,6 +40,7 @@ import _ from 'lodash'; import { LogType } from '../../types'; import { DataStore } from '../store/DataStore'; import { LogCategoryOptionView } from '../components/Utility/LogCategoryOption'; +import { getLogTypeLabel } from '../pages/LogTypes/utils/helpers'; export const parseStringsToOptions = (strings: string[]) => { return strings.map((str) => ({ id: str, label: str })); @@ -305,11 +306,11 @@ export const getPlugins = async (opensearchService: OpenSearchService) => { export const formatRuleType = (matchingRuleType: string) => { const logType = ruleTypes.find( - (ruleType) => ruleType.label.toLowerCase() === matchingRuleType.toLowerCase() + (ruleType) => ruleType.value.toLowerCase() === matchingRuleType.toLowerCase() ); if (logType) { - return `${logType.category}: ${_.capitalize(logType.label)}`; + return `${logType.category}: ${getLogTypeLabel(logType.value)}`; } return DEFAULT_EMPTY_DATA; @@ -332,7 +333,7 @@ export function formatToLogTypeOptions(logTypesByCategories: { [category: string value: category, options: logTypes .map(({ name }) => ({ - label: name, + label: getLogTypeLabel(name), value: name.toLowerCase(), })) .sort((a, b) => (a.label < b.label ? -1 : a.label > b.label ? 1 : 0)), @@ -363,7 +364,7 @@ export function getLogTypeFilterOptions() { value: logTypes[i].value, view: ( - {_.capitalize(logTypes[i].label)} + {getLogTypeLabel(logTypes[i].label)} ), });