Skip to content

Commit

Permalink
[SIEM] Detections add alert & signal tab (#55127)
Browse files Browse the repository at this point in the history
* add alert on detections

* review I + fix unit test

* review II

* review III

* review IV + bug fixes found during review

* review VI
  • Loading branch information
XavierM committed Jan 18, 2020
1 parent c1ccb30 commit 6760c33
Show file tree
Hide file tree
Showing 26 changed files with 240 additions and 141 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ import { MatrixHistogramGqlQuery } from '../../containers/matrix_histogram/index
const ID = 'alertsOverTimeQuery';
export const alertsStackByOptions: MatrixHistogramOption[] = [
{
text: i18n.CATEGORY,
text: 'event.category',
value: 'event.category',
},
{
text: i18n.MODULE,
text: 'event.module',
value: 'event.module',
},
];
Expand Down Expand Up @@ -54,7 +54,6 @@ export const AlertsView = ({
<>
<MatrixHistogramContainer
dataKey={dataKey}
deleteQuery={deleteQuery}
defaultStackByOption={alertsStackByOptions[1]}
endDate={endDate}
errorMessage={i18n.ERROR_FETCHING_ALERTS_DATA}
Expand All @@ -68,7 +67,7 @@ export const AlertsView = ({
stackByOptions={alertsStackByOptions}
startDate={startDate}
subtitle={getSubtitle}
title={i18n.ALERTS_DOCUMENT_TYPE}
title={i18n.ALERTS_GRAPH_TITLE}
type={type}
updateDateRange={updateDateRange}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,14 @@ export const TOTAL_COUNT_OF_ALERTS = i18n.translate('xpack.siem.alertsView.total
defaultMessage: 'alerts match the search criteria',
});

export const ALERTS_TABLE_TITLE = i18n.translate('xpack.siem.alertsView.alertsDocumentType', {
export const ALERTS_TABLE_TITLE = i18n.translate('xpack.siem.alertsView.alertsTableTitle', {
defaultMessage: 'Alerts',
});

export const ALERTS_GRAPH_TITLE = i18n.translate('xpack.siem.alertsView.alertsGraphTitle', {
defaultMessage: 'Alert detection frequency',
});

export const ALERTS_STACK_BY_MODULE = i18n.translate(
'xpack.siem.alertsView.alertsStackByOptions.module',
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { RedirectToHostsPage, RedirectToHostDetailsPage } from './redirect_to_ho
import { RedirectToNetworkPage } from './redirect_to_network';
import { RedirectToOverviewPage } from './redirect_to_overview';
import { RedirectToTimelinesPage } from './redirect_to_timelines';
import { DetectionEngineTab } from '../../pages/detection_engine/types';

interface LinkToPageProps {
match: RouteMatch<{}>;
Expand Down Expand Up @@ -63,6 +64,12 @@ export const LinkToPage = React.memo<LinkToPageProps>(({ match }) => (
path={`${match.url}/:pageName(${SiemPageName.detectionEngine})`}
strict
/>
<Route
component={RedirectToDetectionEnginePage}
exact
path={`${match.url}/:pageName(${SiemPageName.detectionEngine})/:tabName(${DetectionEngineTab.alerts}|${DetectionEngineTab.signals})`}
strict
/>
<Route
component={RedirectToRulesPage}
exact
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,28 @@
import React from 'react';
import { RouteComponentProps } from 'react-router-dom';

import { DetectionEngineTab } from '../../pages/detection_engine/types';
import { RedirectWrapper } from './redirect_wrapper';

export type DetectionEngineComponentProps = RouteComponentProps<{
tabName: DetectionEngineTab;
search: string;
}>;

export const DETECTION_ENGINE_PAGE_NAME = 'detection-engine';

export const RedirectToDetectionEnginePage = ({
match: {
params: { tabName },
},
location: { search },
}: DetectionEngineComponentProps) => (
<RedirectWrapper to={`/${DETECTION_ENGINE_PAGE_NAME}${search}`} />
);
}: DetectionEngineComponentProps) => {
const defaultSelectedTab = DetectionEngineTab.signals;
const selectedTab = tabName ? tabName : defaultSelectedTab;
const to = `/${DETECTION_ENGINE_PAGE_NAME}/${selectedTab}${search}`;

return <RedirectWrapper to={to} />;
};

export const RedirectToRulesPage = ({ location: { search } }: DetectionEngineComponentProps) => {
return <RedirectWrapper to={`/${DETECTION_ENGINE_PAGE_NAME}/rules${search}`} />;
Expand All @@ -28,7 +37,7 @@ export const RedirectToRulesPage = ({ location: { search } }: DetectionEngineCom
export const RedirectToCreateRulePage = ({
location: { search },
}: DetectionEngineComponentProps) => {
return <RedirectWrapper to={`/${DETECTION_ENGINE_PAGE_NAME}/rules/create-rule${search}`} />;
return <RedirectWrapper to={`/${DETECTION_ENGINE_PAGE_NAME}/rules/create${search}`} />;
};

export const RedirectToRuleDetailsPage = ({
Expand All @@ -44,6 +53,8 @@ export const RedirectToEditRulePage = ({ location: { search } }: DetectionEngine
};

export const getDetectionEngineUrl = () => `#/link-to/${DETECTION_ENGINE_PAGE_NAME}`;
export const getDetectionEngineAlertUrl = () =>
`#/link-to/${DETECTION_ENGINE_PAGE_NAME}/${DetectionEngineTab.alerts}`;
export const getRulesUrl = () => `#/link-to/${DETECTION_ENGINE_PAGE_NAME}/rules`;
export const getCreateRuleUrl = () => `#/link-to/${DETECTION_ENGINE_PAGE_NAME}/rules/create-rule`;
export const getRuleDetailsUrl = () => `#/link-to/${DETECTION_ENGINE_PAGE_NAME}/rules/rule-details`;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,12 @@ export const MatrixHistogramComponent: React.FC<MatrixHistogramProps &
isDnsHistogram,
isEventsHistogram,
isInspected,
legendPosition,
legendPosition = 'right',
mapping,
query,
scaleType = ScaleType.Time,
setQuery,
showLegend,
showLegend = true,
skip,
stackByOptions,
startDate,
Expand Down Expand Up @@ -151,6 +151,7 @@ export const MatrixHistogramComponent: React.FC<MatrixHistogramProps &
isInspected,
loading,
data,
refetch,
]);

return !hideHistogram ? (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,14 @@ export const AnomaliesQueryTabBody = ({
flowTarget,
ip,
}: AnomaliesQueryTabBodyProps) => {
useEffect(() => {
return () => {
if (deleteQuery) {
deleteQuery({ id: ID });
}
};
}, []);

const [, siemJobs] = useSiemJobs(true);
const [anomalyScore] = useUiSetting$<number>(DEFAULT_ANOMALY_SCORE);

Expand All @@ -51,21 +59,12 @@ export const AnomaliesQueryTabBody = ({
ip
);

useEffect(() => {
return () => {
if (deleteQuery) {
deleteQuery({ id: ID });
}
};
}, []);

return (
<>
<MatrixHistogramContainer
isAnomaliesHistogram={true}
dataKey="AnomaliesHistogram"
defaultStackByOption={anomaliesStackByOptions[0]}
deleteQuery={deleteQuery}
endDate={endDate}
errorMessage={i18n.ERROR_FETCHING_ANOMALIES_DATA}
filterQuery={mergedFilterQuery}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import { SetQuery } from '../../pages/hosts/navigation/types';
export interface OwnProps extends QueryTemplateProps {
dataKey: string | string[];
defaultStackByOption: MatrixHistogramOption;
deleteQuery?: ({ id }: { id: string }) => void;
errorMessage: string;
headerChildren?: React.ReactNode;
hideHistogramIfEmpty?: boolean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { getOr } from 'lodash/fp';
import { useEffect, useState } from 'react';
import { useEffect, useRef, useState } from 'react';
import {
MatrixHistogramDataTypes,
MatrixHistogramQueryProps,
Expand Down Expand Up @@ -35,7 +35,7 @@ export const useQuery = <Hit, Aggs, TCache = object>({
}: MatrixHistogramQueryProps) => {
const [defaultIndex] = useUiSetting$<string[]>(DEFAULT_INDEX_KEY);
const [, dispatchToaster] = useStateToaster();
const [refetch, setRefetch] = useState<inputsModel.Refetch>();
const refetch = useRef<inputsModel.Refetch>();
const [loading, setLoading] = useState<boolean>(false);
const [data, setData] = useState<MatrixHistogramDataTypes[] | null>(null);
const [inspect, setInspect] = useState<inputsModel.InspectQuery | null>(null);
Expand Down Expand Up @@ -71,7 +71,7 @@ export const useQuery = <Hit, Aggs, TCache = object>({
return apolloClient
.query<GetMatrixHistogramQuery.Query, GetMatrixHistogramQuery.Variables>({
query,
fetchPolicy: 'cache-first',
fetchPolicy: 'network-only',
variables: matrixHistogramVariables,
context: {
fetchOptions: {
Expand Down Expand Up @@ -103,9 +103,7 @@ export const useQuery = <Hit, Aggs, TCache = object>({
}
);
}
setRefetch(() => {
fetchData();
});
refetch.current = fetchData;
fetchData();
return () => {
isSubscribed = false;
Expand All @@ -122,5 +120,5 @@ export const useQuery = <Hit, Aggs, TCache = object>({
endDate,
]);

return { data, loading, inspect, totalCount, refetch };
return { data, loading, inspect, totalCount, refetch: refetch.current };
};
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export const PAGE_TITLE = i18n.translate('xpack.siem.detectionEngine.pageTitle',
});

export const SIGNALS_TABLE_TITLE = i18n.translate('xpack.siem.detectionEngine.signals.tableTitle', {
defaultMessage: 'All signals',
defaultMessage: 'Signals',
});

export const SIGNALS_DOCUMENT_TYPE = i18n.translate(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,17 @@
* you may not use this file except in compliance with the Elastic License.
*/

import * as i18n from './translations';
import { SignalsHistogramOption } from './types';

export const signalsHistogramOptions: SignalsHistogramOption[] = [
{ text: i18n.STACK_BY_RISK_SCORES, value: 'signal.rule.risk_score' },
{ text: i18n.STACK_BY_SEVERITIES, value: 'signal.rule.severity' },
{ text: i18n.STACK_BY_DESTINATION_IPS, value: 'destination.ip' },
{ text: i18n.STACK_BY_ACTIONS, value: 'event.action' },
{ text: i18n.STACK_BY_CATEGORIES, value: 'event.category' },
{ text: i18n.STACK_BY_HOST_NAMES, value: 'host.name' },
{ text: i18n.STACK_BY_RULE_TYPES, value: 'signal.rule.type' },
{ text: i18n.STACK_BY_RULE_NAMES, value: 'signal.rule.name' },
{ text: i18n.STACK_BY_SOURCE_IPS, value: 'source.ip' },
{ text: i18n.STACK_BY_USERS, value: 'user.name' },
{ text: 'signal.rule.risk_score', value: 'signal.rule.risk_score' },
{ text: 'signal.rule.severity', value: 'signal.rule.severity' },
{ text: 'destination.ip', value: 'destination.ip' },
{ text: 'event.action', value: 'event.action' },
{ text: 'event.category', value: 'event.category' },
{ text: 'host.name', value: 'host.name' },
{ text: 'signal.rule.type', value: 'signal.rule.type' },
{ text: 'signal.rule.name', value: 'signal.rule.name' },
{ text: 'source.ip', value: 'source.ip' },
{ text: 'user.name', value: 'user.name' },
];
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export const SignalsHistogramPanel = memo<SignalsHistogramPanelProps>(
filters,
query,
from,
legendPosition = 'bottom',
legendPosition = 'right',
loadingInitial = false,
showLinkToSignals = false,
showTotalSignalsCount = false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export const SignalsHistogram = React.memo<HistogramSignalsProps>(
from,
query,
filters,
legendPosition = 'bottom',
legendPosition = 'right',
loadingInitial,
setTotalSignalsCount,
stackByField,
Expand Down
Loading

0 comments on commit 6760c33

Please sign in to comment.