From e44d3cc7c22c0622e5896e6bf35ca24a1d84e38a Mon Sep 17 00:00:00 2001 From: Amardeepsingh Siglani Date: Mon, 31 Jul 2023 15:13:50 -0700 Subject: [PATCH] fixed log type labels; cypress tests Signed-off-by: Amardeepsingh Siglani --- cypress/integration/1_detectors.spec.js | 1 - cypress/integration/3_alerts.spec.js | 2 +- cypress/integration/4_findings.spec.js | 2 +- .../containers/CorrelationsContainer.tsx | 4 +- .../containers/CreateCorrelationRule.tsx | 18 ++- public/pages/Correlations/utils/constants.tsx | 15 +- .../LogTypes/components/LogTypeDetailsTab.tsx | 2 +- .../pages/LogTypes/components/LogTypeForm.tsx | 5 +- .../LogTypes/containers/CreateLogType.tsx | 2 +- public/pages/LogTypes/containers/LogType.tsx | 28 ++-- .../LogTypes/containers/LogTypeDetails.tsx | 137 ------------------ public/pages/Rules/utils/helpers.tsx | 3 +- public/services/LogTypeService.ts | 18 ++- public/store/LogTypeStore.ts | 17 ++- public/store/RulesStore.ts | 4 +- public/utils/helpers.tsx | 4 +- types/LogTypes.ts | 8 +- 17 files changed, 87 insertions(+), 183 deletions(-) delete mode 100644 public/pages/LogTypes/containers/LogTypeDetails.tsx diff --git a/cypress/integration/1_detectors.spec.js b/cypress/integration/1_detectors.spec.js index 13a23eaab..609615dc6 100644 --- a/cypress/integration/1_detectors.spec.js +++ b/cypress/integration/1_detectors.spec.js @@ -117,7 +117,6 @@ const fillDetailsForm = (detectorName, dataSource) => { getDataSourceField().selectComboboxItem(dataSource); getLogTypeField().selectComboboxItem(cypressLogTypeDns); getLogTypeField().blur(); - // selectDnsLogType(); }; const createDetector = (detectorName, dataSource, expectFailure) => { diff --git a/cypress/integration/3_alerts.spec.js b/cypress/integration/3_alerts.spec.js index 9d3403491..3476d78e0 100644 --- a/cypress/integration/3_alerts.spec.js +++ b/cypress/integration/3_alerts.spec.js @@ -118,7 +118,7 @@ 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('Windows'); + expect($tr, `log type`).to.contain('windows'); }); // Close the flyout diff --git a/cypress/integration/4_findings.spec.js b/cypress/integration/4_findings.spec.js index eec8234b8..59114b36a 100644 --- a/cypress/integration/4_findings.spec.js +++ b/cypress/integration/4_findings.spec.js @@ -52,7 +52,7 @@ describe('Findings', () => { cy.contains('No items found').should('not.exist'); // Check for expected findings - cy.contains('Windows'); + cy.contains('windows'); cy.contains('High'); }); diff --git a/public/pages/Correlations/containers/CorrelationsContainer.tsx b/public/pages/Correlations/containers/CorrelationsContainer.tsx index 9270e7377..5647dcad9 100644 --- a/public/pages/Correlations/containers/CorrelationsContainer.tsx +++ b/public/pages/Correlations/containers/CorrelationsContainer.tsx @@ -6,7 +6,7 @@ import { CorrelationFinding, CorrelationGraphData, DateTimeFilter } from '../../ import React from 'react'; import { RouteComponentProps } from 'react-router-dom'; import { - defaultLogTypeFilterItemOptions, + getDefaultLogTypeFilterItemOptions, defaultSeverityFilterItemOptions, emptyGraphData, getAbbrFromLogType, @@ -85,7 +85,7 @@ export class Correlations extends React.Component = ( isInvalid={isInvalidInputForQuery('logType')} placeholder="Select a log type" data-test-subj={'rule_type_dropdown'} - options={ruleTypes.map(({ value, label }) => ({ value, label }))} + options={ruleTypes.map(({ label }) => ({ + value: label.toLowerCase(), + label, + }))} singleSelection={{ asPlainText: true }} onChange={(e) => { props.handleChange(`queries[${queryIdx}].logType`)( @@ -283,7 +286,18 @@ export const CreateCorrelationRule: React.FC = ( }} onBlur={props.handleBlur(`queries[${queryIdx}].logType`)} selectedOptions={ - query.logType ? [{ value: query.logType, label: query.logType }] : [] + query.logType + ? [ + { + value: query.logType, + label: + ruleTypes.find( + (logType) => + logType.label.toLowerCase() === query.logType.toLowerCase() + )?.label || query.logType, + }, + ] + : [] } isClearable={true} onCreateOption={(e) => { diff --git a/public/pages/Correlations/utils/constants.tsx b/public/pages/Correlations/utils/constants.tsx index 0b95f4f44..46d5d58e6 100644 --- a/public/pages/Correlations/utils/constants.tsx +++ b/public/pages/Correlations/utils/constants.tsx @@ -47,15 +47,12 @@ export const graphRenderOptions = { }, }; -export const defaultLogTypeFilterItemOptions: FilterItem[] = Object.values(ruleTypes).map( - (type) => { - return { - name: `${type.abbr}: ${type.label}`, - id: type.value, - checked: 'on', - }; - } -); +export const getDefaultLogTypeFilterItemOptions: () => FilterItem[] = () => + Object.values(ruleTypes).map((type) => ({ + name: `${type.label}`, + id: type.label.toLowerCase(), + checked: 'on', + })); export const defaultSeverityFilterItemOptions: FilterItem[] = Object.values(ruleSeverity).map( (sev) => { diff --git a/public/pages/LogTypes/components/LogTypeDetailsTab.tsx b/public/pages/LogTypes/components/LogTypeDetailsTab.tsx index 04504f35e..136c5726c 100644 --- a/public/pages/LogTypes/components/LogTypeDetailsTab.tsx +++ b/public/pages/LogTypes/components/LogTypeDetailsTab.tsx @@ -64,7 +64,7 @@ export const LogTypeDetailsTab: React.FC = ({ }) } placeholder="Enter name for log type" - disabled={!isEditMode || !!logTypeDetails.detectionRules} + disabled={!isEditMode || !!logTypeDetails.detectionRulesCount} /> diff --git a/public/pages/LogTypes/components/LogTypeForm.tsx b/public/pages/LogTypes/components/LogTypeForm.tsx index ce0b6ebb4..56d6a98f3 100644 --- a/public/pages/LogTypes/components/LogTypeForm.tsx +++ b/public/pages/LogTypes/components/LogTypeForm.tsx @@ -84,7 +84,8 @@ export const LogTypeForm: React.FC = ({ updateErrors(newLogType); }} placeholder="Enter name for the log type" - disabled={!isEditMode || !!logTypeDetails.detectionRules} + readOnly={!isEditMode} + disabled={isEditMode && !!logTypeDetails.detectionRulesCount} /> @@ -100,7 +101,7 @@ export const LogTypeForm: React.FC = ({ updateErrors(newLogType); }} placeholder="Description of the log type" - disabled={!isEditMode} + readOnly={!isEditMode} /> {isEditMode ? ( diff --git a/public/pages/LogTypes/containers/CreateLogType.tsx b/public/pages/LogTypes/containers/CreateLogType.tsx index 1d11974ba..01d4d8d1e 100644 --- a/public/pages/LogTypes/containers/CreateLogType.tsx +++ b/public/pages/LogTypes/containers/CreateLogType.tsx @@ -48,7 +48,7 @@ export const CreateLogType: React.FC = ({ history, notificat hideHeaderBorder={true} > = ({ notifications, history }) => { const updateRules = useCallback(async (details: LogTypeItem, intialDetails: LogTypeItem) => { const rulesRes = await DataStore.rules.getAllRules({ - 'rule.category': [logTypeId], + 'rule.category': [details.name.toLowerCase()], }); const ruleItems = rulesRes.map((rule) => ({ title: rule._source.title, @@ -74,22 +74,15 @@ export const LogType: React.FC = ({ notifications, history }) => { setLoadingRules(false); setLogTypeDetails({ ...details, - detectionRules: ruleItems.length, + detectionRulesCount: ruleItems.length, }); setInitialLogTypeDetails({ ...intialDetails, - detectionRules: ruleItems.length, + detectionRulesCount: ruleItems.length, }); }, []); useEffect(() => { - context?.chrome.setBreadcrumbs([ - BREADCRUMBS.SECURITY_ANALYTICS, - BREADCRUMBS.DETECTORS, - BREADCRUMBS.LOG_TYPES, - { text: logTypeId }, - ]); - const getLogTypeDetails = async () => { const details = await DataStore.logTypes.getLogType(logTypeId); @@ -98,7 +91,14 @@ export const LogType: React.FC = ({ notifications, history }) => { return; } - updateRules(details, details); + context?.chrome.setBreadcrumbs([ + BREADCRUMBS.SECURITY_ANALYTICS, + BREADCRUMBS.DETECTORS, + BREADCRUMBS.LOG_TYPES, + { text: details.name }, + ]); + const logTypeItem = { ...details, detectionRulesCount: details.detectionRules.length }; + updateRules(logTypeItem, logTypeItem); }; getLogTypeDetails(); @@ -152,7 +152,7 @@ export const LogType: React.FC = ({ notifications, history }) => { {showDeleteModal && ( setShowDeleteModal(false)} onConfirm={deleteLogType} /> @@ -186,7 +186,9 @@ export const LogType: React.FC = ({ notifications, history }) => { diff --git a/public/pages/LogTypes/containers/LogTypeDetails.tsx b/public/pages/LogTypes/containers/LogTypeDetails.tsx deleted file mode 100644 index 8bff13635..000000000 --- a/public/pages/LogTypes/containers/LogTypeDetails.tsx +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright OpenSearch Contributors - * SPDX-License-Identifier: Apache-2.0 - */ - -import React, { useContext } from 'react'; -import { useState } from 'react'; -import { useEffect } from 'react'; -import { useParams } from 'react-router-dom'; -import { LogTypeItem } from '../../../../types'; -import { - EuiDescriptionList, - EuiFlexGroup, - EuiFlexItem, - EuiLoadingSpinner, - EuiPanel, - EuiSpacer, - EuiTab, - EuiTabs, - EuiTitle, -} from '@elastic/eui'; -import { DataStore } from '../../../store/DataStore'; -import { CoreServicesContext } from '../../../components/core_services'; -import { BREADCRUMBS } from '../../../utils/constants'; -import { logTypeDetailsTabs } from '../utils/constants'; -import { LogTypeDetailsTab } from '../components/LogTypeDetailsTab'; - -export interface LogTypeDetailsProps {} - -export const LogTypeDetails: React.FC = () => { - const context = useContext(CoreServicesContext); - const { logTypeId } = useParams<{ logTypeId: string }>(); - const [selectedTabId, setSelectedTabId] = useState('details'); - const [infoText, setInfoText] = useState( - <> - Loading details   - - - ); - const [logTypeDetails, setLogTypeDetails] = useState(undefined); - const [initialLogTypeDetails, setInitialLogTypeDetails] = useState( - undefined - ); - - const [isEditMode, setIsEditMode] = useState(false); - - useEffect(() => { - const getLogTypeDetails = async () => { - const details = await DataStore.logTypes.getLogType(logTypeId); - - if (!details) { - setInfoText('Log type not found!'); - return; - } - - setInitialLogTypeDetails(details); - setLogTypeDetails(details); - }; - - context?.chrome.setBreadcrumbs([ - BREADCRUMBS.SECURITY_ANALYTICS, - BREADCRUMBS.DETECTORS, - BREADCRUMBS.LOG_TYPES, - { text: logTypeId }, - ]); - getLogTypeDetails(); - }, []); - - const renderTabContent = () => { - switch (selectedTabId) { - case 'detection_rules': - return null; - case 'details': - default: - return ( - - ); - } - }; - - return !logTypeDetails ? ( - -

{infoText}

-
- ) : ( - <> - -

{logTypeDetails.name}

-
- - - - - - - - - - - - - - - - - - - {logTypeDetailsTabs.map((tab, index) => { - return ( - { - setSelectedTabId(tab.id); - }} - key={index} - isSelected={selectedTabId === tab.id} - > - {tab.name} - - ); - })} - - {renderTabContent()} - - ); -}; diff --git a/public/pages/Rules/utils/helpers.tsx b/public/pages/Rules/utils/helpers.tsx index a88fc8968..4fb8bdfa4 100644 --- a/public/pages/Rules/utils/helpers.tsx +++ b/public/pages/Rules/utils/helpers.tsx @@ -56,7 +56,8 @@ export const getRulesTableColumns = ( width: '10%', truncateText: true, render: (category: string) => - ruleTypes.find((ruleType) => ruleType.value === category)?.label || DEFAULT_EMPTY_DATA, + ruleTypes.find((ruleType) => ruleType.label.toLowerCase() === category)?.label || + DEFAULT_EMPTY_DATA, }, { field: 'source', diff --git a/public/services/LogTypeService.ts b/public/services/LogTypeService.ts index 7ab3213f4..f7be5fee2 100644 --- a/public/services/LogTypeService.ts +++ b/public/services/LogTypeService.ts @@ -28,8 +28,22 @@ export default class LogTypeService { searchLogTypes = async (id?: string): Promise> => { const url = `..${API.LOGTYPE_BASE}/_search`; - const query = id ? JSON.stringify({ terms: { _id: [id] } }) : undefined; - return (await this.httpClient.post(url, { body: query })) as ServerResponse< + const query = id + ? { + terms: { _id: [id] }, + } + : { + bool: { + must: { + query_string: { + query: + '(source: Sigma and !(name: others*) and !(name: test*)) or (source: Custom)', + }, + }, + }, + }; + const queryString = JSON.stringify(query); + return (await this.httpClient.post(url, { body: queryString })) as ServerResponse< SearchLogTypesResponse >; }; diff --git a/public/store/LogTypeStore.ts b/public/store/LogTypeStore.ts index f33434925..a3538916c 100644 --- a/public/store/LogTypeStore.ts +++ b/public/store/LogTypeStore.ts @@ -4,7 +4,7 @@ */ import { NotificationsStart } from 'opensearch-dashboards/public'; -import { LogType, LogTypeBase, LogTypeItem } from '../../types'; +import { LogType, LogTypeBase, LogTypeWithRules, RuleItemInfoBase } from '../../types'; import LogTypeService from '../services/LogTypeService'; import { errorNotificationToast } from '../utils/helpers'; import { DataStore } from './DataStore'; @@ -13,7 +13,7 @@ import { ruleTypes } from '../pages/Rules/utils/constants'; export class LogTypeStore { constructor(private service: LogTypeService, private notifications: NotificationsStart) {} - public async getLogType(id: string): Promise { + public async getLogType(id: string): Promise { const logTypesRes = await this.service.searchLogTypes(id); if (logTypesRes.ok) { const logTypes: LogType[] = logTypesRes.response.hits.hits.map((hit) => { @@ -23,11 +23,16 @@ export class LogTypeStore { }; }); - const rulesRes = await DataStore.rules.getAllRules({ - 'rule.category': [id], - }); + let detectionRules: RuleItemInfoBase[] = []; + + if (logTypes[0]) { + const logTypeName = logTypes[0].name.toLowerCase(); + detectionRules = await DataStore.rules.getAllRules({ + 'rule.category': [logTypeName], + }); + } - return { ...logTypes[0], detectionRules: rulesRes.length }; + return { ...logTypes[0], detectionRules }; } return undefined; diff --git a/public/store/RulesStore.ts b/public/store/RulesStore.ts index edb392877..0678ee196 100644 --- a/public/store/RulesStore.ts +++ b/public/store/RulesStore.ts @@ -112,8 +112,10 @@ export class RulesStore implements IRulesStore { if (!terms) { terms = { - 'rule.category': _.map(ruleTypes, 'value'), + 'rule.category': ruleTypes.map(({ label }) => label.toLowerCase()), }; + } else if (terms['rule.category']) { + terms['rule.category'] = terms['rule.category'].map((category) => category.toLowerCase()); } const body = { diff --git a/public/utils/helpers.tsx b/public/utils/helpers.tsx index 294a22d9e..4e9e11d25 100644 --- a/public/utils/helpers.tsx +++ b/public/utils/helpers.tsx @@ -296,8 +296,8 @@ export const getPlugins = async (opensearchService: OpenSearchService) => { export const formatRuleType = (matchingRuleType: string) => { return ( - ruleTypes.find((ruleType) => ruleType.value === matchingRuleType.toLowerCase())?.label || - DEFAULT_EMPTY_DATA + ruleTypes.find((ruleType) => ruleType.label.toLowerCase() === matchingRuleType.toLowerCase()) + ?.label || DEFAULT_EMPTY_DATA ); }; diff --git a/types/LogTypes.ts b/types/LogTypes.ts index 229c36b19..c831bbe08 100644 --- a/types/LogTypes.ts +++ b/types/LogTypes.ts @@ -3,8 +3,14 @@ * SPDX-License-Identifier: Apache-2.0 */ +import { RuleItemInfoBase } from './Rule'; + +export interface LogTypeWithRules extends LogType { + detectionRules: RuleItemInfoBase[]; +} + export interface LogTypeItem extends LogType { - detectionRules: number; + detectionRulesCount: number; } export interface LogType extends LogTypeBase {