Skip to content

Commit

Permalink
[Security Solution] Fix TopN filters in timeline (elastic#183501)
Browse files Browse the repository at this point in the history
## Summary

Fixes: elastic#183497

Sets the `applyGlobalQueriesAndFilters` prop correctly to
_VisualizationEmbeddable_. This property was ignored when used from the
_TopN_ component, causing it to always apply the global filters and
query.

Extra: I cleaned all props that are not used in those component

### Screenshots

Pre-condition: Setting `user.name:"0q3c5et718"` query to the global
query in the background.

Before:


![before](https://github.com/elastic/kibana/assets/17747913/0b9ee913-44dc-48a7-a170-1c537ae494cf)

After:


![after](https://github.com/elastic/kibana/assets/17747913/89b6f752-d640-4e99-a826-0ff78d84992b)

---------

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
  • Loading branch information
semd and kibanamachine committed May 16, 2024
1 parent ece10c6 commit 5acea44
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,12 @@ describe('StatefulTopN', () => {

expect(props.to).toEqual('2020-07-08T08:20:18.966Z');
});

test(`provides 'applyGlobalQueriesAndFilters' = true`, () => {
const props = wrapper.find('[data-test-subj="top-n"]').first().props() as Props;

expect(props.applyGlobalQueriesAndFilters).toEqual(true);
});
});

describe('rendering in a timeline context', () => {
Expand Down Expand Up @@ -343,26 +349,38 @@ describe('StatefulTopN', () => {

expect(props.to).toEqual('2020-04-15T03:46:09.047Z');
});

test(`provides 'applyGlobalQueriesAndFilters' = false`, () => {
const props = wrapper.find('[data-test-subj="top-n"]').first().props() as Props;

expect(props.applyGlobalQueriesAndFilters).toEqual(false);
});
});

describe('rendering in alerts context', () => {
detectionAlertsTables.forEach((tableId) => {
test(`defaults to the 'Alert events' option when rendering in Alerts`, async () => {
const wrapper = mount(
describe.each(detectionAlertsTables)('tableId: %s', (tableId) => {
let wrapper: ReactWrapper;
beforeEach(() => {
wrapper = mount(
<TestProviders store={store}>
<StatefulTopN
{...{
...testProps,
scopeId: tableId,
}}
/>
<StatefulTopN {...{ ...testProps, scopeId: tableId }} />
</TestProviders>
);
});
afterEach(() => {
wrapper.unmount();
});

test(`defaults to the 'Alert events' option when rendering in Alerts`, async () => {
await waitFor(() => {
const props = wrapper.find('[data-test-subj="top-n"]').first().props() as Props;
expect(props.defaultView).toEqual('alert');
});
wrapper.unmount();
});

test(`provides 'applyGlobalQueriesAndFilters' = true`, () => {
const props = wrapper.find('[data-test-subj="top-n"]').first().props() as Props;
expect(props.applyGlobalQueriesAndFilters).toEqual(true);
});
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ const StatefulTopNComponent: React.FC<Props> = ({
const { from, deleteQuery, setQuery, to } = useGlobalTime();

const options = getOptions(isActiveTimeline(scopeId ?? '') ? activeTimelineEventType : undefined);
const applyGlobalQueriesAndFilters = !isActiveTimeline(scopeId ?? '');

const combinedQueries = useMemo(
() =>
Expand Down Expand Up @@ -158,7 +159,6 @@ const StatefulTopNComponent: React.FC<Props> = ({
options={options}
paddingSize={paddingSize}
query={isActiveTimeline(scopeId ?? '') ? EMPTY_QUERY : globalQuery}
showLegend={showLegend}
setAbsoluteRangeDatePickerTarget={
isActiveTimeline(scopeId ?? '') ? InputsModelId.timeline : InputsModelId.global
}
Expand All @@ -167,6 +167,7 @@ const StatefulTopNComponent: React.FC<Props> = ({
to={isActiveTimeline(scopeId ?? '') ? activeTimelineTo : to}
toggleTopN={toggleTopN}
onFilterAdded={onFilterAdded}
applyGlobalQueriesAndFilters={applyGlobalQueriesAndFilters}
/>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import { EventsByDataset } from '../../../overview/components/events_by_dataset'
import { SignalsByCategory } from '../../../overview/components/signals_by_category';
import type { InputsModelId } from '../../store/inputs/constants';
import type { TimelineEventsType } from '../../../../common/types/timeline';
import { useSourcererDataView } from '../../containers/sourcerer';
import type { TopNOption } from './helpers';
import { getSourcererScopeName, removeIgnoredAlertFilters } from './helpers';
import * as i18n from './translations';
Expand Down Expand Up @@ -54,10 +53,10 @@ export interface Props extends Pick<GlobalTimeArgs, 'from' | 'to' | 'deleteQuery
paddingSize?: 's' | 'm' | 'l' | 'none';
query: Query;
setAbsoluteRangeDatePickerTarget: InputsModelId;
showLegend?: boolean;
scopeId?: string;
toggleTopN: () => void;
onFilterAdded?: () => void; // eslint-disable-line react/no-unused-prop-types
applyGlobalQueriesAndFilters?: boolean;
}

const TopNComponent: React.FC<Props> = ({
Expand All @@ -71,20 +70,19 @@ const TopNComponent: React.FC<Props> = ({
options,
paddingSize,
query,
showLegend,
setAbsoluteRangeDatePickerTarget,
setQuery,
scopeId,
to,
toggleTopN,
applyGlobalQueriesAndFilters,
}) => {
const [view, setView] = useState<TimelineEventsType>(defaultView);
const onViewSelected = useCallback(
(value: string) => setView(value as TimelineEventsType),
[setView]
);
const sourcererScopeId = getSourcererScopeName({ scopeId, view });
const { selectedPatterns, runtimeMappings } = useSourcererDataView(sourcererScopeId);

useEffect(() => {
setView(defaultView);
Expand Down Expand Up @@ -121,21 +119,17 @@ const TopNComponent: React.FC<Props> = ({
from={from}
headerChildren={headerChildren}
indexPattern={indexPattern}
indexNames={selectedPatterns}
runtimeMappings={runtimeMappings}
onlyField={field}
paddingSize={paddingSize}
query={query}
queryType="topN"
showLegend={showLegend}
setAbsoluteRangeDatePickerTarget={setAbsoluteRangeDatePickerTarget}
setQuery={setQuery}
showSpacer={false}
toggleTopN={toggleTopN}
scopeId={scopeId}
sourcererScopeId={sourcererScopeId}
to={to}
hideQueryToggle
applyGlobalQueriesAndFilters={applyGlobalQueriesAndFilters}
/>
) : (
<SignalsByCategory
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

import { Position } from '@elastic/charts';
import numeral from '@elastic/numeral';
import type { MappingRuntimeFields } from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
import React, { useEffect, useMemo, useCallback } from 'react';

import type { DataViewBase, Filter, Query } from '@kbn/es-query';
Expand All @@ -29,7 +28,6 @@ import {
eventsHistogramConfig,
} from '../../../common/components/events_tab/histogram_configurations';
import { HostsTableType } from '../../../explore/hosts/store/model';
import type { InputsModelId } from '../../../common/store/inputs/constants';
import type { GlobalTimeArgs } from '../../../common/containers/use_global_time';

import * as i18n from '../../pages/translations';
Expand All @@ -48,20 +46,16 @@ interface Props extends Pick<GlobalTimeArgs, 'from' | 'to' | 'deleteQuery' | 'se
filters: Filter[];
headerChildren?: React.ReactNode;
indexPattern: DataViewBase;
indexNames: string[];
runtimeMappings?: MappingRuntimeFields;
onlyField?: string;
paddingSize?: 's' | 'm' | 'l' | 'none';
query: Query;
// Make a unique query type everywhere this query is used
queryType: 'topN' | 'overview';
setAbsoluteRangeDatePickerTarget?: InputsModelId;
showLegend?: boolean;
showSpacer?: boolean;
scopeId?: string;
toggleTopN?: () => void;
hideQueryToggle?: boolean;
sourcererScopeId?: SourcererScopeName;
applyGlobalQueriesAndFilters?: boolean;
}

const getHistogramOption = (fieldName: string): MatrixHistogramOption => ({
Expand All @@ -83,21 +77,17 @@ const EventsByDatasetComponent: React.FC<Props> = ({
from,
headerChildren,
indexPattern,
indexNames,
runtimeMappings,
onlyField,
paddingSize,
query,
queryType,
setAbsoluteRangeDatePickerTarget,
setQuery,
showLegend,
showSpacer = true,
scopeId,
sourcererScopeId,
to,
toggleTopN,
hideQueryToggle = false,
applyGlobalQueriesAndFilters,
}) => {
const uniqueQueryId = useMemo(() => `${ID}-${queryType}`, [queryType]);

Expand Down Expand Up @@ -204,6 +194,7 @@ const EventsByDatasetComponent: React.FC<Props> = ({
title={onlyField != null ? i18n.TOP(onlyField) : eventsByDatasetHistogramConfigs.title}
chartHeight={CHART_HEIGHT}
hideQueryToggle={hideQueryToggle}
applyGlobalQueriesAndFilters={applyGlobalQueriesAndFilters}
/>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,6 @@ const OverviewComponent = () => {
filters={filters}
from={from}
indexPattern={indexPattern}
indexNames={selectedPatterns}
query={query}
queryType="overview"
setQuery={setQuery}
Expand Down

0 comments on commit 5acea44

Please sign in to comment.