From b1d683d768fce1bfbcc9b40280e3bd03ce90820b Mon Sep 17 00:00:00 2001 From: Luciano Gorza Date: Tue, 21 May 2024 14:02:20 -0300 Subject: [PATCH 1/6] Fix events flyout and improve events columns --- .../common/wazuh-discover/wz-discover.tsx | 104 +++++++++++++----- .../mitre/events/mitre-attack-columns.tsx | 66 +---------- .../office/events/office-365-columns.tsx | 16 +-- .../events/threat-hunting-columns.tsx | 98 +---------------- 4 files changed, 85 insertions(+), 199 deletions(-) diff --git a/plugins/main/public/components/common/wazuh-discover/wz-discover.tsx b/plugins/main/public/components/common/wazuh-discover/wz-discover.tsx index 11855a2cee..6ee9980529 100644 --- a/plugins/main/public/components/common/wazuh-discover/wz-discover.tsx +++ b/plugins/main/public/components/common/wazuh-discover/wz-discover.tsx @@ -44,10 +44,29 @@ import { } from '../data-source'; import DiscoverDataGridAdditionalControls from './components/data-grid-additional-controls'; import { RedirectAppLinks } from '../../../../../../src/plugins/opensearch_dashboards_react/public'; -import { endpointSummary } from '../../../utils/applications'; +import { endpointSummary, mitreAttack, rules } from '../../../utils/applications'; +import _ from 'lodash'; +import { AppNavigate, formatUIDate } from '../../../react-services'; export const MAX_ENTRIES_PER_QUERY = 10000; +const navigateTo = (ev, section, params) => { + AppNavigate.navigateToModule(ev, section, params); +}; + +const renderMitreTechnique = (technique: string) => + navigateTo(e, 'overview', { + tab: 'mitre', + tabView: 'intelligence', + tabRedirect: 'techniques', + idToRedirect: technique, + }) + } +> + {technique} + + export type WazuhDiscoverProps = { tableColumns: tDataGridColumn[]; DataSource: IDataSourceFactoryConstructor; @@ -61,7 +80,7 @@ const WazuhDiscoverComponent = (props: WazuhDiscoverProps) => { } const SearchBar = getPlugins().data.ui.SearchBar; - const [results, setResults] = useState({} as SearchResponse); + const [results, setResults] = useState<{ raw: SearchResponse, withRender: SearchResponse }>({ raw: {}, withRender: {} }); const [inspectedHit, setInspectedHit] = useState(undefined); const [indexPattern, setIndexPattern] = useState( undefined, @@ -83,12 +102,13 @@ const WazuhDiscoverComponent = (props: WazuhDiscoverProps) => { const onClickInspectDoc = useMemo( () => (index: number) => { - const rowClicked = results.hits.hits[index]; + const rowClicked = results.raw.hits.hits[index]; setInspectedHit(rowClicked); }, [results], ); + const DocViewInspectButton = ({ rowIndex, }: EuiDataGridCellValueElementProps) => { @@ -114,7 +134,7 @@ const WazuhDiscoverComponent = (props: WazuhDiscoverProps) => { const dataGridProps = useDataGrid({ ariaLabelledBy: 'Discover events table', defaultColumns: defaultTableColumns, - results, + results: results.withRender, indexPattern: indexPattern as IndexPattern, DocViewInspectButton, pagination: { @@ -137,33 +157,61 @@ const WazuhDiscoverComponent = (props: WazuhDiscoverProps) => { sorting, dateRange: { from: dateRangeFrom || '', to: dateRangeTo || '' }, }) - .then(results => { - results?.hits?.hits.map(value => { - const agentId = value._source.agent.id; - const agentName = value._source.agent.name; - if (agentId === '000') { - return value; - } - value._source.agent.name = ( - + .then(rawResults => { + const hitsWithRender = rawResults?.hits?.hits.map(value => { + const { agent, rule, timestamp } = value._source; + const newValue = _.cloneDeep(value) + + if (agent.id !== '000') { + _.set(newValue, '_source.agent.id', - {agentName} + {agent.id} - - ); - value._source.agent.id = ( - + ); + _.set(newValue, '_source.agent.name', - {agentId} + {agent.name} - - ); - return value; + ) + } + + if (rule?.id) { + _.set(newValue, '_source.rule.id', + + {rule.id} + + ) + } + + if (rule?.mitre?.id) { + _.set(newValue, '_source.rule.mitre.id', Array.isArray(rule.mitre.id) ?
+ {rule.mitre.id?.map(technique => ( +
+ {renderMitreTechnique(technique)} +
+ ))} +
:
+ {renderMitreTechnique(rule.mitre.id)} +
) + } + + if (timestamp) { + _.set(newValue, '_source.timestamp', formatUIDate(timestamp)) + } + + return newValue }); + + const withRenderResults = _.set(_.cloneDeep(rawResults), 'hits.hits', hitsWithRender) + + const results = { + raw: rawResults, + withRender: withRenderResults + } setResults(results); }) .catch(error => { @@ -194,7 +242,7 @@ const WazuhDiscoverComponent = (props: WazuhDiscoverProps) => { fields: columnVisibility.visibleColumns, pagination: { pageIndex: 0, - pageSize: results.hits.total, + pageSize: results.raw.hits.total, }, sorting, }; @@ -234,10 +282,10 @@ const WazuhDiscoverComponent = (props: WazuhDiscoverProps) => { /> )} - {!isDataSourceLoading && results?.hits?.total === 0 ? ( + {!isDataSourceLoading && results?.raw?.hits?.total === 0 ? ( ) : null} - {!isDataSourceLoading && dataSource && results?.hits?.total > 0 ? ( + {!isDataSourceLoading && dataSource && results?.raw?.hits?.total > 0 ? ( <> { additionalControls: ( <> { - AppNavigate.navigateToModule(ev, section, params); -}; - -const renderTechniques = (value: []) => { - return ( -
- {value.length && - value.map(technique => ( -
- - navigateTo(e, 'overview', { - tab: 'mitre', - tabView: 'intelligence', - tabRedirect: 'techniques', - idToRedirect: technique, - }) - } - > - {technique} - -
- ))} -
- ); -}; export const mitreAttackColumns: tDataGridColumn[] = [ { id: 'timestamp', displayAsText: 'Time', - render: value => formatUIDate(value), - }, - { - id: 'agent.name', - displayAsText: 'Agent Name', - render: (value: string, item: any) => { - return ( - - navigateTo(e, 'agents', { tab: 'welcome', agent: item.agent.id }) - } - > - {value} - - ); - }, }, + { id: 'agent.name', displayAsText: 'Agent Name' }, { id: 'rule.mitre.id', displayAsText: 'Technique(s)', - render: value => renderTechniques(value), }, { id: 'rule.mitre.tactic', displayAsText: 'Tactic(s)' }, { id: 'rule.description', displayAsText: 'Description' }, { id: 'rule.level', displayAsText: 'Level' }, - { - id: 'rule.id', - displayAsText: 'Rule ID', - render: value => ( - - - {value} - - - ), - }, + { id: 'rule.id', displayAsText: 'Rule ID' }, ]; diff --git a/plugins/main/public/components/overview/office/events/office-365-columns.tsx b/plugins/main/public/components/overview/office/events/office-365-columns.tsx index 4fb1d2d511..06b16fb40d 100644 --- a/plugins/main/public/components/overview/office/events/office-365-columns.tsx +++ b/plugins/main/public/components/overview/office/events/office-365-columns.tsx @@ -1,9 +1,4 @@ -import React from 'react'; import { tDataGridColumn } from '../../../common/data-grid'; -import { EuiLink } from '@elastic/eui'; -import { RedirectAppLinks } from '../../../../../../../src/plugins/opensearch_dashboards_react/public'; -import { getCore } from '../../../../kibana-services'; -import { rules } from '../../../../utils/applications'; export const office365Columns: tDataGridColumn[] = [ { @@ -22,15 +17,6 @@ export const office365Columns: tDataGridColumn[] = [ id: 'rule.level', }, { - id: 'rule.id', - render: value => ( - - - {value} - - - ), + id: 'rule.id' }, ]; diff --git a/plugins/main/public/components/overview/threat-hunting/events/threat-hunting-columns.tsx b/plugins/main/public/components/overview/threat-hunting/events/threat-hunting-columns.tsx index 1cd9200b71..87bda4ea92 100644 --- a/plugins/main/public/components/overview/threat-hunting/events/threat-hunting-columns.tsx +++ b/plugins/main/public/components/overview/threat-hunting/events/threat-hunting-columns.tsx @@ -1,13 +1,5 @@ -import { EuiDataGridColumn, EuiLink } from '@elastic/eui'; +import { EuiDataGridColumn } from '@elastic/eui'; import { tDataGridColumn } from '../../../common/data-grid'; -import { getCore } from '../../../../kibana-services'; -import React from 'react'; -import { RedirectAppLinks } from '../../../../../../../src/plugins/opensearch_dashboards_react/public'; -import { - endpointSummary, - mitreAttack, - rules, -} from '../../../../utils/applications'; export const MAX_ENTRIES_PER_QUERY = 10000; @@ -19,55 +11,13 @@ export const threatHuntingTableDefaultColumns: tDataGridColumn[] = [ id: 'timestamp', }, { - id: 'agent.id', - render: (value: any) => { - if (value === '000') { - return value; - } - const destURL = getCore().application.getUrlForApp(endpointSummary.id, { - path: `#/agents?tab=welcome&agent=${value}`, - }); - return ( - - - {value} - - - ); - }, - }, - { - id: 'agent.name', - render: (value: any, _source) => { - if (_source.agent.id === '000') { - return value; - } - const destURL = getCore().application.getUrlForApp(endpointSummary.id, { - path: `#/agents?tab=welcome&agent=${_source.agent.id}`, - }); - return ( - - - {value} - - - ); - }, + id: 'agent.id' + }, + { + id: 'agent.name' }, { id: 'rule.mitre.id', - render: (value: any) => { - const destURL = getCore().application.getUrlForApp(mitreAttack.id, { - path: `#/overview/?tab=mitre&tabView=intelligence&tabRedirect=techniques&idToRedirect=${value}`, - }); - return ( - - - {value} - - - ); - }, }, { id: 'rule.mitre.tactic', @@ -79,19 +29,7 @@ export const threatHuntingTableDefaultColumns: tDataGridColumn[] = [ id: 'rule.level', }, { - id: 'rule.id', - render: (value: any) => { - const destURL = getCore().application.getUrlForApp(rules.id, { - path: `manager/?tab=ruleset&redirectRule=${value}`, - }); - return ( - - - {value} - - - ); - }, + id: 'rule.id' }, ]; @@ -104,18 +42,6 @@ export const threatHuntingTableAgentColumns: EuiDataGridColumn[] = [ }, { id: 'rule.mitre.id', - render: (value: any) => { - const destURL = getCore().application.getUrlForApp(mitreAttack.id, { - path: `#/overview/?tab=mitre&tabView=intelligence&tabRedirect=techniques&idToRedirect=${value}`, - }); - return ( - - - {value} - - - ); - }, }, { id: 'rule.mitre.tactic', @@ -128,17 +54,5 @@ export const threatHuntingTableAgentColumns: EuiDataGridColumn[] = [ }, { id: 'rule.id', - render: (value: any) => { - const destURL = getCore().application.getUrlForApp(rules.id, { - path: `manager/?tab=ruleset&redirectRule=${value}`, - }); - return ( - - - {value} - - - ); - }, }, ]; From b4e044cfcc057965006f9fa086cf6069cb1921b9 Mon Sep 17 00:00:00 2001 From: Luciano Gorza Date: Tue, 21 May 2024 14:07:38 -0300 Subject: [PATCH 2/6] Update CHANGELOG --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7cc0bb77e4..162cce0009 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,7 +21,7 @@ All notable changes to the Wazuh app project will be documented in this file. ### Changed -- Removed embedded discover [#6120](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6120) [#6235](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6235) [#6254](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6254) [#6285](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6285) [#6288](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6288) [#6290](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6290) [#6289](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6289) [#6286](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6286) [#6275](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6275) [#6287](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6287) [#6297](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6297) [#6291](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6287) [#6459](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6459) [#6434](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6434) [#6504](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6504) [#6649](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6649) [#6506](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6506) [#6537](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6537) [#6528](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6528) [#6675](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6675) [#6674](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6674) [#6558](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6558) +- Removed embedded discover [#6120](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6120) [#6235](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6235) [#6254](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6254) [#6285](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6285) [#6288](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6288) [#6290](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6290) [#6289](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6289) [#6286](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6286) [#6275](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6275) [#6287](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6287) [#6297](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6297) [#6291](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6287) [#6459](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6459) [#6434](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6434) [#6504](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6504) [#6649](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6649) [#6506](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6506) [#6537](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6537) [#6528](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6528) [#6675](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6675) [#6674](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6674) [#6558](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6558) [#6691](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6691) - Develop logic of a new index for the fim module [#6227](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6227) - Allow editing groups for an agent from Endpoints Summary [#6250](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6250) - Change how the configuration is managed in the backend side [#6337](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6337) [#6519](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6519) [#6573](https://github.com/wazuh/wazuh-dashboard-plugins/pull/6573) From 5fc6d0427c3867d24372f6b519d711ecaf168b73 Mon Sep 17 00:00:00 2001 From: Luciano Gorza Date: Tue, 21 May 2024 15:19:03 -0300 Subject: [PATCH 3/6] Update snapshot --- .../__snapshots__/inventory.test.tsx.snap | 54 +++++++------------ 1 file changed, 19 insertions(+), 35 deletions(-) diff --git a/plugins/main/public/components/agents/syscollector/__snapshots__/inventory.test.tsx.snap b/plugins/main/public/components/agents/syscollector/__snapshots__/inventory.test.tsx.snap index df26ef4255..d048bbcd49 100644 --- a/plugins/main/public/components/agents/syscollector/__snapshots__/inventory.test.tsx.snap +++ b/plugins/main/public/components/agents/syscollector/__snapshots__/inventory.test.tsx.snap @@ -2,18 +2,16 @@ exports[`Inventory component A Apple agent should be well rendered. 1`] = `
Date: Wed, 22 May 2024 13:30:11 -0300 Subject: [PATCH 4/6] Improve discover column renderers --- .../common/data-grid/use-data-grid.ts | 23 +++- .../common/wazuh-discover/wz-discover.tsx | 130 +++++++++--------- 2 files changed, 81 insertions(+), 72 deletions(-) diff --git a/plugins/main/public/components/common/data-grid/use-data-grid.ts b/plugins/main/public/components/common/data-grid/use-data-grid.ts index 62c54c6dcd..ab0235bedf 100644 --- a/plugins/main/public/components/common/data-grid/use-data-grid.ts +++ b/plugins/main/public/components/common/data-grid/use-data-grid.ts @@ -4,7 +4,6 @@ import { EuiDataGridProps, EuiDataGridSorting, } from '@elastic/eui'; -import dompurify from 'dompurify'; import React, { useEffect, useMemo, useState, Fragment } from 'react'; import { SearchResponse } from '@opensearch-project/opensearch/api/types'; // ToDo: check how create this methods @@ -19,16 +18,17 @@ const MAX_ENTRIES_PER_QUERY = 10000; const DEFAULT_PAGE_SIZE_OPTIONS = [20, 50, 100]; export type tDataGridColumn = { - render?: ( - value: any, - rowItem: object - ) => string | React.ReactNode; + render?: (value: any, rowItem: object) => string | React.ReactNode; } & EuiDataGridColumn; +export type tDataGridRenderColumn = Required> & + Omit; + export type tDataGridProps = { indexPattern: IndexPattern; results: SearchResponse; defaultColumns: tDataGridColumn[]; + renderColumns?: tDataGridRenderColumn[]; DocViewInspectButton: ({ rowIndex, }: EuiDataGridCellValueElementProps) => React.JSX.Element; @@ -42,6 +42,7 @@ export const useDataGrid = (props: tDataGridProps): EuiDataGridProps => { DocViewInspectButton, results, defaultColumns, + renderColumns, pagination: defaultPagination, } = props; /** Columns **/ @@ -115,11 +116,19 @@ export const useDataGrid = (props: tDataGridProps): EuiDataGridProps => { // check if column have render method initialized const column = columns.find(column => column.id === columnId); if (column && column.render) { - return column.render( + return column.render(fieldFormatted, rowsParsed[relativeRowIndex]); + } + // check if column have render method in renderColumns prop + const renderColumn = renderColumns?.find( + column => column.id === columnId, + ); + if (renderColumn) { + return renderColumn.render( fieldFormatted, - rowsParsed[relativeRowIndex] + rowsParsed[relativeRowIndex], ); } + return fieldFormatted; } return null; diff --git a/plugins/main/public/components/common/wazuh-discover/wz-discover.tsx b/plugins/main/public/components/common/wazuh-discover/wz-discover.tsx index 6ee9980529..9934653b84 100644 --- a/plugins/main/public/components/common/wazuh-discover/wz-discover.tsx +++ b/plugins/main/public/components/common/wazuh-discover/wz-discover.tsx @@ -44,7 +44,7 @@ import { } from '../data-source'; import DiscoverDataGridAdditionalControls from './components/data-grid-additional-controls'; import { RedirectAppLinks } from '../../../../../../src/plugins/opensearch_dashboards_react/public'; -import { endpointSummary, mitreAttack, rules } from '../../../utils/applications'; +import { endpointSummary, rules } from '../../../utils/applications'; import _ from 'lodash'; import { AppNavigate, formatUIDate } from '../../../react-services'; @@ -80,7 +80,7 @@ const WazuhDiscoverComponent = (props: WazuhDiscoverProps) => { } const SearchBar = getPlugins().data.ui.SearchBar; - const [results, setResults] = useState<{ raw: SearchResponse, withRender: SearchResponse }>({ raw: {}, withRender: {} }); + const [results, setResults] = useState({} as SearchResponse); const [inspectedHit, setInspectedHit] = useState(undefined); const [indexPattern, setIndexPattern] = useState( undefined, @@ -102,7 +102,7 @@ const WazuhDiscoverComponent = (props: WazuhDiscoverProps) => { const onClickInspectDoc = useMemo( () => (index: number) => { - const rowClicked = results.raw.hits.hits[index]; + const rowClicked = results.hits.hits[index]; setInspectedHit(rowClicked); }, [results], @@ -131,10 +131,66 @@ const WazuhDiscoverComponent = (props: WazuhDiscoverProps) => { }); const { query, dateRangeFrom, dateRangeTo } = searchBarProps; + const renderColumns = [ + { + id: 'agent.id', + render: (value) => { + if (value === '000') return value + + return + + {value} + + + } + }, + { + id: 'agent.name', + render: (value, row) => { + if (row.agent.id === '000') return value + + return + + {value} + + + } + }, + { + id: 'rule.id', + render: (value) => + + {value} + + + }, + { + id: 'rule.mitre.id', + render: (value) => Array.isArray(value) ?
+ {value?.map(technique => ( +
+ {renderMitreTechnique(technique)} +
+ ))} +
:
+ {renderMitreTechnique(value)} +
+ }, + { + id: 'timestamp', + render: (value) => formatUIDate(value) + }, + ] + const dataGridProps = useDataGrid({ ariaLabelledBy: 'Discover events table', defaultColumns: defaultTableColumns, - results: results.withRender, + renderColumns, + results, indexPattern: indexPattern as IndexPattern, DocViewInspectButton, pagination: { @@ -157,63 +213,7 @@ const WazuhDiscoverComponent = (props: WazuhDiscoverProps) => { sorting, dateRange: { from: dateRangeFrom || '', to: dateRangeTo || '' }, }) - .then(rawResults => { - const hitsWithRender = rawResults?.hits?.hits.map(value => { - const { agent, rule, timestamp } = value._source; - const newValue = _.cloneDeep(value) - - if (agent.id !== '000') { - _.set(newValue, '_source.agent.id', - - {agent.id} - - ); - _.set(newValue, '_source.agent.name', - - {agent.name} - - ) - } - - if (rule?.id) { - _.set(newValue, '_source.rule.id', - - {rule.id} - - ) - } - - if (rule?.mitre?.id) { - _.set(newValue, '_source.rule.mitre.id', Array.isArray(rule.mitre.id) ?
- {rule.mitre.id?.map(technique => ( -
- {renderMitreTechnique(technique)} -
- ))} -
:
- {renderMitreTechnique(rule.mitre.id)} -
) - } - - if (timestamp) { - _.set(newValue, '_source.timestamp', formatUIDate(timestamp)) - } - - return newValue - }); - - const withRenderResults = _.set(_.cloneDeep(rawResults), 'hits.hits', hitsWithRender) - - const results = { - raw: rawResults, - withRender: withRenderResults - } - setResults(results); - }) + .then(results => setResults(results)) .catch(error => { const searchError = ErrorFactory.create(HttpError, { error, @@ -242,7 +242,7 @@ const WazuhDiscoverComponent = (props: WazuhDiscoverProps) => { fields: columnVisibility.visibleColumns, pagination: { pageIndex: 0, - pageSize: results.raw.hits.total, + pageSize: results.hits.total, }, sorting, }; @@ -282,10 +282,10 @@ const WazuhDiscoverComponent = (props: WazuhDiscoverProps) => { />
)} - {!isDataSourceLoading && results?.raw?.hits?.total === 0 ? ( + {!isDataSourceLoading && results?.hits?.total === 0 ? ( ) : null} - {!isDataSourceLoading && dataSource && results?.raw?.hits?.total > 0 ? ( + {!isDataSourceLoading && dataSource && results?.hits?.total > 0 ? ( <> { additionalControls: ( <> Date: Wed, 22 May 2024 14:18:11 -0300 Subject: [PATCH 5/6] Remove mitre attack columns displayAsText --- .../mitre/events/mitre-attack-columns.tsx | 20 +++++++------------ 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/plugins/main/public/components/overview/mitre/events/mitre-attack-columns.tsx b/plugins/main/public/components/overview/mitre/events/mitre-attack-columns.tsx index 954f353725..a080f31044 100644 --- a/plugins/main/public/components/overview/mitre/events/mitre-attack-columns.tsx +++ b/plugins/main/public/components/overview/mitre/events/mitre-attack-columns.tsx @@ -1,17 +1,11 @@ import { tDataGridColumn } from '../../../common/data-grid'; export const mitreAttackColumns: tDataGridColumn[] = [ - { - id: 'timestamp', - displayAsText: 'Time', - }, - { id: 'agent.name', displayAsText: 'Agent Name' }, - { - id: 'rule.mitre.id', - displayAsText: 'Technique(s)', - }, - { id: 'rule.mitre.tactic', displayAsText: 'Tactic(s)' }, - { id: 'rule.description', displayAsText: 'Description' }, - { id: 'rule.level', displayAsText: 'Level' }, - { id: 'rule.id', displayAsText: 'Rule ID' }, + { id: 'timestamp' }, + { id: 'agent.name' }, + { id: 'rule.mitre.id' }, + { id: 'rule.mitre.tactic' }, + { id: 'rule.description' }, + { id: 'rule.level' }, + { id: 'rule.id' }, ]; From 899173a1d6cd491c292370fcdedbfdfdb61d940e Mon Sep 17 00:00:00 2001 From: Luciano Gorza Date: Wed, 22 May 2024 16:47:47 -0300 Subject: [PATCH 6/6] Modularize renderColumns for Discover --- .../common/wazuh-discover/render-columns.tsx | 81 ++++++++++++++++++ .../common/wazuh-discover/wz-discover.tsx | 82 +------------------ .../threat-hunting/dashboard/dashboard.tsx | 20 +++-- 3 files changed, 95 insertions(+), 88 deletions(-) create mode 100644 plugins/main/public/components/common/wazuh-discover/render-columns.tsx diff --git a/plugins/main/public/components/common/wazuh-discover/render-columns.tsx b/plugins/main/public/components/common/wazuh-discover/render-columns.tsx new file mode 100644 index 0000000000..483b056a85 --- /dev/null +++ b/plugins/main/public/components/common/wazuh-discover/render-columns.tsx @@ -0,0 +1,81 @@ +import React from 'react'; +import { EuiLink } from '@elastic/eui'; +import { tDataGridRenderColumn } from '../data-grid'; +import { getCore } from '../../../kibana-services'; +import { RedirectAppLinks } from '../../../../../../src/plugins/opensearch_dashboards_react/public'; +import { endpointSummary, rules } from '../../../utils/applications'; +import { AppNavigate, formatUIDate } from '../../../react-services'; + +export const MAX_ENTRIES_PER_QUERY = 10000; + +const navigateTo = (ev, section, params) => { + AppNavigate.navigateToModule(ev, section, params); +}; + +const renderMitreTechnique = (technique: string) => + navigateTo(e, 'overview', { + tab: 'mitre', + tabView: 'intelligence', + tabRedirect: 'techniques', + idToRedirect: technique, + }) + } +> + {technique} + + +export const wzDiscoverRenderColumns: tDataGridRenderColumn[] = [ + { + id: 'agent.id', + render: (value) => { + if (value === '000') return value + + return + + {value} + + + } + }, + { + id: 'agent.name', + render: (value, row) => { + if (row.agent.id === '000') return value + + return + + {value} + + + } + }, + { + id: 'rule.id', + render: (value) => + + {value} + + + }, + { + id: 'rule.mitre.id', + render: (value) => Array.isArray(value) ?
+ {value?.map(technique => ( +
+ {renderMitreTechnique(technique)} +
+ ))} +
:
+ {renderMitreTechnique(value)} +
+ }, + { + id: 'timestamp', + render: (value) => formatUIDate(value) + }, +] \ No newline at end of file diff --git a/plugins/main/public/components/common/wazuh-discover/wz-discover.tsx b/plugins/main/public/components/common/wazuh-discover/wz-discover.tsx index 9934653b84..90f68d923c 100644 --- a/plugins/main/public/components/common/wazuh-discover/wz-discover.tsx +++ b/plugins/main/public/components/common/wazuh-discover/wz-discover.tsx @@ -13,7 +13,6 @@ import { EuiTitle, EuiSpacer, EuiPanel, - EuiLink, } from '@elastic/eui'; import { IntlProvider } from 'react-intl'; import { IndexPattern } from '../../../../../../src/plugins/data/common'; @@ -28,7 +27,7 @@ import { HttpError, } from '../../../react-services/error-management'; import useSearchBar from '../search-bar/use-search-bar'; -import { getCore, getPlugins } from '../../../kibana-services'; +import { getPlugins } from '../../../kibana-services'; import { histogramChartInput } from './config/histogram-chart'; import { getWazuhCorePlugin } from '../../../kibana-services'; const DashboardByRenderer = @@ -43,30 +42,10 @@ import { AlertsDataSourceRepository, } from '../data-source'; import DiscoverDataGridAdditionalControls from './components/data-grid-additional-controls'; -import { RedirectAppLinks } from '../../../../../../src/plugins/opensearch_dashboards_react/public'; -import { endpointSummary, rules } from '../../../utils/applications'; -import _ from 'lodash'; -import { AppNavigate, formatUIDate } from '../../../react-services'; +import { wzDiscoverRenderColumns } from './render-columns'; export const MAX_ENTRIES_PER_QUERY = 10000; -const navigateTo = (ev, section, params) => { - AppNavigate.navigateToModule(ev, section, params); -}; - -const renderMitreTechnique = (technique: string) => - navigateTo(e, 'overview', { - tab: 'mitre', - tabView: 'intelligence', - tabRedirect: 'techniques', - idToRedirect: technique, - }) - } -> - {technique} - - export type WazuhDiscoverProps = { tableColumns: tDataGridColumn[]; DataSource: IDataSourceFactoryConstructor; @@ -131,65 +110,10 @@ const WazuhDiscoverComponent = (props: WazuhDiscoverProps) => { }); const { query, dateRangeFrom, dateRangeTo } = searchBarProps; - const renderColumns = [ - { - id: 'agent.id', - render: (value) => { - if (value === '000') return value - - return - - {value} - - - } - }, - { - id: 'agent.name', - render: (value, row) => { - if (row.agent.id === '000') return value - - return - - {value} - - - } - }, - { - id: 'rule.id', - render: (value) => - - {value} - - - }, - { - id: 'rule.mitre.id', - render: (value) => Array.isArray(value) ?
- {value?.map(technique => ( -
- {renderMitreTechnique(technique)} -
- ))} -
:
- {renderMitreTechnique(value)} -
- }, - { - id: 'timestamp', - render: (value) => formatUIDate(value) - }, - ] - const dataGridProps = useDataGrid({ ariaLabelledBy: 'Discover events table', defaultColumns: defaultTableColumns, - renderColumns, + renderColumns: wzDiscoverRenderColumns, results, indexPattern: indexPattern as IndexPattern, DocViewInspectButton, diff --git a/plugins/main/public/components/overview/threat-hunting/dashboard/dashboard.tsx b/plugins/main/public/components/overview/threat-hunting/dashboard/dashboard.tsx index 76f326e29b..66c2b6b888 100644 --- a/plugins/main/public/components/overview/threat-hunting/dashboard/dashboard.tsx +++ b/plugins/main/public/components/overview/threat-hunting/dashboard/dashboard.tsx @@ -52,6 +52,7 @@ import { import { DiscoverNoResults } from '../../../common/no-results/no-results'; import { LoadingSpinner } from '../../../common/loading-spinner/loading-spinner'; import { useReportingCommunicateSearchContext } from '../../../common/hooks/use-reporting-communicate-search-context'; +import { wzDiscoverRenderColumns } from '../../../common/wazuh-discover/render-columns'; const plugins = getPlugins(); @@ -112,6 +113,7 @@ const DashboardTH: React.FC = () => { const dataGridProps = useDataGrid({ ariaLabelledBy: 'Threat Hunting Table', defaultColumns: threatHuntingTableDefaultColumns, + renderColumns: wzDiscoverRenderColumns, results, indexPattern: dataSource?.indexPattern, DocViewInspectButton, @@ -282,18 +284,18 @@ const DashboardTH: React.FC = () => { {}} + onResetQuery={() => { }} tooltip={ results?.hits?.total && - results?.hits?.total > MAX_ENTRIES_PER_QUERY + results?.hits?.total > MAX_ENTRIES_PER_QUERY ? { - ariaLabel: 'Warning', - content: `The query results has exceeded the limit of 10,000 hits. To provide a better experience the table only shows the first ${formatNumWithCommas( - MAX_ENTRIES_PER_QUERY, - )} hits.`, - iconType: 'alert', - position: 'top', - } + ariaLabel: 'Warning', + content: `The query results has exceeded the limit of 10,000 hits. To provide a better experience the table only shows the first ${formatNumWithCommas( + MAX_ENTRIES_PER_QUERY, + )} hits.`, + iconType: 'alert', + position: 'top', + } : undefined } />