[Security Solution] Fix - Alert Table Event Rendered View + Cell actions (#212721)

## Summary

This PR fixes 2 bugs with regards to Event Rendered view.

## 1. Cell Actions of Event Rendered View
The Cell actions were not initialized in `Event Rendered View` and would
only appear once user has switched to the `Grid View`. See `Before`
section below to see the demo

|Before|After|
|---|---|
|<video
src="https://github.com/user-attachments/assets/ee02054c-828c-4b22-9364-bcba1c9c8067"/>|<video
src="https://github.com/user-attachments/assets/f7a428eb-e4d1-40c7-b2fc-deac9ef1ce30"/>|

## 2. Cell Actions in Event Renderers 
Some Event Renderers ( For example, `System Generic File`) and its
nested Event renderers had cell actions directed towards `timeline` even
though, they were rendered in Alert Table.

This was because `scopeId` was not being passed correctly to the Cell
Actions Provider. This is the case with most of the renderers and PR
adds `scopeId` prop, wherever it was needed.

|Before|After|
|---|---|
|<video
src="https://github.com/user-attachments/assets/c7511a25-a313-4e98-9370-40955d3c1d3b"/>|<video
src="https://github.com/user-attachments/assets/90aaa1be-209f-49a0-834e-c5bd5dded8c9"/>|




### Checklist

Check the PR satisfies following conditions. 

Reviewers should verify this PR satisfies this list as well.

- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
This commit is contained in:
Jatin Kathuria 2025-03-14 12:29:34 +01:00 committed by GitHub
parent b9a258723d
commit 876a784a41
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
93 changed files with 2298 additions and 869 deletions

View file

@ -7,14 +7,12 @@
import type { TimelineNonEcsData } from '@kbn/timelines-plugin/common';
import { useCallback, useMemo } from 'react';
import { TableId, tableDefaults, dataTableSelectors } from '@kbn/securitysolution-data-table';
import { TableId } from '@kbn/securitysolution-data-table';
import type { RenderContext } from '@kbn/response-ops-alerts-table/types';
import type { UseDataGridColumnsSecurityCellActionsProps } from '../../../common/components/cell_actions';
import { useDataGridColumnsSecurityCellActions } from '../../../common/components/cell_actions';
import { SecurityCellActionsTrigger, SecurityCellActionType } from '../../../app/actions/constants';
import { VIEW_SELECTION } from '../../../../common/constants';
import { SourcererScopeName } from '../../../sourcerer/store/model';
import { useShallowEqualSelector } from '../../../common/hooks/use_selector';
import { useGetFieldSpec } from '../../../common/hooks/use_get_field_spec';
import { useDataViewId } from '../../../common/hooks/use_data_view_id';
import type {
@ -38,28 +36,22 @@ export const useCellActionsOptions = (
} = context ?? {};
const getFieldSpec = useGetFieldSpec(SourcererScopeName.detections);
const dataViewId = useDataViewId(SourcererScopeName.detections);
const getTable = useMemo(() => dataTableSelectors.getTableByIdSelector(), []);
const viewMode =
useShallowEqualSelector((state) => (getTable(state, tableId) ?? tableDefaults).viewMode) ??
tableDefaults.viewMode;
const cellActionsMetadata = useMemo(
() => ({ scopeId: tableId, dataViewId }),
[dataViewId, tableId]
);
const cellActionsFields: UseDataGridColumnsSecurityCellActionsProps['fields'] = useMemo(
() =>
viewMode === VIEW_SELECTION.eventRenderedView
? undefined
: columns.map(
(column) =>
getFieldSpec(column.id) ?? {
name: '',
type: '', // When type is an empty string all cell actions are incompatible
aggregatable: false,
searchable: false,
}
),
[columns, getFieldSpec, viewMode]
columns.map(
(column) =>
getFieldSpec(column.id) ?? {
name: '',
type: '', // When type is an empty string all cell actions are incompatible
aggregatable: false,
searchable: false,
}
),
[columns, getFieldSpec]
);
/**

View file

@ -60,8 +60,10 @@ export const DirectionBadge = React.memo<{
contextId: string;
direction?: string | null;
eventId: string;
}>(({ contextId, eventId, direction }) => (
scopeId: string;
}>(({ contextId, eventId, direction, scopeId }) => (
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={eventId}
field={NETWORK_DIRECTION_FIELD_NAME}

View file

@ -74,7 +74,8 @@ const GeoFieldValues = React.memo<{
eventId: string;
fieldName: string;
values?: string[] | null;
}>(({ contextId, eventId, fieldName, values }) =>
scopeId: string;
}>(({ contextId, eventId, fieldName, values, scopeId }) =>
values != null ? (
<>
{uniq(values).map((value) => (
@ -89,6 +90,7 @@ const GeoFieldValues = React.memo<{
<EuiFlexItem grow={false}>
<DefaultDraggable
scopeId={scopeId}
data-test-subj={fieldName}
field={fieldName}
id={`geo-field-values-default-draggable-${contextId}-${eventId}-${fieldName}-${value}`}
@ -114,13 +116,14 @@ GeoFieldValues.displayName = 'GeoFieldValues';
* - `source|destination.geo.city_name`
*/
export const GeoFields = React.memo<GeoFieldsProps>((props) => {
const { contextId, eventId, type } = props;
const { contextId, eventId, type, scopeId } = props;
const propNameToFieldName = getGeoFieldPropNameToFieldNameMap(type);
return (
<EuiFlexGroup alignItems="center" gutterSize="none">
{uniq(propNameToFieldName).map((geo) => (
<GeoFieldValues
scopeId={scopeId}
contextId={contextId}
eventId={eventId}
fieldName={geo.fieldName}

View file

@ -45,6 +45,17 @@ import {
NETWORK_PROTOCOL_FIELD_NAME,
NETWORK_TRANSPORT_FIELD_NAME,
} from './field_names';
import { CellActionsWrapper } from '../../../../common/components/drag_and_drop/cell_actions_wrapper';
jest.mock('../../../../common/components/drag_and_drop/cell_actions_wrapper', () => {
return {
CellActionsWrapper: jest.fn(),
};
});
const MockedCellActionsWrapper = jest.fn(({ children }) => {
return <div data-test-subj="mock-cell-action-wrapper">{children}</div>;
});
jest.mock('../../../../common/lib/kibana');
@ -58,6 +69,7 @@ jest.mock('@elastic/eui', () => {
const getSourceDestinationInstance = () => (
<SourceDestination
scopeId="some_scope"
contextId="test"
destinationBytes={asArrayIfExists(get(DESTINATION_BYTES_FIELD_NAME, getMockNetflowData()))}
destinationGeoContinentName={asArrayIfExists(
@ -118,6 +130,10 @@ jest.mock('react-router-dom', () => {
});
describe('SourceDestination', () => {
beforeEach(() => {
(CellActionsWrapper as unknown as jest.Mock).mockImplementation(MockedCellActionsWrapper);
});
test('renders correctly against snapshot', () => {
const { asFragment } = render(<TestProviders>{getSourceDestinationInstance()}</TestProviders>);
expect(asFragment).toMatchSnapshot();
@ -317,4 +333,15 @@ describe('SourceDestination', () => {
expect(screen.getByText('tcp')).toBeInTheDocument();
});
test('should passing correct scopeId to cell actions', () => {
render(<TestProviders>{getSourceDestinationInstance()}</TestProviders>);
expect(MockedCellActionsWrapper).toHaveBeenCalledWith(
expect.objectContaining({
scopeId: 'some_scope',
}),
{}
);
});
});

View file

@ -26,6 +26,7 @@ EuiFlexItemMarginTop.displayName = 'EuiFlexItemMarginTop';
export const SourceDestination = React.memo<SourceDestinationProps>(
({
contextId,
scopeId,
destinationBytes,
destinationGeoContinentName,
destinationGeoCountryName,
@ -55,6 +56,7 @@ export const SourceDestination = React.memo<SourceDestinationProps>(
<EuiFlexGroup alignItems="center" direction="column" justifyContent="center" gutterSize="none">
<EuiFlexItem grow={false}>
<Network
scopeId={scopeId}
bytes={networkBytes}
packets={networkPackets}
communityId={networkCommunityId}
@ -69,6 +71,7 @@ export const SourceDestination = React.memo<SourceDestinationProps>(
<EuiFlexItemMarginTop grow={false}>
<SourceDestinationWithArrows
contextId={contextId}
scopeId={scopeId}
destinationBytes={destinationBytes}
destinationGeoContinentName={destinationGeoContinentName}
destinationGeoCountryName={destinationGeoCountryName}

View file

@ -48,98 +48,121 @@ export const Network = React.memo<{
packets?: string[] | null;
protocol?: string[] | null;
transport?: string[] | null;
}>(({ bytes, communityId, contextId, direction, eventId, packets, protocol, transport }) => (
<EuiFlexGroup alignItems="center" justifyContent="center" gutterSize="none">
{direction != null
? uniq(direction).map((dir) => (
<EuiFlexItemMarginRight grow={false} key={dir}>
<DirectionBadge contextId={contextId} direction={dir} eventId={eventId} />
</EuiFlexItemMarginRight>
))
: null}
scopeId: string;
}>(
({
bytes,
communityId,
contextId,
direction,
eventId,
packets,
protocol,
transport,
scopeId,
}) => (
<EuiFlexGroup alignItems="center" justifyContent="center" gutterSize="none">
{direction != null
? uniq(direction).map((dir) => (
<EuiFlexItemMarginRight grow={false} key={dir}>
<DirectionBadge
scopeId={scopeId}
contextId={contextId}
direction={dir}
eventId={eventId}
/>
</EuiFlexItemMarginRight>
))
: null}
{protocol != null
? uniq(protocol).map((proto) => (
<EuiFlexItemMarginRight grow={false} key={proto}>
<DraggableBadge
contextId={contextId}
eventId={eventId}
field={NETWORK_PROTOCOL_FIELD_NAME}
value={proto}
isAggregatable={true}
fieldType="keyword"
/>
</EuiFlexItemMarginRight>
))
: null}
{protocol != null
? uniq(protocol).map((proto) => (
<EuiFlexItemMarginRight grow={false} key={proto}>
<DraggableBadge
contextId={contextId}
scopeId={scopeId}
eventId={eventId}
field={NETWORK_PROTOCOL_FIELD_NAME}
value={proto}
isAggregatable={true}
fieldType="keyword"
/>
</EuiFlexItemMarginRight>
))
: null}
{bytes != null
? uniq(bytes).map((b) =>
!isNaN(Number(b)) ? (
<EuiFlexItemMarginRight grow={false} key={b}>
{bytes != null
? uniq(bytes).map((b) =>
!isNaN(Number(b)) ? (
<EuiFlexItemMarginRight grow={false} key={b}>
<DefaultDraggable
scopeId={scopeId}
field={NETWORK_BYTES_FIELD_NAME}
id={`network-default-draggable-${contextId}-${eventId}-${NETWORK_BYTES_FIELD_NAME}-${b}`}
value={b}
>
<Stats size="xs">
<span>
<PreferenceFormattedBytes value={b} />
</span>
</Stats>
</DefaultDraggable>
</EuiFlexItemMarginRight>
) : null
)
: null}
{packets != null
? uniq(packets).map((p) => (
<EuiFlexItemMarginRight grow={false} key={p}>
<DefaultDraggable
field={NETWORK_BYTES_FIELD_NAME}
id={`network-default-draggable-${contextId}-${eventId}-${NETWORK_BYTES_FIELD_NAME}-${b}`}
value={b}
scopeId={scopeId}
field={NETWORK_PACKETS_FIELD_NAME}
id={`network-default-draggable-${contextId}-${eventId}-${NETWORK_PACKETS_FIELD_NAME}-${p}`}
value={p}
>
<Stats size="xs">
<span>
<PreferenceFormattedBytes value={b} />
</span>
<span>{`${p} ${i18n.PACKETS}`}</span>
</Stats>
</DefaultDraggable>
</EuiFlexItemMarginRight>
) : null
)
: null}
))
: null}
{packets != null
? uniq(packets).map((p) => (
<EuiFlexItemMarginRight grow={false} key={p}>
<DefaultDraggable
field={NETWORK_PACKETS_FIELD_NAME}
id={`network-default-draggable-${contextId}-${eventId}-${NETWORK_PACKETS_FIELD_NAME}-${p}`}
value={p}
>
<Stats size="xs">
<span>{`${p} ${i18n.PACKETS}`}</span>
</Stats>
</DefaultDraggable>
</EuiFlexItemMarginRight>
))
: null}
{transport != null
? uniq(transport).map((trans) => (
<EuiFlexItemMarginRight grow={false} key={trans}>
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
data-test-subj="network-transport"
eventId={eventId}
field={NETWORK_TRANSPORT_FIELD_NAME}
value={trans}
isAggregatable={true}
fieldType="keyword"
/>
</EuiFlexItemMarginRight>
))
: null}
{transport != null
? uniq(transport).map((trans) => (
<EuiFlexItemMarginRight grow={false} key={trans}>
<DraggableBadge
contextId={contextId}
data-test-subj="network-transport"
eventId={eventId}
field={NETWORK_TRANSPORT_FIELD_NAME}
value={trans}
isAggregatable={true}
fieldType="keyword"
/>
</EuiFlexItemMarginRight>
))
: null}
{communityId != null
? uniq(communityId).map((trans) => (
<EuiFlexItem grow={false} key={trans}>
<DraggableBadge
contextId={contextId}
eventId={eventId}
field={NETWORK_COMMUNITY_ID_FIELD_NAME}
value={trans}
isAggregatable={true}
fieldType="keyword"
/>
</EuiFlexItem>
))
: null}
</EuiFlexGroup>
));
{communityId != null
? uniq(communityId).map((trans) => (
<EuiFlexItem grow={false} key={trans}>
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={eventId}
field={NETWORK_COMMUNITY_ID_FIELD_NAME}
value={trans}
isAggregatable={true}
fieldType="keyword"
/>
</EuiFlexItem>
))
: null}
</EuiFlexGroup>
)
);
Network.displayName = 'Network';

View file

@ -59,7 +59,8 @@ const SourceArrow = React.memo<{
sourceBytes: string | undefined;
sourceBytesPercent: number | undefined;
sourcePackets: string | undefined;
}>(({ contextId, eventId, sourceBytes, sourceBytesPercent, sourcePackets }) => {
scopeId: string;
}>(({ contextId, eventId, sourceBytes, sourceBytesPercent, sourcePackets, scopeId }) => {
const sourceArrowHeight =
sourceBytesPercent != null
? getArrowHeightFromPercent(sourceBytesPercent)
@ -74,6 +75,7 @@ const SourceArrow = React.memo<{
{sourceBytes != null && !isNaN(Number(sourceBytes)) ? (
<EuiFlexItem grow={false}>
<DefaultDraggable
scopeId={scopeId}
field={SOURCE_BYTES_FIELD_NAME}
id={`source-arrow-default-draggable-${contextId}-${eventId}-${SOURCE_BYTES_FIELD_NAME}-${sourceBytes}`}
value={sourceBytes}
@ -97,6 +99,7 @@ const SourceArrow = React.memo<{
{sourcePackets != null && !isNaN(Number(sourcePackets)) ? (
<EuiFlexItem grow={false}>
<DefaultDraggable
scopeId={scopeId}
field={SOURCE_PACKETS_FIELD_NAME}
id={`source-arrow-default-draggable-${contextId}-${eventId}-${SOURCE_PACKETS_FIELD_NAME}-${sourcePackets}`}
value={sourcePackets}
@ -131,65 +134,77 @@ const DestinationArrow = React.memo<{
destinationBytesPercent: number | undefined;
destinationPackets: string | undefined;
eventId: string;
}>(({ contextId, destinationBytes, destinationBytesPercent, destinationPackets, eventId }) => {
const destinationArrowHeight =
destinationBytesPercent != null
? getArrowHeightFromPercent(destinationBytesPercent)
: DEFAULT_ARROW_HEIGHT;
scopeId: string;
}>(
({
contextId,
destinationBytes,
destinationBytesPercent,
destinationPackets,
eventId,
scopeId,
}) => {
const destinationArrowHeight =
destinationBytesPercent != null
? getArrowHeightFromPercent(destinationBytesPercent)
: DEFAULT_ARROW_HEIGHT;
return (
<EuiFlexGroup alignItems="center" gutterSize="none" justifyContent="center">
<EuiFlexItem grow={false}>
<ArrowHead direction="arrowLeft" />
</EuiFlexItem>
<EuiFlexItem grow={false}>
<ArrowBody height={destinationArrowHeight ?? 0} />
</EuiFlexItem>
{destinationBytes != null && !isNaN(Number(destinationBytes)) ? (
return (
<EuiFlexGroup alignItems="center" gutterSize="none" justifyContent="center">
<EuiFlexItem grow={false}>
<DefaultDraggable
field={DESTINATION_BYTES_FIELD_NAME}
id={`destination-arrow-default-draggable-${contextId}-${eventId}-${DESTINATION_BYTES_FIELD_NAME}-${destinationBytes}`}
value={destinationBytes}
>
<Data size="xs">
{destinationBytesPercent != null ? (
<Percent>{`(${numeral(destinationBytesPercent).format('0.00')}%)`}</Percent>
) : null}
<span>
<PreferenceFormattedBytes value={destinationBytes} />
</span>
</Data>
</DefaultDraggable>
<ArrowHead direction="arrowLeft" />
</EuiFlexItem>
) : null}
<EuiFlexItem grow={false}>
<ArrowBody height={destinationArrowHeight ?? 0} />
</EuiFlexItem>
{destinationPackets != null && !isNaN(Number(destinationPackets)) ? (
<EuiFlexItem grow={false}>
<DefaultDraggable
field={DESTINATION_PACKETS_FIELD_NAME}
id={`destination-arrow-default-draggable-${contextId}-${eventId}-${DESTINATION_PACKETS_FIELD_NAME}-${destinationPackets}`}
value={destinationPackets}
>
<Data size="xs">
<span>{`${numeral(destinationPackets).format('0,0')} ${i18n.PACKETS}`}</span>
</Data>
</DefaultDraggable>
<ArrowBody height={destinationArrowHeight ?? 0} />
</EuiFlexItem>
) : null}
<EuiFlexItem grow={false}>
<ArrowBody height={destinationArrowHeight ?? 0} />
</EuiFlexItem>
</EuiFlexGroup>
);
});
{destinationBytes != null && !isNaN(Number(destinationBytes)) ? (
<EuiFlexItem grow={false}>
<DefaultDraggable
scopeId={scopeId}
field={DESTINATION_BYTES_FIELD_NAME}
id={`destination-arrow-default-draggable-${contextId}-${eventId}-${DESTINATION_BYTES_FIELD_NAME}-${destinationBytes}`}
value={destinationBytes}
>
<Data size="xs">
{destinationBytesPercent != null ? (
<Percent>{`(${numeral(destinationBytesPercent).format('0.00')}%)`}</Percent>
) : null}
<span>
<PreferenceFormattedBytes value={destinationBytes} />
</span>
</Data>
</DefaultDraggable>
</EuiFlexItem>
) : null}
<EuiFlexItem grow={false}>
<ArrowBody height={destinationArrowHeight ?? 0} />
</EuiFlexItem>
{destinationPackets != null && !isNaN(Number(destinationPackets)) ? (
<EuiFlexItem grow={false}>
<DefaultDraggable
scopeId={scopeId}
field={DESTINATION_PACKETS_FIELD_NAME}
id={`destination-arrow-default-draggable-${contextId}-${eventId}-${DESTINATION_PACKETS_FIELD_NAME}-${destinationPackets}`}
value={destinationPackets}
>
<Data size="xs">
<span>{`${numeral(destinationPackets).format('0,0')} ${i18n.PACKETS}`}</span>
</Data>
</DefaultDraggable>
</EuiFlexItem>
) : null}
<EuiFlexItem grow={false}>
<ArrowBody height={destinationArrowHeight ?? 0} />
</EuiFlexItem>
</EuiFlexGroup>
);
}
);
DestinationArrow.displayName = 'DestinationArrow';
@ -204,63 +219,76 @@ export const SourceDestinationArrows = React.memo<{
eventId: string;
sourceBytes?: string[] | null;
sourcePackets?: string[] | null;
}>(({ contextId, destinationBytes, destinationPackets, eventId, sourceBytes, sourcePackets }) => {
const maybeSourceBytes =
sourceBytes != null && hasOneValue(sourceBytes) ? sourceBytes[0] : undefined;
scopeId?: string;
}>(
({
contextId,
destinationBytes,
destinationPackets,
eventId,
sourceBytes,
sourcePackets,
scopeId = '',
}) => {
const maybeSourceBytes =
sourceBytes != null && hasOneValue(sourceBytes) ? sourceBytes[0] : undefined;
const maybeSourcePackets =
sourcePackets != null && hasOneValue(sourcePackets) ? sourcePackets[0] : undefined;
const maybeSourcePackets =
sourcePackets != null && hasOneValue(sourcePackets) ? sourcePackets[0] : undefined;
const maybeDestinationBytes =
destinationBytes != null && hasOneValue(destinationBytes) ? destinationBytes[0] : undefined;
const maybeDestinationBytes =
destinationBytes != null && hasOneValue(destinationBytes) ? destinationBytes[0] : undefined;
const maybeDestinationPackets =
destinationPackets != null && hasOneValue(destinationPackets)
? destinationPackets[0]
: undefined;
const maybeDestinationPackets =
destinationPackets != null && hasOneValue(destinationPackets)
? destinationPackets[0]
: undefined;
const maybeSourceBytesPercent =
maybeSourceBytes != null && maybeDestinationBytes != null
? getPercent({
numerator: Number(maybeSourceBytes),
denominator: Number(maybeSourceBytes) + Number(maybeDestinationBytes),
})
: undefined;
const maybeSourceBytesPercent =
maybeSourceBytes != null && maybeDestinationBytes != null
? getPercent({
numerator: Number(maybeSourceBytes),
denominator: Number(maybeSourceBytes) + Number(maybeDestinationBytes),
})
: undefined;
const maybeDestinationBytesPercent =
maybeSourceBytesPercent != null ? 100 - maybeSourceBytesPercent : undefined;
const maybeDestinationBytesPercent =
maybeSourceBytesPercent != null ? 100 - maybeSourceBytesPercent : undefined;
return (
<SourceDestinationArrowsContainer
alignItems="center"
justifyContent="center"
direction="column"
gutterSize="none"
>
{maybeSourceBytes != null ? (
<EuiFlexItem grow={false}>
<SourceArrow
contextId={contextId}
eventId={eventId}
sourceBytes={maybeSourceBytes}
sourcePackets={maybeSourcePackets}
sourceBytesPercent={maybeSourceBytesPercent}
/>
</EuiFlexItem>
) : null}
{maybeDestinationBytes != null ? (
<EuiFlexItem grow={false}>
<DestinationArrow
contextId={contextId}
destinationBytes={maybeDestinationBytes}
destinationPackets={maybeDestinationPackets}
destinationBytesPercent={maybeDestinationBytesPercent}
eventId={eventId}
/>
</EuiFlexItem>
) : null}
</SourceDestinationArrowsContainer>
);
});
return (
<SourceDestinationArrowsContainer
alignItems="center"
justifyContent="center"
direction="column"
gutterSize="none"
>
{maybeSourceBytes != null ? (
<EuiFlexItem grow={false}>
<SourceArrow
scopeId={scopeId}
contextId={contextId}
eventId={eventId}
sourceBytes={maybeSourceBytes}
sourcePackets={maybeSourcePackets}
sourceBytesPercent={maybeSourceBytesPercent}
/>
</EuiFlexItem>
) : null}
{maybeDestinationBytes != null ? (
<EuiFlexItem grow={false}>
<DestinationArrow
scopeId={scopeId}
contextId={contextId}
destinationBytes={maybeDestinationBytes}
destinationPackets={maybeDestinationPackets}
destinationBytesPercent={maybeDestinationBytesPercent}
eventId={eventId}
/>
</EuiFlexItem>
) : null}
</SourceDestinationArrowsContainer>
);
}
);
SourceDestinationArrows.displayName = 'SourceDestinationArrows';

View file

@ -332,6 +332,7 @@ describe('SourceDestinationIp', () => {
render(
<TestProviders>
<SourceDestinationIp
scopeId="some_scope"
contextId="test"
destinationGeoContinentName={asArrayIfExists(
get(DESTINATION_GEO_CONTINENT_NAME_FIELD_NAME, getMockNetflowData())
@ -381,6 +382,7 @@ describe('SourceDestinationIp', () => {
render(
<TestProviders>
<SourceDestinationIp
scopeId="some_scope"
contextId="test"
destinationGeoContinentName={asArrayIfExists(
get(DESTINATION_GEO_CONTINENT_NAME_FIELD_NAME, getMockNetflowData())
@ -430,6 +432,7 @@ describe('SourceDestinationIp', () => {
render(
<TestProviders>
<SourceDestinationIp
scopeId="some_scope"
contextId="test"
destinationGeoContinentName={asArrayIfExists(
get(DESTINATION_GEO_CONTINENT_NAME_FIELD_NAME, getMockNetflowData())
@ -479,6 +482,7 @@ describe('SourceDestinationIp', () => {
render(
<TestProviders>
<SourceDestinationIp
scopeId="some_scope"
contextId="test"
destinationGeoContinentName={asArrayIfExists(
get(DESTINATION_GEO_CONTINENT_NAME_FIELD_NAME, getMockNetflowData())
@ -529,6 +533,7 @@ describe('SourceDestinationIp', () => {
render(
<TestProviders>
<SourceDestinationIp
scopeId="some_scope"
contextId="test"
destinationGeoContinentName={asArrayIfExists(
get(DESTINATION_GEO_CONTINENT_NAME_FIELD_NAME, getMockNetflowData())
@ -578,6 +583,7 @@ describe('SourceDestinationIp', () => {
render(
<TestProviders>
<SourceDestinationIp
scopeId="some_scope"
contextId="test"
destinationGeoContinentName={asArrayIfExists(
get(DESTINATION_GEO_CONTINENT_NAME_FIELD_NAME, getMockNetflowData())
@ -627,6 +633,7 @@ describe('SourceDestinationIp', () => {
render(
<TestProviders>
<SourceDestinationIp
scopeId="some_scope"
contextId="test"
destinationGeoContinentName={asArrayIfExists(
get(DESTINATION_GEO_CONTINENT_NAME_FIELD_NAME, getMockNetflowData())
@ -676,6 +683,7 @@ describe('SourceDestinationIp', () => {
render(
<TestProviders>
<SourceDestinationIp
scopeId="some_scope"
contextId="test"
destinationGeoContinentName={asArrayIfExists(
get(DESTINATION_GEO_CONTINENT_NAME_FIELD_NAME, getMockNetflowData())
@ -725,6 +733,7 @@ describe('SourceDestinationIp', () => {
render(
<TestProviders>
<SourceDestinationIp
scopeId="some_scope"
contextId="test"
destinationGeoContinentName={asArrayIfExists(
get(DESTINATION_GEO_CONTINENT_NAME_FIELD_NAME, getMockNetflowData())
@ -774,6 +783,7 @@ describe('SourceDestinationIp', () => {
render(
<TestProviders>
<SourceDestinationIp
scopeId="some_scope"
contextId="test"
destinationGeoContinentName={asArrayIfExists(
get(DESTINATION_GEO_CONTINENT_NAME_FIELD_NAME, getMockNetflowData())
@ -823,6 +833,7 @@ describe('SourceDestinationIp', () => {
render(
<TestProviders>
<SourceDestinationIp
scopeId="some_scope"
contextId="test"
destinationGeoContinentName={asArrayIfExists(
get(DESTINATION_GEO_CONTINENT_NAME_FIELD_NAME, getMockNetflowData())
@ -872,6 +883,7 @@ describe('SourceDestinationIp', () => {
render(
<TestProviders>
<SourceDestinationIp
scopeId="some_scope"
contextId="test"
destinationGeoContinentName={asArrayIfExists(
get(DESTINATION_GEO_CONTINENT_NAME_FIELD_NAME, getMockNetflowData())
@ -921,6 +933,7 @@ describe('SourceDestinationIp', () => {
render(
<TestProviders>
<SourceDestinationIp
scopeId="some_scope"
contextId="test"
destinationGeoContinentName={asArrayIfExists(
get(DESTINATION_GEO_CONTINENT_NAME_FIELD_NAME, getMockNetflowData())
@ -970,6 +983,7 @@ describe('SourceDestinationIp', () => {
render(
<TestProviders>
<SourceDestinationIp
scopeId="some_scope"
contextId="test"
destinationGeoContinentName={asArrayIfExists(
get(DESTINATION_GEO_CONTINENT_NAME_FIELD_NAME, getMockNetflowData())
@ -1019,6 +1033,7 @@ describe('SourceDestinationIp', () => {
render(
<TestProviders>
<SourceDestinationIp
scopeId="some_scope"
contextId="test"
destinationGeoContinentName={asArrayIfExists(
get(DESTINATION_GEO_CONTINENT_NAME_FIELD_NAME, getMockNetflowData())
@ -1069,6 +1084,7 @@ describe('SourceDestinationIp', () => {
render(
<TestProviders>
<SourceDestinationIp
scopeId="some_scope"
contextId="test"
destinationGeoContinentName={asArrayIfExists(
get(DESTINATION_GEO_CONTINENT_NAME_FIELD_NAME, getMockNetflowData())
@ -1119,6 +1135,7 @@ describe('SourceDestinationIp', () => {
render(
<TestProviders>
<SourceDestinationIp
scopeId="some_scope"
contextId="test"
destinationGeoContinentName={asArrayIfExists(
get(DESTINATION_GEO_CONTINENT_NAME_FIELD_NAME, getMockNetflowData())
@ -1169,6 +1186,7 @@ describe('SourceDestinationIp', () => {
render(
<TestProviders>
<SourceDestinationIp
scopeId="some_scope"
contextId="test"
destinationGeoContinentName={asArrayIfExists(
get(DESTINATION_GEO_CONTINENT_NAME_FIELD_NAME, getMockNetflowData())
@ -1218,6 +1236,7 @@ describe('SourceDestinationIp', () => {
render(
<TestProviders>
<SourceDestinationIp
scopeId="some_scope"
contextId="test"
destinationGeoContinentName={asArrayIfExists(
get(DESTINATION_GEO_CONTINENT_NAME_FIELD_NAME, getMockNetflowData())

View file

@ -149,6 +149,7 @@ IpAdressesWithPorts.displayName = 'IpAdressesWithPorts';
export const SourceDestinationIp = React.memo<SourceDestinationIpProps>(
({
contextId,
scopeId,
destinationGeoContinentName,
destinationGeoCountryName,
destinationGeoCountryIsoCode,
@ -203,6 +204,7 @@ export const SourceDestinationIp = React.memo<SourceDestinationIpProps>(
</EuiFlexItem>
<EuiFlexItem>
<GeoFields
scopeId={scopeId}
contextId={contextId}
destinationGeoContinentName={destinationGeoContinentName}
destinationGeoCountryName={destinationGeoCountryName}

View file

@ -41,10 +41,12 @@ export const SourceDestinationWithArrows = React.memo<SourceDestinationWithArrow
sourcePackets,
sourceIp,
sourcePort,
scopeId,
}) => (
<EuiFlexGroup justifyContent="center" gutterSize="none">
<EuiFlexItem grow={false}>
<SourceDestinationIp
scopeId={scopeId}
contextId={contextId}
destinationGeoContinentName={destinationGeoContinentName}
destinationGeoCountryName={destinationGeoCountryName}
@ -66,6 +68,7 @@ export const SourceDestinationWithArrows = React.memo<SourceDestinationWithArrow
</EuiFlexItem>
<SourceDestinationArrows
scopeId={scopeId}
contextId={contextId}
destinationBytes={destinationBytes}
destinationPackets={destinationPackets}
@ -76,6 +79,7 @@ export const SourceDestinationWithArrows = React.memo<SourceDestinationWithArrow
<EuiFlexItem grow={false}>
<SourceDestinationIp
scopeId={scopeId}
contextId={contextId}
destinationGeoContinentName={destinationGeoContinentName}
destinationGeoCountryName={destinationGeoCountryName}

View file

@ -9,6 +9,7 @@ export type SourceDestinationType = 'source' | 'destination';
export interface GeoFieldsProps {
contextId: string;
scopeId: string;
destinationGeoContinentName?: string[] | null;
destinationGeoCountryName?: string[] | null;
destinationGeoCountryIsoCode?: string[] | null;
@ -25,6 +26,7 @@ export interface GeoFieldsProps {
export interface SourceDestinationProps {
contextId: string;
scopeId: string;
destinationBytes?: string[] | null;
destinationGeoContinentName?: string[] | null;
destinationGeoCountryName?: string[] | null;
@ -55,6 +57,7 @@ export interface SourceDestinationProps {
export interface SourceDestinationIpProps {
contextId: string;
scopeId: string;
destinationGeoContinentName?: string[] | null;
destinationGeoCountryName?: string[] | null;
destinationGeoCountryIsoCode?: string[] | null;
@ -75,6 +78,7 @@ export interface SourceDestinationIpProps {
export interface SourceDestinationWithArrowsProps {
contextId: string;
scopeId: string;
destinationBytes?: string[] | null;
destinationGeoContinentName?: string[] | null;
destinationGeoCountryName?: string[] | null;

View file

@ -19,6 +19,7 @@ describe('CertificateFingerprint', () => {
render(
<TestProviders>
<CertificateFingerprint
scopeId="some_scope"
eventId="Tgwnt2kBqd-n62SwPZDP"
certificateType="client"
contextId="test"
@ -34,6 +35,7 @@ describe('CertificateFingerprint', () => {
render(
<TestProviders>
<CertificateFingerprint
scopeId="some_scope"
eventId="Tgwnt2kBqd-n62SwPZDP"
certificateType="client"
contextId="test"
@ -49,6 +51,7 @@ describe('CertificateFingerprint', () => {
render(
<TestProviders>
<CertificateFingerprint
scopeId="some_scope"
eventId="Tgwnt2kBqd-n62SwPZDP"
certificateType="client"
contextId="test"

View file

@ -41,9 +41,11 @@ export const CertificateFingerprint = React.memo<{
contextId: string;
fieldName: string;
value?: string | null;
}>(({ eventId, certificateType, contextId, fieldName, value }) => {
scopeId: string;
}>(({ eventId, certificateType, contextId, fieldName, value, scopeId }) => {
return (
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
data-test-subj={`${certificateType}-certificate-fingerprint`}
eventId={eventId}

View file

@ -19,6 +19,7 @@ describe('Ja3Fingerprint', () => {
render(
<TestProviders>
<Ja3Fingerprint
scopeId="some_scope"
eventId="KzNOvGkBqd-n62SwSPa4"
contextId="test"
fieldName="tls.fingerprints.ja3.hash"
@ -34,6 +35,7 @@ describe('Ja3Fingerprint', () => {
render(
<TestProviders>
<Ja3Fingerprint
scopeId="some_scope"
eventId="KzNOvGkBqd-n62SwSPa4"
contextId="test"
fieldName="tls.fingerprints.ja3.hash"
@ -49,6 +51,7 @@ describe('Ja3Fingerprint', () => {
render(
<TestProviders>
<Ja3Fingerprint
scopeId="some_scope"
eventId="KzNOvGkBqd-n62SwSPa4"
contextId="test"
fieldName="tls.fingerprints.ja3.hash"

View file

@ -31,8 +31,10 @@ export const Ja3Fingerprint = React.memo<{
contextId: string;
fieldName: string;
value?: string | null;
}>(({ contextId, eventId, fieldName, value }) => (
scopeId: string;
}>(({ contextId, eventId, fieldName, value, scopeId }) => (
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
data-test-subj="ja3-hash"
eventId={eventId}

View file

@ -26,6 +26,7 @@ export const Fingerprints = React.memo<{
tlsClientCertificateFingerprintSha1?: string[] | null;
tlsFingerprintsJa3Hash?: string[] | null;
tlsServerCertificateFingerprintSha1?: string[] | null;
scopeId: string;
}>(
({
contextId,
@ -33,6 +34,7 @@ export const Fingerprints = React.memo<{
tlsClientCertificateFingerprintSha1,
tlsFingerprintsJa3Hash,
tlsServerCertificateFingerprintSha1,
scopeId,
}) => (
<EuiFlexGroup
alignItems="center"
@ -45,6 +47,7 @@ export const Fingerprints = React.memo<{
? uniq(tlsFingerprintsJa3Hash).map((ja3) => (
<EuiFlexItem grow={false} key={ja3}>
<Ja3Fingerprint
scopeId={scopeId}
eventId={eventId}
fieldName={JA3_HASH_FIELD_NAME}
contextId={contextId}
@ -57,6 +60,7 @@ export const Fingerprints = React.memo<{
? uniq(tlsClientCertificateFingerprintSha1).map((clientCert) => (
<EuiFlexItem grow={false} key={clientCert}>
<CertificateFingerprint
scopeId={scopeId}
eventId={eventId}
certificateType="client"
contextId={contextId}
@ -70,6 +74,7 @@ export const Fingerprints = React.memo<{
? uniq(tlsServerCertificateFingerprintSha1).map((serverCert) => (
<EuiFlexItem grow={false} key={serverCert}>
<CertificateFingerprint
scopeId={scopeId}
eventId={eventId}
certificateType="server"
contextId={contextId}

View file

@ -59,6 +59,7 @@ import {
NETWORK_TRANSPORT_FIELD_NAME,
} from '../../../explore/network/components/source_destination/field_names';
import { getMockNetflowData } from '../../../common/mock/netflow';
import { CellActionsWrapper } from '../../../common/components/drag_and_drop/cell_actions_wrapper';
jest.mock('../../../common/lib/kibana');
@ -70,8 +71,19 @@ jest.mock('@elastic/eui', () => {
};
});
jest.mock('../../../common/components/drag_and_drop/cell_actions_wrapper', () => {
return {
CellActionsWrapper: jest.fn(),
};
});
const MockedCellActionsWrapper = jest.fn(({ children }) => {
return <div data-test-subj="mock-cell-action-wrapper">{children}</div>;
});
const getNetflowInstance = () => (
<Netflow
scopeId="some_scope"
contextId="test"
destinationBytes={asArrayIfExists(get(DESTINATION_BYTES_FIELD_NAME, getMockNetflowData()))}
destinationGeoContinentName={asArrayIfExists(
@ -134,6 +146,10 @@ const getNetflowInstance = () => (
jest.mock('../../../common/components/links/link_props');
describe('Netflow', () => {
beforeEach(() => {
(CellActionsWrapper as unknown as jest.Mock).mockImplementation(MockedCellActionsWrapper);
});
test('renders correctly against snapshot', () => {
const { asFragment } = render(<TestProviders>{getNetflowInstance()}</TestProviders>);
expect(asFragment()).toMatchSnapshot();
@ -368,4 +384,15 @@ describe('Netflow', () => {
expect(screen.getByText('first.last')).toBeInTheDocument();
});
test('should passing correct scopeId to cell actions', () => {
render(<TestProviders>{getNetflowInstance()}</TestProviders>);
expect(MockedCellActionsWrapper).toHaveBeenCalledWith(
expect.objectContaining({
scopeId: 'some_scope',
}),
{}
);
});
});

View file

@ -24,6 +24,7 @@ import type { NetflowProps } from './types';
export const Netflow = React.memo<NetflowProps>(
({
contextId,
scopeId,
destinationBytes,
destinationGeoContinentName,
destinationGeoCountryName,
@ -68,6 +69,7 @@ export const Netflow = React.memo<NetflowProps>(
>
<EuiFlexItem grow={false}>
<NetflowColumns
scopeId={scopeId}
contextId={contextId}
destinationBytes={destinationBytes}
destinationGeoContinentName={destinationGeoContinentName}
@ -103,6 +105,7 @@ export const Netflow = React.memo<NetflowProps>(
</EuiFlexItem>
<EuiFlexItem grow={false}>
<Fingerprints
scopeId={scopeId}
contextId={contextId}
eventId={eventId}
tlsClientCertificateFingerprintSha1={tlsClientCertificateFingerprintSha1}

View file

@ -38,7 +38,8 @@ export const DurationEventStartEnd = React.memo<{
eventId: string;
eventEnd?: string[] | null;
eventStart?: string[] | null;
}>(({ contextId, eventDuration, eventId, eventEnd, eventStart }) => (
scopeId: string;
}>(({ contextId, eventDuration, eventId, eventEnd, eventStart, scopeId }) => (
<EuiFlexGroup
alignItems="flexStart"
data-test-subj="duration-and-start-group"
@ -50,6 +51,7 @@ export const DurationEventStartEnd = React.memo<{
? uniq(eventDuration).map((duration) => (
<EuiFlexItem grow={false} key={duration}>
<DefaultDraggable
scopeId={scopeId}
field={EVENT_DURATION_FIELD_NAME}
id={`duration-event-start-end-default-draggable-${contextId}-${eventId}-${EVENT_DURATION_FIELD_NAME}-${duration}`}
// @ts-expect-error
@ -72,6 +74,7 @@ export const DurationEventStartEnd = React.memo<{
? uniq(eventStart).map((start) => (
<EuiFlexItem grow={false} key={start}>
<DefaultDraggable
scopeId={scopeId}
field={EVENT_START_FIELD_NAME}
id={`duration-event-start-end-default-draggable-${contextId}-${eventId}-${EVENT_START_FIELD_NAME}-${start}`}
tooltipContent={null}
@ -89,6 +92,7 @@ export const DurationEventStartEnd = React.memo<{
? uniq(eventEnd).map((end) => (
<EuiFlexItem grow={false} key={end}>
<DefaultDraggable
scopeId={scopeId}
field={EVENT_END_FIELD_NAME}
id={`duration-event-start-end-default-draggable-${contextId}-${eventId}-${EVENT_END_FIELD_NAME}-${end}`}
tooltipContent={null}

View file

@ -32,6 +32,7 @@ EuiFlexItemMarginRight.displayName = 'EuiFlexItemMarginRight';
export const NetflowColumns = React.memo<NetflowColumnsProps>(
({
contextId,
scopeId,
destinationBytes,
destinationGeoContinentName,
destinationGeoCountryName,
@ -71,6 +72,7 @@ export const NetflowColumns = React.memo<NetflowColumnsProps>(
>
<EuiFlexItemMarginRight grow={false}>
<UserProcess
scopeId={scopeId}
contextId={contextId}
eventId={eventId}
processName={processName}
@ -80,6 +82,7 @@ export const NetflowColumns = React.memo<NetflowColumnsProps>(
<EuiFlexItemMarginRight grow={false}>
<DurationEventStartEnd
scopeId={scopeId}
contextId={contextId}
eventDuration={eventDuration}
eventId={eventId}
@ -90,6 +93,7 @@ export const NetflowColumns = React.memo<NetflowColumnsProps>(
<EuiFlexItem grow={false}>
<SourceDestination
scopeId={scopeId}
contextId={contextId}
destinationBytes={destinationBytes}
destinationGeoContinentName={destinationGeoContinentName}

View file

@ -7,6 +7,7 @@
export interface NetflowColumnsProps {
contextId: string;
scopeId: string;
destinationBytes?: string[] | null;
destinationGeoContinentName?: string[] | null;
destinationGeoCountryName?: string[] | null;

View file

@ -24,7 +24,8 @@ export const UserProcess = React.memo<{
eventId: string;
processName?: string[] | null;
userName?: string[] | null;
}>(({ contextId, eventId, processName, userName }) => (
scopeId: string;
}>(({ contextId, eventId, processName, userName, scopeId }) => (
<EuiFlexGroup
alignItems="flexStart"
data-test-subj="user-process"
@ -36,6 +37,7 @@ export const UserProcess = React.memo<{
? uniq(userName).map((user) => (
<EuiFlexItem grow={false} key={user}>
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
data-test-subj="user-name"
eventId={eventId}
@ -53,6 +55,7 @@ export const UserProcess = React.memo<{
? uniq(processName).map((process) => (
<EuiFlexItem grow={false} key={process}>
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={eventId}
field={PROCESS_NAME_FIELD_NAME}

View file

@ -7,6 +7,7 @@
export interface NetflowProps {
contextId: string;
scopeId: string;
destinationBytes?: string[] | null;
destinationGeoContinentName?: string[] | null;
destinationGeoCountryName?: string[] | null;

View file

@ -13,6 +13,7 @@ exports[`Args rendering it renders against shallow snapshot 1`] = `
field="process.args"
fieldType="keyword"
isAggregatable={true}
scopeId="some_scope"
value="arg1"
/>
</TokensFlexItem>
@ -27,6 +28,7 @@ exports[`Args rendering it renders against shallow snapshot 1`] = `
field="process.args"
fieldType="keyword"
isAggregatable={true}
scopeId="some_scope"
value="arg2"
/>
</TokensFlexItem>
@ -41,6 +43,7 @@ exports[`Args rendering it renders against shallow snapshot 1`] = `
field="process.args"
fieldType="keyword"
isAggregatable={true}
scopeId="some_scope"
value="arg3"
/>
</TokensFlexItem>
@ -54,6 +57,7 @@ exports[`Args rendering it renders against shallow snapshot 1`] = `
field="process.title"
fieldType="keyword"
isAggregatable={true}
scopeId="some_scope"
value="process-title-1"
/>
</TokensFlexItem>

View file

@ -12,6 +12,7 @@ exports[`HostWorkingDir renders correctly against snapshot 1`] = `
field="host.name"
fieldType="keyword"
isAggregatable={true}
scopeId="some_scope"
value="[hostname-123]"
/>
</TokensFlexItem>
@ -32,6 +33,7 @@ exports[`HostWorkingDir renders correctly against snapshot 1`] = `
fieldType="keyword"
iconType="folderOpen"
isAggregatable={true}
scopeId="some_scope"
value="[working-directory-123]"
/>
</TokensFlexItem>

View file

@ -15,6 +15,7 @@ exports[`ProcessDraggable rendering it renders against shallow snapshot 1`] = `
fieldType="keyword"
iconType="console"
isAggregatable={true}
scopeId="some_scope"
value="process-name-1"
/>
</EuiFlexItem>
@ -28,6 +29,7 @@ exports[`ProcessDraggable rendering it renders against shallow snapshot 1`] = `
fieldType="keyword"
isAggregatable={true}
queryValue="123"
scopeId="some_scope"
value="(123)"
/>
</EuiFlexItem>

View file

@ -13,6 +13,7 @@ exports[`UserHostWorkingDir rendering it renders against shallow snapshot 1`] =
fieldType="keyword"
iconType="user"
isAggregatable={true}
scopeId="some_scope"
value="[userName-123]"
/>
</TokensFlexItem>
@ -33,6 +34,7 @@ exports[`UserHostWorkingDir rendering it renders against shallow snapshot 1`] =
field="user.domain"
fieldType="keyword"
isAggregatable={true}
scopeId="some_scope"
value="[userDomain-123]"
/>
</TokensFlexItem>
@ -46,6 +48,7 @@ exports[`UserHostWorkingDir rendering it renders against shallow snapshot 1`] =
contextId="context-123"
eventId="event-123"
hostName="[hostName-123]"
scopeId="some_scope"
workingDirectory="[working-directory-123]"
/>
</Fragment>

View file

@ -11,6 +11,7 @@ import React from 'react';
import { useMountAppended } from '../../../../../common/utils/use_mount_appended';
import { TestProviders } from '../../../../../common/mock';
import { ArgsComponent } from './args';
import { CellActionsWrapper } from '../../../../../common/components/drag_and_drop/cell_actions_wrapper';
jest.mock('../../../../../common/lib/kibana');
@ -22,13 +23,28 @@ jest.mock('@elastic/eui', () => {
};
});
jest.mock('../../../../../common/components/drag_and_drop/cell_actions_wrapper', () => {
return {
CellActionsWrapper: jest.fn(),
};
});
const MockedCellActionsWrapper = jest.fn(({ children }) => {
return <div data-test-subj="mock-cell-action-wrapper">{children}</div>;
});
describe('Args', () => {
const mount = useMountAppended();
beforeEach(() => {
(CellActionsWrapper as unknown as jest.Mock).mockImplementation(MockedCellActionsWrapper);
});
describe('rendering', () => {
test('it renders against shallow snapshot', () => {
const wrapper = shallow(
<ArgsComponent
scopeId="some_scope"
contextId="context-123"
eventId="event-123"
args={['arg1', 'arg2', 'arg3']}
@ -42,6 +58,7 @@ describe('Args', () => {
const wrapper = mount(
<TestProviders>
<ArgsComponent
scopeId="some_scope"
contextId="context-123"
eventId="event-123"
args={undefined}
@ -56,6 +73,7 @@ describe('Args', () => {
const wrapper = mount(
<TestProviders>
<ArgsComponent
scopeId="some_scope"
contextId="context-123"
eventId="event-123"
args={null}
@ -69,7 +87,13 @@ describe('Args', () => {
test('it returns an empty string when args is an empty array, and title is an empty string', () => {
const wrapper = mount(
<TestProviders>
<ArgsComponent contextId="context-123" eventId="event-123" args={[]} processTitle="" />
<ArgsComponent
scopeId="some_scope"
contextId="context-123"
eventId="event-123"
args={[]}
processTitle=""
/>
</TestProviders>
);
expect(wrapper.text()).toEqual('');
@ -79,6 +103,7 @@ describe('Args', () => {
const wrapper = mount(
<TestProviders>
<ArgsComponent
scopeId="some_scope"
contextId="context-123"
eventId="event-123"
args={['arg1', 'arg2', 'arg3']}
@ -93,6 +118,7 @@ describe('Args', () => {
const wrapper = mount(
<TestProviders>
<ArgsComponent
scopeId="some_scope"
contextId="context-123"
eventId="event-123"
args={null}
@ -107,6 +133,7 @@ describe('Args', () => {
const wrapper = mount(
<TestProviders>
<ArgsComponent
scopeId="some_scope"
contextId="context-123"
eventId="event-123"
args={['arg1', 'arg2', 'arg3']}
@ -116,5 +143,28 @@ describe('Args', () => {
);
expect(wrapper.text()).toEqual('arg1arg2arg3process-title-1');
});
test('should passing correct scopeId to cell actions', () => {
mount(
<TestProviders>
<div>
<ArgsComponent
scopeId="some_scope"
contextId="context-123"
eventId="event-123"
args={['arg1', 'arg2', 'arg3']}
processTitle="process-title-1"
/>
</div>
</TestProviders>
);
expect(MockedCellActionsWrapper).toHaveBeenCalledWith(
expect.objectContaining({
scopeId: 'some_scope',
}),
{}
);
});
});
});

View file

@ -15,9 +15,10 @@ interface Props {
contextId: string;
eventId: string;
processTitle: string | null | undefined;
scopeId: string;
}
export const ArgsComponent = ({ args, contextId, eventId, processTitle }: Props) => {
export const ArgsComponent = ({ args, contextId, eventId, processTitle, scopeId }: Props) => {
if (isNillEmptyOrNotFinite(args) && isNillEmptyOrNotFinite(processTitle)) {
return null;
}
@ -28,6 +29,7 @@ export const ArgsComponent = ({ args, contextId, eventId, processTitle }: Props)
args.map((arg, i) => (
<TokensFlexItem key={`${contextId}-args-${i}-${arg}`} grow={false} component="span">
<DraggableBadge
scopeId={scopeId}
contextId={`${contextId}-args-${i}-${arg}`}
eventId={eventId}
field="process.args"
@ -41,6 +43,7 @@ export const ArgsComponent = ({ args, contextId, eventId, processTitle }: Props)
{!isNillEmptyOrNotFinite(processTitle) && (
<TokensFlexItem grow={false} component="span">
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={eventId}
field="process.title"

View file

@ -10,6 +10,7 @@ exports[`GenericDetails rendering it renders the default AuditAcquiredCredsDetai
processExecutable="/usr/sbin/sshd"
processPid={21202}
result="success"
scopeId="test"
secondary="alice"
session="340"
text="generic-text-123"

View file

@ -14,6 +14,7 @@ exports[`GenericFileDetails rendering it renders the default GenericFileDetails
processPid={27244}
processTitle="/lib/systemd/systemd-journald"
result="success"
scopeId="test"
secondary="root"
session="242"
text="generic-text-123"

View file

@ -5,6 +5,7 @@ exports[`UserPrimarySecondary rendering it renders the default PrimarySecondaryU
contextId="context-123"
eventId="event-123"
primary="primary-1"
scopeId="some_scope"
secondary="secondary-1"
/>
`;

View file

@ -9,6 +9,7 @@ exports[`SessionUserHostWorkingDir rendering it renders the default SessionUserH
eventId="eventid-123"
hostName="hostname-123"
primary="primary-123"
scopeId="some_scope"
secondary="secondary-123"
session="session-123"
userName="username-123"

View file

@ -73,6 +73,7 @@ describe('GenericDetails', () => {
<TestProviders>
<AuditdGenericLine
id="hello-i-am-an-id"
scopeId="some_scope"
contextId="contextid-123"
text="generic-text-123"
hostName="host-1"
@ -100,6 +101,7 @@ describe('GenericDetails', () => {
<TestProviders>
<AuditdGenericLine
id="hello-i-am-an-id"
scopeId="some_scope"
contextId="contextid-123"
text="generic-text-123"
hostName="host-1"
@ -127,6 +129,7 @@ describe('GenericDetails', () => {
<TestProviders>
<AuditdGenericLine
id="hello-i-am-an-id"
scopeId="some_scope"
contextId="contextid-123"
text="generic-text-123"
hostName="host-1"
@ -154,6 +157,7 @@ describe('GenericDetails', () => {
<TestProviders>
<AuditdGenericLine
id="hello-i-am-an-id"
scopeId="some_scope"
contextId="contextid-123"
text="generic-text-123"
hostName="host-1"
@ -181,6 +185,7 @@ describe('GenericDetails', () => {
<TestProviders>
<AuditdGenericLine
id="hello-i-am-an-id"
scopeId="some_scope"
contextId="contextid-123"
text="generic-text-123"
hostName="host-1"
@ -208,6 +213,7 @@ describe('GenericDetails', () => {
<TestProviders>
<AuditdGenericLine
id="hello-i-am-an-id"
scopeId="some_scope"
contextId="contextid-123"
text="generic-text-123"
hostName="host-1"
@ -235,6 +241,7 @@ describe('GenericDetails', () => {
<TestProviders>
<AuditdGenericLine
id="hello-i-am-an-id"
scopeId="some_scope"
contextId="contextid-123"
text="generic-text-123"
hostName="host-1"
@ -262,6 +269,7 @@ describe('GenericDetails', () => {
<TestProviders>
<AuditdGenericLine
id="hello-i-am-an-id"
scopeId="some_scope"
contextId="contextid-123"
text="generic-text-123"
hostName="host-1"
@ -289,6 +297,7 @@ describe('GenericDetails', () => {
<TestProviders>
<AuditdGenericLine
id="hello-i-am-an-id"
scopeId="some_scope"
contextId="contextid-123"
text="generic-text-123"
hostName="host-1"
@ -316,6 +325,7 @@ describe('GenericDetails', () => {
<TestProviders>
<AuditdGenericLine
id="hello-i-am-an-id"
scopeId="some_scope"
contextId="contextid-123"
text="generic-text-123"
userName={undefined}
@ -341,6 +351,7 @@ describe('GenericDetails', () => {
<TestProviders>
<AuditdGenericLine
id="hello-i-am-an-id"
scopeId="some_scope"
contextId="contextid-123"
text="generic-text-123"
hostName="some-host-name"
@ -366,6 +377,7 @@ describe('GenericDetails', () => {
<TestProviders>
<AuditdGenericLine
id="hello-i-am-an-id"
scopeId="some_scope"
contextId="contextid-123"
text="generic-text-123"
userName="some-user-name"
@ -391,6 +403,7 @@ describe('GenericDetails', () => {
<TestProviders>
<AuditdGenericLine
id="hello-i-am-an-id"
scopeId="some_scope"
contextId="contextid-123"
text="generic-text-123"
userName={undefined}
@ -416,6 +429,7 @@ describe('GenericDetails', () => {
<TestProviders>
<AuditdGenericLine
id="hello-i-am-an-id"
scopeId="some_scope"
contextId="contextid-123"
text="generic-text-123"
processTitle="some-process-title"
@ -441,6 +455,7 @@ describe('GenericDetails', () => {
<TestProviders>
<AuditdGenericLine
id="hello-i-am-an-id"
scopeId="some_scope"
contextId="contextid-123"
text="generic-text-123"
workingDirectory="some-working-directory"
@ -466,6 +481,7 @@ describe('GenericDetails', () => {
<TestProviders>
<AuditdGenericLine
id="hello-i-am-an-id"
scopeId="some_scope"
contextId="contextid-123"
text="generic-text-123"
args={['arg1', 'arg2', 'arg 3']}

View file

@ -35,6 +35,7 @@ interface Props {
workingDirectory: string | null | undefined;
args: string[] | null | undefined;
session: string | null | undefined;
scopeId: string;
}
export const AuditdGenericLine = React.memo<Props>(
@ -54,9 +55,11 @@ export const AuditdGenericLine = React.memo<Props>(
result,
session,
text,
scopeId,
}) => (
<EuiFlexGroup alignItems="center" justifyContent="center" gutterSize="none" wrap={true}>
<SessionUserHostWorkingDir
scopeId={scopeId}
eventId={id}
contextId={contextId}
hostName={hostName}
@ -73,6 +76,7 @@ export const AuditdGenericLine = React.memo<Props>(
)}
<TokensFlexItem grow={false} component="span">
<ProcessDraggable
scopeId={scopeId}
contextId={contextId}
endgamePid={undefined}
endgameProcessName={undefined}
@ -82,7 +86,13 @@ export const AuditdGenericLine = React.memo<Props>(
processExecutable={processExecutable}
/>
</TokensFlexItem>
<Args eventId={id} args={args} contextId={contextId} processTitle={processTitle} />
<Args
scopeId={scopeId}
eventId={id}
args={args}
contextId={contextId}
processTitle={processTitle}
/>
{result != null && (
<TokensFlexItem grow={false} component="span">
{i18n.WITH_RESULT}
@ -90,6 +100,7 @@ export const AuditdGenericLine = React.memo<Props>(
)}
<TokensFlexItem grow={false} component="span">
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={id}
field="auditd.result"
@ -132,6 +143,7 @@ export const AuditdGenericDetails = React.memo<GenericDetailsProps>(
<Details>
<AuditdGenericLine
id={id}
scopeId={timelineId}
contextId={contextId}
text={text}
hostName={hostName}

View file

@ -75,6 +75,7 @@ describe('GenericFileDetails', () => {
const wrapper = mount(
<TestProviders>
<AuditdGenericFileLine
scopeId="some_scope"
id="hello-i-am-an-id"
contextId="contextid-123"
text="generic-text-123"
@ -104,6 +105,7 @@ describe('GenericFileDetails', () => {
const wrapper = mount(
<TestProviders>
<AuditdGenericFileLine
scopeId="some_scope"
id="hello-i-am-an-id"
contextId="contextid-123"
text="generic-text-123"
@ -133,6 +135,7 @@ describe('GenericFileDetails', () => {
const wrapper = mount(
<TestProviders>
<AuditdGenericFileLine
scopeId="some_scope"
id="hello-i-am-an-id"
contextId="contextid-123"
text="generic-text-123"
@ -162,6 +165,7 @@ describe('GenericFileDetails', () => {
const wrapper = mount(
<TestProviders>
<AuditdGenericFileLine
scopeId="some_scope"
id="hello-i-am-an-id"
contextId="contextid-123"
text="generic-text-123"
@ -191,6 +195,7 @@ describe('GenericFileDetails', () => {
const wrapper = mount(
<TestProviders>
<AuditdGenericFileLine
scopeId="some_scope"
id="hello-i-am-an-id"
contextId="contextid-123"
text="generic-text-123"
@ -220,6 +225,7 @@ describe('GenericFileDetails', () => {
const wrapper = mount(
<TestProviders>
<AuditdGenericFileLine
scopeId="some_scope"
id="hello-i-am-an-id"
contextId="contextid-123"
text="generic-text-123"
@ -249,6 +255,7 @@ describe('GenericFileDetails', () => {
const wrapper = mount(
<TestProviders>
<AuditdGenericFileLine
scopeId="some_scope"
id="hello-i-am-an-id"
contextId="contextid-123"
text="generic-text-123"
@ -278,6 +285,7 @@ describe('GenericFileDetails', () => {
const wrapper = mount(
<TestProviders>
<AuditdGenericFileLine
scopeId="some_scope"
id="hello-i-am-an-id"
contextId="contextid-123"
text="generic-text-123"
@ -307,6 +315,7 @@ describe('GenericFileDetails', () => {
const wrapper = mount(
<TestProviders>
<AuditdGenericFileLine
scopeId="some_scope"
id="hello-i-am-an-id"
contextId="contextid-123"
text="generic-text-123"
@ -336,6 +345,7 @@ describe('GenericFileDetails', () => {
const wrapper = mount(
<TestProviders>
<AuditdGenericFileLine
scopeId="some_scope"
id="hello-i-am-an-id"
contextId="contextid-123"
text="generic-text-123"
@ -363,6 +373,7 @@ describe('GenericFileDetails', () => {
const wrapper = mount(
<TestProviders>
<AuditdGenericFileLine
scopeId="some_scope"
id="hello-i-am-an-id"
contextId="contextid-123"
text="generic-text-123"
@ -391,6 +402,7 @@ describe('GenericFileDetails', () => {
<TestProviders>
<AuditdGenericFileLine
id="hello-i-am-an-id"
scopeId="some_scope"
contextId="contextid-123"
text="generic-text-123"
userName="some-user-name"
@ -418,6 +430,7 @@ describe('GenericFileDetails', () => {
<TestProviders>
<AuditdGenericFileLine
id="hello-i-am-an-id"
scopeId="some_scope"
contextId="contextid-123"
text="generic-text-123"
fileIcon="document"
@ -445,6 +458,7 @@ describe('GenericFileDetails', () => {
<TestProviders>
<AuditdGenericFileLine
id="hello-i-am-an-id"
scopeId="some_scope"
contextId="contextid-123"
text="generic-text-123"
processTitle="some-process-title"
@ -472,6 +486,7 @@ describe('GenericFileDetails', () => {
<TestProviders>
<AuditdGenericFileLine
id="hello-i-am-an-id"
scopeId="some_scope"
contextId="contextid-123"
text="generic-text-123"
workingDirectory="some-working-directory"
@ -499,6 +514,7 @@ describe('GenericFileDetails', () => {
<TestProviders>
<AuditdGenericFileLine
id="hello-i-am-an-id"
scopeId="some_scope"
contextId="contextid-123"
text="generic-text-123"
args={['arg1', 'arg2', 'arg 3']}

View file

@ -38,6 +38,7 @@ interface Props {
workingDirectory: string | null | undefined;
args: string[] | null | undefined;
session: string | null | undefined;
scopeId: string;
}
export const AuditdGenericFileLine = React.memo<Props>(
@ -59,10 +60,12 @@ export const AuditdGenericFileLine = React.memo<Props>(
session,
text,
fileIcon,
scopeId,
}) => (
<EuiFlexGroup alignItems="center" justifyContent="center" gutterSize="none" wrap={true}>
<SessionUserHostWorkingDir
eventId={id}
scopeId={scopeId}
contextId={contextId}
hostName={hostName}
userName={userName}
@ -78,6 +81,7 @@ export const AuditdGenericFileLine = React.memo<Props>(
)}
<TokensFlexItem grow={false} component="span">
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={id}
field="file.path"
@ -92,6 +96,7 @@ export const AuditdGenericFileLine = React.memo<Props>(
)}
<TokensFlexItem grow={false} component="span">
<ProcessDraggable
scopeId={scopeId}
contextId={contextId}
endgamePid={undefined}
endgameProcessName={undefined}
@ -101,7 +106,13 @@ export const AuditdGenericFileLine = React.memo<Props>(
processExecutable={processExecutable}
/>
</TokensFlexItem>
<Args eventId={id} args={args} contextId={contextId} processTitle={processTitle} />
<Args
scopeId={scopeId}
eventId={id}
args={args}
contextId={contextId}
processTitle={processTitle}
/>
{result != null && (
<TokensFlexItem grow={false} component="span">
{i18n.WITH_RESULT}
@ -109,6 +120,7 @@ export const AuditdGenericFileLine = React.memo<Props>(
)}
<TokensFlexItem grow={false} component="span">
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={id}
field="auditd.result"
@ -152,6 +164,7 @@ export const AuditdGenericFileDetails = React.memo<GenericDetailsProps>(
<Details>
<AuditdGenericFileLine
id={id}
scopeId={timelineId}
contextId={contextId}
text={text}
hostName={hostName}

View file

@ -29,6 +29,7 @@ describe('UserPrimarySecondary', () => {
test('it renders the default PrimarySecondaryUserInfo', () => {
const wrapper = shallow(
<PrimarySecondaryUserInfo
scopeId="some_scope"
contextId="context-123"
eventId="event-123"
userName="user-name-1"
@ -43,6 +44,7 @@ describe('UserPrimarySecondary', () => {
const wrapper = mount(
<TestProviders>
<PrimarySecondaryUserInfo
scopeId="some_scope"
contextId="context-123"
eventId="event-123"
userName="user-name-1"
@ -58,6 +60,7 @@ describe('UserPrimarySecondary', () => {
const wrapper = mount(
<TestProviders>
<PrimarySecondaryUserInfo
scopeId="some_scope"
contextId="context-123"
eventId="event-123"
userName="user-name-1"
@ -73,6 +76,7 @@ describe('UserPrimarySecondary', () => {
const wrapper = mount(
<TestProviders>
<PrimarySecondaryUserInfo
scopeId="some_scope"
contextId="context-123"
eventId="event-123"
primary="primary-1"
@ -88,6 +92,7 @@ describe('UserPrimarySecondary', () => {
const wrapper = mount(
<TestProviders>
<PrimarySecondaryUserInfo
scopeId="some_scope"
contextId="context-123"
eventId="event-123"
primary="primary-1"
@ -103,6 +108,7 @@ describe('UserPrimarySecondary', () => {
const wrapper = mount(
<TestProviders>
<PrimarySecondaryUserInfo
scopeId="some_scope"
contextId="context-123"
eventId="event-123"
userName={undefined}
@ -118,6 +124,7 @@ describe('UserPrimarySecondary', () => {
const wrapper = mount(
<TestProviders>
<PrimarySecondaryUserInfo
scopeId="some_scope"
contextId="context-123"
eventId="event-123"
secondary="secondary-1"
@ -133,6 +140,7 @@ describe('UserPrimarySecondary', () => {
const wrapper = mount(
<TestProviders>
<PrimarySecondaryUserInfo
scopeId="some_scope"
contextId="context-123"
eventId="event-123"
userName="username-1"
@ -148,6 +156,7 @@ describe('UserPrimarySecondary', () => {
const wrapper = mount(
<TestProviders>
<PrimarySecondaryUserInfo
scopeId="some_scope"
contextId="context-123"
eventId="event-123"
userName="[username]"

View file

@ -21,79 +21,87 @@ interface Props {
eventId: string;
primary: string | null | undefined;
secondary: string | null | undefined;
scopeId: string;
}
export const PrimarySecondary = React.memo<Props>(({ contextId, eventId, primary, secondary }) => {
if (nilOrUnSet(primary) && nilOrUnSet(secondary)) {
return null;
} else if (!nilOrUnSet(primary) && nilOrUnSet(secondary)) {
return (
<DraggableBadge
contextId={contextId}
eventId={eventId}
field="auditd.summary.actor.primary"
value={primary}
iconType="user"
isAggregatable={true}
fieldType="keyword"
/>
);
} else if (nilOrUnSet(primary) && !nilOrUnSet(secondary)) {
return (
<DraggableBadge
contextId={contextId}
eventId={eventId}
field="auditd.summary.actor.secondary"
value={secondary}
iconType="user"
isAggregatable={true}
fieldType="keyword"
/>
);
} else if (primary === secondary) {
return (
<DraggableBadge
contextId={contextId}
eventId={eventId}
field="auditd.summary.actor.secondary"
value={secondary}
iconType="user"
isAggregatable={true}
fieldType="keyword"
/>
);
} else {
return (
<EuiFlexGroup gutterSize="none">
<TokensFlexItem grow={false} component="span">
<DraggableBadge
contextId={contextId}
eventId={eventId}
field="auditd.summary.actor.primary"
value={primary}
iconType="user"
isAggregatable={true}
fieldType="keyword"
/>
</TokensFlexItem>
<TokensFlexItem grow={false} component="span">
{i18n.AS}
</TokensFlexItem>
<TokensFlexItem grow={false} component="span">
<DraggableBadge
contextId={contextId}
eventId={eventId}
field="auditd.summary.actor.secondary"
value={secondary}
iconType="user"
isAggregatable={true}
fieldType="keyword"
/>
</TokensFlexItem>
</EuiFlexGroup>
);
export const PrimarySecondary = React.memo<Props>(
({ contextId, eventId, primary, secondary, scopeId }) => {
if (nilOrUnSet(primary) && nilOrUnSet(secondary)) {
return null;
} else if (!nilOrUnSet(primary) && nilOrUnSet(secondary)) {
return (
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={eventId}
field="auditd.summary.actor.primary"
value={primary}
iconType="user"
isAggregatable={true}
fieldType="keyword"
/>
);
} else if (nilOrUnSet(primary) && !nilOrUnSet(secondary)) {
return (
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={eventId}
field="auditd.summary.actor.secondary"
value={secondary}
iconType="user"
isAggregatable={true}
fieldType="keyword"
/>
);
} else if (primary === secondary) {
return (
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={eventId}
field="auditd.summary.actor.secondary"
value={secondary}
iconType="user"
isAggregatable={true}
fieldType="keyword"
/>
);
} else {
return (
<EuiFlexGroup gutterSize="none">
<TokensFlexItem grow={false} component="span">
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={eventId}
field="auditd.summary.actor.primary"
value={primary}
iconType="user"
isAggregatable={true}
fieldType="keyword"
/>
</TokensFlexItem>
<TokensFlexItem grow={false} component="span">
{i18n.AS}
</TokensFlexItem>
<TokensFlexItem grow={false} component="span">
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={eventId}
field="auditd.summary.actor.secondary"
value={secondary}
iconType="user"
isAggregatable={true}
fieldType="keyword"
/>
</TokensFlexItem>
</EuiFlexGroup>
);
}
}
});
);
PrimarySecondary.displayName = 'PrimarySecondary';
@ -103,10 +111,11 @@ interface PrimarySecondaryUserInfoProps {
userName: string | null | undefined;
primary: string | null | undefined;
secondary: string | null | undefined;
scopeId: string;
}
export const PrimarySecondaryUserInfo = React.memo<PrimarySecondaryUserInfoProps>(
({ contextId, eventId, userName, primary, secondary }) => {
({ contextId, eventId, userName, primary, secondary, scopeId }) => {
if (nilOrUnSet(userName) && nilOrUnSet(primary) && nilOrUnSet(secondary)) {
return null;
} else if (
@ -118,6 +127,7 @@ export const PrimarySecondaryUserInfo = React.memo<PrimarySecondaryUserInfoProps
) {
return (
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={eventId}
field="user.name"
@ -130,6 +140,7 @@ export const PrimarySecondaryUserInfo = React.memo<PrimarySecondaryUserInfoProps
} else if (!nilOrUnSet(userName) && nilOrUnSet(primary) && nilOrUnSet(secondary)) {
return (
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={eventId}
field="user.name"
@ -142,6 +153,7 @@ export const PrimarySecondaryUserInfo = React.memo<PrimarySecondaryUserInfoProps
} else {
return (
<PrimarySecondary
scopeId={scopeId}
contextId={contextId}
eventId={eventId}
primary={primary}

View file

@ -33,6 +33,7 @@ describe('SessionUserHostWorkingDir', () => {
<SessionUserHostWorkingDir
eventId="eventid-123"
session="session-123"
scopeId="some_scope"
contextId="contextid-123"
hostName="hostname-123"
userName="username-123"
@ -51,6 +52,7 @@ describe('SessionUserHostWorkingDir', () => {
<EuiFlexItem grow={false} component="span">
<SessionUserHostWorkingDir
eventId="eventid-123"
scopeId="some_scope"
contextId="contextid-123"
session={undefined}
hostName={undefined}
@ -71,6 +73,7 @@ describe('SessionUserHostWorkingDir', () => {
<EuiFlexItem grow={false} component="span">
<SessionUserHostWorkingDir
eventId="eventid-123"
scopeId="some_scope"
contextId="contextid-123"
session="session-123"
hostName={undefined}
@ -91,6 +94,7 @@ describe('SessionUserHostWorkingDir', () => {
<EuiFlexItem grow={false} component="span">
<SessionUserHostWorkingDir
eventId="eventid-123"
scopeId="some_scope"
contextId="contextid-123"
session="session-123"
hostName="hostname-123"
@ -111,6 +115,7 @@ describe('SessionUserHostWorkingDir', () => {
<EuiFlexItem grow={false} component="span">
<SessionUserHostWorkingDir
eventId="eventid-123"
scopeId="some_scope"
contextId="contextid-123"
session="session-123"
hostName="hostname-123"
@ -131,6 +136,7 @@ describe('SessionUserHostWorkingDir', () => {
<EuiFlexItem grow={false} component="span">
<SessionUserHostWorkingDir
eventId="eventid-123"
scopeId="some_scope"
contextId="contextid-123"
session="session-123"
hostName="hostname-123"
@ -151,6 +157,7 @@ describe('SessionUserHostWorkingDir', () => {
<EuiFlexItem grow={false} component="span">
<SessionUserHostWorkingDir
eventId="eventid-123"
scopeId="some_scope"
contextId="contextid-123"
session="session-123"
hostName="hostname-123"
@ -171,6 +178,7 @@ describe('SessionUserHostWorkingDir', () => {
<EuiFlexItem grow={false} component="span">
<SessionUserHostWorkingDir
eventId="eventid-123"
scopeId="some_scope"
contextId="contextid-123"
session="session-123"
hostName="hostname-123"

View file

@ -23,16 +23,28 @@ interface Props {
secondary: string | null | undefined;
workingDirectory: string | null | undefined;
session: string | null | undefined;
scopeId: string;
}
export const SessionUserHostWorkingDir = React.memo<Props>(
({ eventId, contextId, hostName, userName, primary, secondary, workingDirectory, session }) => (
({
eventId,
contextId,
hostName,
userName,
primary,
secondary,
workingDirectory,
session,
scopeId,
}) => (
<>
<TokensFlexItem grow={false} component="span">
{i18n.SESSION}
</TokensFlexItem>
<TokensFlexItem grow={false} component="span">
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={eventId}
field="auditd.session"
@ -44,6 +56,7 @@ export const SessionUserHostWorkingDir = React.memo<Props>(
</TokensFlexItem>
<TokensFlexItem grow={false} component="span">
<PrimarySecondaryUserInfo
scopeId={scopeId}
contextId={contextId}
eventId={eventId}
userName={userName}
@ -57,6 +70,7 @@ export const SessionUserHostWorkingDir = React.memo<Props>(
</TokensFlexItem>
)}
<HostWorkingDir
scopeId={scopeId}
contextId={contextId}
eventId={eventId}
workingDirectory={workingDirectory}

View file

@ -13,6 +13,7 @@ exports[`ThreatMatchRowView matches the registered snapshot 1`] = `
<MatchDetails
contextId="contextId"
eventId="eventId"
scopeId="some_scope"
sourceField="host.name"
sourceValue="http://elastic.co"
/>
@ -26,6 +27,7 @@ exports[`ThreatMatchRowView matches the registered snapshot 1`] = `
feedName="feedName"
indicatorReference="http://example.com"
indicatorType="domain"
scopeId="some_scope"
/>
</EuiFlexItem>
</EuiFlexGroup>

View file

@ -24,6 +24,7 @@ interface IndicatorDetailsProps {
feedName: string | undefined;
indicatorReference: string | undefined;
indicatorType: string | undefined;
scopeId: string;
}
export const IndicatorDetails: React.FC<IndicatorDetailsProps> = ({
@ -32,6 +33,7 @@ export const IndicatorDetails: React.FC<IndicatorDetailsProps> = ({
feedName,
indicatorReference,
indicatorType,
scopeId,
}) => (
<EuiFlexGroup
alignItems="flexStart"
@ -44,6 +46,7 @@ export const IndicatorDetails: React.FC<IndicatorDetailsProps> = ({
{indicatorType && (
<EuiFlexItem grow={false}>
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
data-test-subj="threat-match-indicator-details-indicator-type"
eventId={eventId}
@ -67,6 +70,7 @@ export const IndicatorDetails: React.FC<IndicatorDetailsProps> = ({
<EuiFlexItem grow={false}>
<DraggableBadge
contextId={contextId}
scopeId={scopeId}
data-test-subj="threat-match-indicator-details-indicator-feedName"
eventId={eventId}
field={FEED_NAME}

View file

@ -18,6 +18,7 @@ interface MatchDetailsProps {
eventId: string;
sourceField: string;
sourceValue: string;
scopeId: string;
}
export const MatchDetails: React.FC<MatchDetailsProps> = ({
@ -25,6 +26,7 @@ export const MatchDetails: React.FC<MatchDetailsProps> = ({
eventId,
sourceField,
sourceValue,
scopeId,
}) => (
<EuiFlexGroup
alignItems="center"
@ -36,6 +38,7 @@ export const MatchDetails: React.FC<MatchDetailsProps> = ({
>
<EuiFlexItem grow={false}>
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
data-test-subj="threat-match-details-source-field"
eventId={eventId}
@ -55,6 +58,7 @@ export const MatchDetails: React.FC<MatchDetailsProps> = ({
</EuiFlexItem>
<EuiFlexItem grow={false}>
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
data-test-subj="threat-match-details-source-value"
eventId={eventId}

View file

@ -21,6 +21,7 @@ describe('ThreatMatchRowView', () => {
it('renders an indicator match row', () => {
const wrapper = shallow(
<ThreatMatchRowView
scopeId="some_scope"
contextId="contextId"
eventId="eventId"
feedName="feedName"
@ -37,6 +38,7 @@ describe('ThreatMatchRowView', () => {
it('matches the registered snapshot', () => {
const wrapper = shallow(
<ThreatMatchRowView
scopeId="some_scope"
contextId="contextId"
eventId="eventId"
feedName="feedName"
@ -61,6 +63,7 @@ describe('ThreatMatchRowView', () => {
beforeEach(() => {
baseProps = {
scopeId: 'some_scope',
contextId: 'contextId',
eventId: 'eventId',
feedName: 'feedName',

View file

@ -28,16 +28,19 @@ export interface ThreatMatchRowProps {
indicatorType?: string;
sourceField: string;
sourceValue: string;
scopeId: string;
}
export const ThreatMatchRow = ({
contextId,
data,
eventId,
scopeId,
}: {
contextId: string;
data: Fields;
eventId: string;
scopeId: string;
}) => {
const props = {
contextId,
@ -47,6 +50,7 @@ export const ThreatMatchRow = ({
indicatorType: getOr([], MATCHED_TYPE, data)[0] as string | undefined,
sourceField: get(MATCHED_FIELD, data)[0] as string,
sourceValue: get(MATCHED_ATOMIC, data)[0] as string,
scopeId,
};
return <ThreatMatchRowView {...props} />;
@ -60,6 +64,7 @@ export const ThreatMatchRowView = ({
indicatorType,
sourceField,
sourceValue,
scopeId,
}: ThreatMatchRowProps) => {
return (
<EuiFlexGroup
@ -70,6 +75,7 @@ export const ThreatMatchRowView = ({
>
<EuiFlexItem grow={false}>
<MatchDetails
scopeId={scopeId}
contextId={contextId}
eventId={eventId}
sourceField={sourceField}
@ -78,6 +84,7 @@ export const ThreatMatchRowView = ({
</EuiFlexItem>
<EuiFlexItem grow={false}>
<IndicatorDetails
scopeId={scopeId}
contextId={contextId}
eventId={eventId}
feedName={feedName}

View file

@ -66,7 +66,12 @@ const ThreatMatchRowWrapper: FC<ThreatMatchRowProps> = ({ data, scopeId }) => {
const contextId = `threat-match-row-${scopeId}-${eventId}-${index}`;
return (
<Fragment key={contextId}>
<ThreatMatchRow contextId={contextId} data={indicator} eventId={eventId} />
<ThreatMatchRow
scopeId={scopeId}
contextId={contextId}
data={indicator}
eventId={eventId}
/>
{index < indicators.length - 1 && <EuiHorizontalRule margin="s" />}
</Fragment>
);

View file

@ -39,6 +39,7 @@ export const DnsRequestEventDetails = React.memo<Props>(({ data, contextId, time
return (
<Details>
<DnsRequestEventDetailsLine
scopeId={timelineId}
contextId={contextId}
dnsQuestionName={dnsQuestionName}
dnsQuestionType={dnsQuestionType}

View file

@ -10,6 +10,7 @@ import React from 'react';
import { TestProviders } from '../../../../../../common/mock';
import { DnsRequestEventDetailsLine } from './dns_request_event_details_line';
import { useMountAppended } from '../../../../../../common/utils/use_mount_appended';
import { CellActionsWrapper } from '../../../../../../common/components/drag_and_drop/cell_actions_wrapper';
jest.mock('../../../../../../common/lib/kibana');
@ -21,13 +22,27 @@ jest.mock('@elastic/eui', () => {
};
});
jest.mock('../../../../../../common/components/drag_and_drop/cell_actions_wrapper', () => {
return {
CellActionsWrapper: jest.fn(),
};
});
const MockedCellActionsWrapper = jest.fn(({ children }) => {
return <div data-test-subj="mock-cell-action-wrapper">{children}</div>;
});
describe('DnsRequestEventDetailsLine', () => {
beforeEach(() => {
(CellActionsWrapper as unknown as jest.Mock).mockImplementation(MockedCellActionsWrapper);
});
const mount = useMountAppended();
test('it renders the expected text when all properties are provided', () => {
const wrapper = mount(
<TestProviders>
<DnsRequestEventDetailsLine
scopeId="some_scope"
contextId="test"
dnsQuestionName="[dnsQuestionName]"
dnsQuestionType="[dnsQuestionType]"
@ -54,6 +69,7 @@ describe('DnsRequestEventDetailsLine', () => {
const wrapper = mount(
<TestProviders>
<DnsRequestEventDetailsLine
scopeId="some_scope"
contextId="test"
dnsQuestionName={undefined}
dnsQuestionType="[dnsQuestionType]"
@ -80,6 +96,7 @@ describe('DnsRequestEventDetailsLine', () => {
const wrapper = mount(
<TestProviders>
<DnsRequestEventDetailsLine
scopeId="some_scope"
contextId="test"
dnsQuestionName="[dnsQuestionName]"
dnsQuestionType={undefined}
@ -106,6 +123,7 @@ describe('DnsRequestEventDetailsLine', () => {
const wrapper = mount(
<TestProviders>
<DnsRequestEventDetailsLine
scopeId="some_scope"
contextId="test"
dnsQuestionName="[dnsQuestionName]"
dnsQuestionType="[dnsQuestionType]"
@ -132,6 +150,7 @@ describe('DnsRequestEventDetailsLine', () => {
const wrapper = mount(
<TestProviders>
<DnsRequestEventDetailsLine
scopeId="some_scope"
contextId="test"
dnsQuestionName="[dnsQuestionName]"
dnsQuestionType="[dnsQuestionType]"
@ -158,6 +177,7 @@ describe('DnsRequestEventDetailsLine', () => {
const wrapper = mount(
<TestProviders>
<DnsRequestEventDetailsLine
scopeId="some_scope"
contextId="test"
dnsQuestionName="[dnsQuestionName]"
dnsQuestionType="[dnsQuestionType]"
@ -184,6 +204,7 @@ describe('DnsRequestEventDetailsLine', () => {
const wrapper = mount(
<TestProviders>
<DnsRequestEventDetailsLine
scopeId="some_scope"
contextId="test"
dnsQuestionName="[dnsQuestionName]"
dnsQuestionType="[dnsQuestionType]"
@ -210,6 +231,7 @@ describe('DnsRequestEventDetailsLine', () => {
const wrapper = mount(
<TestProviders>
<DnsRequestEventDetailsLine
scopeId="some_scope"
contextId="test"
dnsQuestionName="[dnsQuestionName]"
dnsQuestionType="[dnsQuestionType]"
@ -236,6 +258,7 @@ describe('DnsRequestEventDetailsLine', () => {
const wrapper = mount(
<TestProviders>
<DnsRequestEventDetailsLine
scopeId="some_scope"
contextId="test"
dnsQuestionName="[dnsQuestionName]"
dnsQuestionType="[dnsQuestionType]"
@ -262,6 +285,7 @@ describe('DnsRequestEventDetailsLine', () => {
const wrapper = mount(
<TestProviders>
<DnsRequestEventDetailsLine
scopeId="some_scope"
contextId="test"
dnsQuestionName="[dnsQuestionName]"
dnsQuestionType="[dnsQuestionType]"
@ -288,6 +312,7 @@ describe('DnsRequestEventDetailsLine', () => {
const wrapper = mount(
<TestProviders>
<DnsRequestEventDetailsLine
scopeId="some_scope"
contextId="test"
dnsQuestionName="[dnsQuestionName]"
dnsQuestionType="[dnsQuestionType]"
@ -314,6 +339,7 @@ describe('DnsRequestEventDetailsLine', () => {
const wrapper = mount(
<TestProviders>
<DnsRequestEventDetailsLine
scopeId="some_scope"
contextId="test"
dnsQuestionName="[dnsQuestionName]"
dnsQuestionType="[dnsQuestionType]"
@ -340,6 +366,7 @@ describe('DnsRequestEventDetailsLine', () => {
const wrapper = mount(
<TestProviders>
<DnsRequestEventDetailsLine
scopeId="some_scope"
contextId="test"
dnsQuestionName="[dnsQuestionName]"
dnsQuestionType="[dnsQuestionType]"
@ -366,6 +393,7 @@ describe('DnsRequestEventDetailsLine', () => {
const wrapper = mount(
<TestProviders>
<DnsRequestEventDetailsLine
scopeId="some_scope"
contextId="test"
dnsQuestionName="[dnsQuestionName]"
dnsQuestionType="[dnsQuestionType]"
@ -387,4 +415,35 @@ describe('DnsRequestEventDetailsLine', () => {
'[userName]\\[userDomain]@[hostName]asked for[dnsQuestionName]with question type[dnsQuestionType], which resolved to[dnsResolvedIp](response code:[dnsResponseCode])via[processName](123)'
);
});
test('should passing correct scopeId to cell actions', () => {
mount(
<TestProviders>
<DnsRequestEventDetailsLine
scopeId="some_scope"
contextId="test"
dnsQuestionName="[dnsQuestionName]"
dnsQuestionType="[dnsQuestionType]"
dnsResolvedIp="[dnsResolvedIp]"
dnsResponseCode="[dnsResponseCode]"
eventCode={null}
hostName="[hostName]"
id="1"
processExecutable="[processExecutable]"
processName="[processName]"
processPid={123}
userDomain="[userDomain]"
userName="[userName]"
winlogEventId={undefined}
/>
</TestProviders>
);
expect(MockedCellActionsWrapper).toHaveBeenCalledWith(
expect.objectContaining({
scopeId: 'some_scope',
}),
{}
);
});
});

View file

@ -30,6 +30,7 @@ interface Props {
userDomain: string | null | undefined;
userName: string | null | undefined;
winlogEventId: string | null | undefined;
scopeId: string;
}
export const DnsRequestEventDetailsLine = React.memo<Props>(
@ -48,11 +49,13 @@ export const DnsRequestEventDetailsLine = React.memo<Props>(
userDomain,
userName,
winlogEventId,
scopeId,
}) => {
return (
<>
<EuiFlexGroup alignItems="center" justifyContent="center" gutterSize="none" wrap={true}>
<UserHostWorkingDir
scopeId={scopeId}
contextId={contextId}
eventId={id}
hostName={hostName}
@ -68,6 +71,7 @@ export const DnsRequestEventDetailsLine = React.memo<Props>(
</TokensFlexItem>
<TokensFlexItem component="span" grow={false}>
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={id}
field="dns.question.name"
@ -86,6 +90,7 @@ export const DnsRequestEventDetailsLine = React.memo<Props>(
</TokensFlexItem>
<TokensFlexItem component="span" grow={false}>
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={id}
field="dns.question.type"
@ -104,6 +109,7 @@ export const DnsRequestEventDetailsLine = React.memo<Props>(
</TokensFlexItem>
<TokensFlexItem component="span" grow={false}>
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={id}
field="dns.resolved_ip"
@ -125,6 +131,7 @@ export const DnsRequestEventDetailsLine = React.memo<Props>(
</TokensFlexItem>
<TokensFlexItem component="span" grow={false}>
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={id}
field="dns.response_code"
@ -145,6 +152,7 @@ export const DnsRequestEventDetailsLine = React.memo<Props>(
<TokensFlexItem component="span" grow={false}>
<ProcessDraggableWithNonExistentProcess
scopeId={scopeId}
contextId={contextId}
endgamePid={undefined}
endgameProcessName={undefined}
@ -160,6 +168,7 @@ export const DnsRequestEventDetailsLine = React.memo<Props>(
{!isNillEmptyOrNotFinite(eventCode) ? (
<TokensFlexItem component="span" grow={false}>
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={id}
field="event.code"
@ -171,6 +180,7 @@ export const DnsRequestEventDetailsLine = React.memo<Props>(
) : (
<TokensFlexItem component="span" grow={false}>
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={id}
iconType="logoWindows"

View file

@ -53,6 +53,7 @@ export const EndgameSecurityEventDetails = React.memo<Props>(({ data, contextId,
return (
<Details>
<EndgameSecurityEventDetailsLine
scopeId={timelineId}
contextId={contextId}
endgameLogonType={endgameLogonType}
endgameSubjectDomainName={endgameSubjectDomainName}

View file

@ -11,6 +11,7 @@ import { TestProviders } from '../../../../../../common/mock';
import { EndgameSecurityEventDetailsLine } from './endgame_security_event_details_line';
import { useMountAppended } from '../../../../../../common/utils/use_mount_appended';
import { CellActionsWrapper } from '../../../../../../common/components/drag_and_drop/cell_actions_wrapper';
jest.mock('../../../../../../common/lib/kibana');
@ -22,13 +23,27 @@ jest.mock('@elastic/eui', () => {
};
});
jest.mock('../../../../../../common/components/drag_and_drop/cell_actions_wrapper', () => {
return {
CellActionsWrapper: jest.fn(),
};
});
const MockedCellActionsWrapper = jest.fn(({ children }) => {
return <div data-test-subj="mock-cell-action-wrapper">{children}</div>;
});
describe('EndgameSecurityEventDetailsLine', () => {
beforeEach(() => {
(CellActionsWrapper as unknown as jest.Mock).mockImplementation(MockedCellActionsWrapper);
});
const mount = useMountAppended();
test('it renders the expected text when all properties are provided and event action is admin_logon', () => {
const wrapper = mount(
<TestProviders>
<EndgameSecurityEventDetailsLine
scopeId="some_scope"
contextId="test"
endgameLogonType={2}
endgameSubjectDomainName="[endgameSubjectDomainName]"
@ -60,6 +75,7 @@ describe('EndgameSecurityEventDetailsLine', () => {
const wrapper = mount(
<TestProviders>
<EndgameSecurityEventDetailsLine
scopeId="some_scope"
contextId="test"
endgameLogonType={2}
endgameSubjectDomainName="[endgameSubjectDomainName]"
@ -91,6 +107,7 @@ describe('EndgameSecurityEventDetailsLine', () => {
const wrapper = mount(
<TestProviders>
<EndgameSecurityEventDetailsLine
scopeId="some_scope"
contextId="test"
endgameLogonType={undefined}
endgameSubjectDomainName="[endgameSubjectDomainName]"
@ -122,6 +139,7 @@ describe('EndgameSecurityEventDetailsLine', () => {
const wrapper = mount(
<TestProviders>
<EndgameSecurityEventDetailsLine
scopeId="some_scope"
contextId="test"
endgameLogonType={2}
endgameSubjectDomainName={undefined}
@ -153,6 +171,7 @@ describe('EndgameSecurityEventDetailsLine', () => {
const wrapper = mount(
<TestProviders>
<EndgameSecurityEventDetailsLine
scopeId="some_scope"
contextId="test"
endgameLogonType={2}
endgameSubjectDomainName="[endgameSubjectDomainName]"
@ -184,6 +203,7 @@ describe('EndgameSecurityEventDetailsLine', () => {
const wrapper = mount(
<TestProviders>
<EndgameSecurityEventDetailsLine
scopeId="some_scope"
contextId="test"
endgameLogonType={2}
endgameSubjectDomainName="[endgameSubjectDomainName]"
@ -215,6 +235,7 @@ describe('EndgameSecurityEventDetailsLine', () => {
const wrapper = mount(
<TestProviders>
<EndgameSecurityEventDetailsLine
scopeId="some_scope"
contextId="test"
endgameLogonType={2}
endgameSubjectDomainName="[endgameSubjectDomainName]"
@ -246,6 +267,7 @@ describe('EndgameSecurityEventDetailsLine', () => {
const wrapper = mount(
<TestProviders>
<EndgameSecurityEventDetailsLine
scopeId="some_scope"
contextId="test"
endgameLogonType={2}
endgameSubjectDomainName="[endgameSubjectDomainName]"
@ -277,6 +299,7 @@ describe('EndgameSecurityEventDetailsLine', () => {
const wrapper = mount(
<TestProviders>
<EndgameSecurityEventDetailsLine
scopeId="some_scope"
contextId="test"
endgameLogonType={2}
endgameSubjectDomainName="[endgameSubjectDomainName]"
@ -308,6 +331,7 @@ describe('EndgameSecurityEventDetailsLine', () => {
const wrapper = mount(
<TestProviders>
<EndgameSecurityEventDetailsLine
scopeId="some_scope"
contextId="test"
endgameLogonType={2}
endgameSubjectDomainName="[endgameSubjectDomainName]"
@ -339,6 +363,7 @@ describe('EndgameSecurityEventDetailsLine', () => {
const wrapper = mount(
<TestProviders>
<EndgameSecurityEventDetailsLine
scopeId="some_scope"
contextId="test"
endgameLogonType={2}
endgameSubjectDomainName="[endgameSubjectDomainName]"
@ -370,6 +395,7 @@ describe('EndgameSecurityEventDetailsLine', () => {
const wrapper = mount(
<TestProviders>
<EndgameSecurityEventDetailsLine
scopeId="some_scope"
contextId="test"
endgameLogonType={2}
endgameSubjectDomainName="[endgameSubjectDomainName]"
@ -401,6 +427,7 @@ describe('EndgameSecurityEventDetailsLine', () => {
const wrapper = mount(
<TestProviders>
<EndgameSecurityEventDetailsLine
scopeId="some_scope"
contextId="test"
endgameLogonType={2}
endgameSubjectDomainName="[endgameSubjectDomainName]"
@ -432,6 +459,7 @@ describe('EndgameSecurityEventDetailsLine', () => {
const wrapper = mount(
<TestProviders>
<EndgameSecurityEventDetailsLine
scopeId="some_scope"
contextId="test"
endgameLogonType={2}
endgameSubjectDomainName="[endgameSubjectDomainName]"
@ -463,6 +491,7 @@ describe('EndgameSecurityEventDetailsLine', () => {
const wrapper = mount(
<TestProviders>
<EndgameSecurityEventDetailsLine
scopeId="some_scope"
contextId="test"
endgameLogonType={2}
endgameSubjectDomainName="[endgameSubjectDomainName]"
@ -494,6 +523,7 @@ describe('EndgameSecurityEventDetailsLine', () => {
const wrapper = mount(
<TestProviders>
<EndgameSecurityEventDetailsLine
scopeId="some_scope"
contextId="test"
endgameLogonType={2}
endgameSubjectDomainName="[endgameSubjectDomainName]"
@ -525,6 +555,7 @@ describe('EndgameSecurityEventDetailsLine', () => {
const wrapper = mount(
<TestProviders>
<EndgameSecurityEventDetailsLine
scopeId="some_scope"
contextId="test"
endgameLogonType={2}
endgameSubjectDomainName="[endgameSubjectDomainName]"
@ -556,6 +587,7 @@ describe('EndgameSecurityEventDetailsLine', () => {
const wrapper = mount(
<TestProviders>
<EndgameSecurityEventDetailsLine
scopeId="some_scope"
contextId="test"
endgameLogonType={2}
endgameSubjectDomainName="[endgameSubjectDomainName]"
@ -587,6 +619,7 @@ describe('EndgameSecurityEventDetailsLine', () => {
const wrapper = mount(
<TestProviders>
<EndgameSecurityEventDetailsLine
scopeId="some_scope"
contextId="test"
endgameLogonType={2}
endgameSubjectDomainName="[endgameSubjectDomainName]"
@ -613,4 +646,40 @@ describe('EndgameSecurityEventDetailsLine', () => {
'With special privileges,[userName]\\[userDomain]@[hostName]successfully logged inusing logon type2 - Interactive(target logon ID[endgameTargetLogonId])via[processName](123)as requested by subject[endgameSubjectUserName]\\[endgameSubjectDomainName](subject logon ID[endgameSubjectLogonId])'
);
});
test('should passing correct scopeId to cell actions', () => {
mount(
<TestProviders>
<EndgameSecurityEventDetailsLine
scopeId="some_scope"
contextId="test"
endgameLogonType={2}
endgameSubjectDomainName="[endgameSubjectDomainName]"
endgameSubjectLogonId="[endgameSubjectLogonId]"
endgameSubjectUserName="[endgameSubjectUserName]"
endgameTargetDomainName="[endgameTargetDomainName]"
endgameTargetLogonId="[endgameTargetLogonId]"
endgameTargetUserName="[endgameTargetUserName]"
eventAction="admin_logon"
eventCode={undefined}
eventOutcome={undefined}
hostName="[hostName]"
id="1"
processExecutable="[processExecutable]"
processName="[processName]"
processPid={123}
userDomain="[userDomain]"
userName="[userName]"
winlogEventId={undefined}
/>
</TestProviders>
);
expect(MockedCellActionsWrapper).toHaveBeenCalledWith(
expect.objectContaining({
scopeId: 'some_scope',
}),
{}
);
});
});

View file

@ -44,6 +44,7 @@ interface Props {
userDomain: string | null | undefined;
userName: string | null | undefined;
winlogEventId: string | null | undefined;
scopeId: string;
}
export const EndgameSecurityEventDetailsLine = React.memo<Props>(
@ -67,6 +68,7 @@ export const EndgameSecurityEventDetailsLine = React.memo<Props>(
userDomain,
userName,
winlogEventId,
scopeId,
}) => {
const domain = getTargetUserAndTargetDomain(eventAction) ? endgameTargetDomainName : userDomain;
const eventDetails = getEventDetails({ eventAction, eventOutcome });
@ -91,6 +93,7 @@ export const EndgameSecurityEventDetailsLine = React.memo<Props>(
)}
<UserHostWorkingDir
scopeId={scopeId}
contextId={contextId}
eventId={id}
hostName={hostName}
@ -113,6 +116,7 @@ export const EndgameSecurityEventDetailsLine = React.memo<Props>(
</TokensFlexItem>
<TokensFlexItem component="span" grow={false}>
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={id}
field="endgame.logon_type"
@ -135,6 +139,7 @@ export const EndgameSecurityEventDetailsLine = React.memo<Props>(
</TokensFlexItem>
<TokensFlexItem component="span" grow={false}>
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={id}
field="endgame.target_logon_id"
@ -155,6 +160,7 @@ export const EndgameSecurityEventDetailsLine = React.memo<Props>(
<TokensFlexItem component="span" grow={false}>
<ProcessDraggableWithNonExistentProcess
scopeId={scopeId}
contextId={contextId}
endgamePid={undefined}
endgameProcessName={undefined}
@ -177,6 +183,7 @@ export const EndgameSecurityEventDetailsLine = React.memo<Props>(
<TokensFlexItem component="span" grow={false}>
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={id}
field="endgame.subject_user_name"
@ -200,6 +207,7 @@ export const EndgameSecurityEventDetailsLine = React.memo<Props>(
</TokensFlexItem>
<TokensFlexItem component="span" grow={false}>
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={id}
field="endgame.subject_domain_name"
@ -221,6 +229,7 @@ export const EndgameSecurityEventDetailsLine = React.memo<Props>(
</TokensFlexItem>
<TokensFlexItem component="span" grow={false}>
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={id}
field="endgame.subject_logon_id"
@ -240,6 +249,7 @@ export const EndgameSecurityEventDetailsLine = React.memo<Props>(
{!isNillEmptyOrNotFinite(eventCode) ? (
<TokensFlexItem component="span" grow={false}>
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={id}
field="event.code"
@ -251,6 +261,7 @@ export const EndgameSecurityEventDetailsLine = React.memo<Props>(
) : (
<TokensFlexItem component="span" grow={false}>
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={id}
iconType="logoWindows"

View file

@ -9,6 +9,7 @@ import React from 'react';
import { TestProviders } from '../../../../../common/mock';
import { useMountAppended } from '../../../../../common/utils/use_mount_appended';
import { CellActionsWrapper } from '../../../../../common/components/drag_and_drop/cell_actions_wrapper';
import { ExitCodeDraggable } from './exit_code_draggable';
@ -22,13 +23,27 @@ jest.mock('@elastic/eui', () => {
};
});
jest.mock('../../../../../common/components/drag_and_drop/cell_actions_wrapper', () => {
return {
CellActionsWrapper: jest.fn(),
};
});
const MockedCellActionsWrapper = jest.fn(({ children }) => {
return <div data-test-subj="mock-cell-action-wrapper">{children}</div>;
});
describe('ExitCodeDraggable', () => {
beforeEach(() => {
(CellActionsWrapper as unknown as jest.Mock).mockImplementation(MockedCellActionsWrapper);
});
const mount = useMountAppended();
test('it renders the expected text and exit codes, when text, processExitCode, and an endgameExitCode are provided', () => {
const wrapper = mount(
<TestProviders>
<ExitCodeDraggable
scopeId="some_scope"
contextId="test"
endgameExitCode="0"
eventId="1"
@ -44,6 +59,7 @@ describe('ExitCodeDraggable', () => {
const wrapper = mount(
<TestProviders>
<ExitCodeDraggable
scopeId="some_scope"
contextId="test"
endgameExitCode={undefined}
eventId="1"
@ -59,6 +75,7 @@ describe('ExitCodeDraggable', () => {
const wrapper = mount(
<TestProviders>
<ExitCodeDraggable
scopeId="some_scope"
contextId="test"
endgameExitCode={null}
eventId="1"
@ -74,6 +91,7 @@ describe('ExitCodeDraggable', () => {
const wrapper = mount(
<TestProviders>
<ExitCodeDraggable
scopeId="some_scope"
contextId="test"
endgameExitCode=""
eventId="1"
@ -89,6 +107,7 @@ describe('ExitCodeDraggable', () => {
const wrapper = mount(
<TestProviders>
<ExitCodeDraggable
scopeId="some_scope"
contextId="test"
endgameExitCode="1"
eventId="1"
@ -104,6 +123,7 @@ describe('ExitCodeDraggable', () => {
const wrapper = mount(
<TestProviders>
<ExitCodeDraggable
scopeId="some_scope"
contextId="test"
endgameExitCode={undefined}
eventId="1"
@ -119,6 +139,7 @@ describe('ExitCodeDraggable', () => {
const wrapper = mount(
<TestProviders>
<ExitCodeDraggable
scopeId="some_scope"
contextId="test"
endgameExitCode="1"
eventId="1"
@ -134,6 +155,7 @@ describe('ExitCodeDraggable', () => {
const wrapper = mount(
<TestProviders>
<ExitCodeDraggable
scopeId="some_scope"
contextId="test"
endgameExitCode={undefined}
eventId="1"
@ -149,6 +171,7 @@ describe('ExitCodeDraggable', () => {
const wrapper = mount(
<TestProviders>
<ExitCodeDraggable
scopeId="some_scope"
contextId="test"
endgameExitCode="1"
eventId="1"
@ -164,6 +187,7 @@ describe('ExitCodeDraggable', () => {
const wrapper = mount(
<TestProviders>
<ExitCodeDraggable
scopeId="some_scope"
contextId="test"
endgameExitCode={undefined}
eventId="1"
@ -174,4 +198,26 @@ describe('ExitCodeDraggable', () => {
);
expect(wrapper.text()).toEqual('-1');
});
test('should passing correct scopeId to cell actions', () => {
mount(
<TestProviders>
<ExitCodeDraggable
scopeId="some_scope"
contextId="test"
endgameExitCode={undefined}
eventId="1"
processExitCode={-1}
text=""
/>
</TestProviders>
);
expect(MockedCellActionsWrapper).toHaveBeenCalledWith(
expect.objectContaining({
scopeId: 'some_scope',
}),
{}
);
});
});

View file

@ -17,10 +17,11 @@ interface Props {
eventId: string;
processExitCode: number | null | undefined;
text: string | null | undefined;
scopeId: string;
}
export const ExitCodeDraggable = React.memo<Props>(
({ contextId, endgameExitCode, eventId, processExitCode, text }) => {
({ contextId, endgameExitCode, eventId, processExitCode, text, scopeId }) => {
if (isNillEmptyOrNotFinite(processExitCode) && isNillEmptyOrNotFinite(endgameExitCode)) {
return null;
}
@ -36,6 +37,7 @@ export const ExitCodeDraggable = React.memo<Props>(
{!isNillEmptyOrNotFinite(processExitCode) && (
<TokensFlexItem grow={false} component="span">
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={eventId}
field="process.exit_code"
@ -49,6 +51,7 @@ export const ExitCodeDraggable = React.memo<Props>(
{!isNillEmptyOrNotFinite(endgameExitCode) && (
<TokensFlexItem grow={false} component="span">
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={eventId}
field="endgame.exit_code"

View file

@ -11,6 +11,7 @@ import { TestProviders } from '../../../../../common/mock';
import { FileDraggable } from './file_draggable';
import { useMountAppended } from '../../../../../common/utils/use_mount_appended';
import { CellActionsWrapper } from '../../../../../common/components/drag_and_drop/cell_actions_wrapper';
jest.mock('../../../../../common/lib/kibana');
@ -22,13 +23,27 @@ jest.mock('@elastic/eui', () => {
};
});
jest.mock('../../../../../common/components/drag_and_drop/cell_actions_wrapper', () => {
return {
CellActionsWrapper: jest.fn(),
};
});
const MockedCellActionsWrapper = jest.fn(({ children }) => {
return <div data-test-subj="mock-cell-action-wrapper">{children}</div>;
});
describe('FileDraggable', () => {
beforeEach(() => {
(CellActionsWrapper as unknown as jest.Mock).mockImplementation(MockedCellActionsWrapper);
});
const mount = useMountAppended();
test('it prefers fileName and filePath over endgameFileName and endgameFilePath when all of them are provided', () => {
const wrapper = mount(
<TestProviders>
<FileDraggable
scopeId="some_scope"
contextId="test"
endgameFileName="[endgameFileName]"
endgameFilePath="[endgameFilePath]"
@ -48,6 +63,7 @@ describe('FileDraggable', () => {
const wrapper = mount(
<TestProviders>
<FileDraggable
scopeId="some_scope"
contextId="test"
endgameFileName={undefined}
endgameFilePath={undefined}
@ -65,6 +81,7 @@ describe('FileDraggable', () => {
const wrapper = mount(
<TestProviders>
<FileDraggable
scopeId="some_scope"
contextId="test"
endgameFileName="[endgameFileName]"
endgameFilePath={undefined}
@ -82,6 +99,7 @@ describe('FileDraggable', () => {
const wrapper = mount(
<TestProviders>
<FileDraggable
scopeId="some_scope"
contextId="test"
endgameFileName={undefined}
endgameFilePath="[endgameFilePath]"
@ -99,6 +117,7 @@ describe('FileDraggable', () => {
const wrapper = mount(
<TestProviders>
<FileDraggable
scopeId="some_scope"
contextId="test"
endgameFileName={undefined}
endgameFilePath={undefined}
@ -116,6 +135,7 @@ describe('FileDraggable', () => {
const wrapper = mount(
<TestProviders>
<FileDraggable
scopeId="some_scope"
contextId="test"
endgameFileName={undefined}
endgameFilePath={undefined}
@ -128,4 +148,28 @@ describe('FileDraggable', () => {
);
expect(wrapper.text()).toEqual('in[filePath]');
});
test('should passing correct scopeId to cell actions', () => {
mount(
<TestProviders>
<FileDraggable
scopeId="some_scope"
contextId="test"
endgameFileName={undefined}
endgameFilePath={undefined}
eventId="1"
fileExtOriginalPath={undefined}
fileName={undefined}
filePath="[filePath]"
/>
</TestProviders>
);
expect(MockedCellActionsWrapper).toHaveBeenCalledWith(
expect.objectContaining({
scopeId: 'some_scope',
}),
{}
);
});
});

View file

@ -20,6 +20,7 @@ interface Props {
fileName: string | null | undefined;
filePath: string | null | undefined;
fileExtOriginalPath: string | null | undefined;
scopeId: string;
}
export const FileDraggable = React.memo<Props>(
@ -31,6 +32,7 @@ export const FileDraggable = React.memo<Props>(
fileExtOriginalPath,
fileName,
filePath,
scopeId,
}) => {
if (
isNillEmptyOrNotFinite(fileName) &&
@ -49,6 +51,7 @@ export const FileDraggable = React.memo<Props>(
{!isNillEmptyOrNotFinite(fileName) ? (
<TokensFlexItem grow={false} component="span">
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={eventId}
field="file.name"
@ -61,6 +64,7 @@ export const FileDraggable = React.memo<Props>(
) : !isNillEmptyOrNotFinite(endgameFileName) ? (
<TokensFlexItem grow={false} component="span">
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={eventId}
field="endgame.file_name"
@ -81,6 +85,7 @@ export const FileDraggable = React.memo<Props>(
{!isNillEmptyOrNotFinite(filePath) ? (
<TokensFlexItem grow={false} component="span">
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={eventId}
field="file.path"
@ -93,6 +98,7 @@ export const FileDraggable = React.memo<Props>(
) : !isNillEmptyOrNotFinite(endgameFilePath) ? (
<TokensFlexItem grow={false} component="span">
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={eventId}
field="endgame.file_path"
@ -111,6 +117,7 @@ export const FileDraggable = React.memo<Props>(
</TokensFlexItem>
<TokensFlexItem grow={false} component="span">
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={eventId}
field="file.Ext.original.path"

View file

@ -9,6 +9,7 @@ import React from 'react';
import { TestProviders } from '../../../../../common/mock';
import { useMountAppended } from '../../../../../common/utils/use_mount_appended';
import { CellActionsWrapper } from '../../../../../common/components/drag_and_drop/cell_actions_wrapper';
import { FileHash } from './file_hash';
@ -22,10 +23,24 @@ jest.mock('@elastic/eui', () => {
};
});
jest.mock('../../../../../common/components/drag_and_drop/cell_actions_wrapper', () => {
return {
CellActionsWrapper: jest.fn(),
};
});
const MockedCellActionsWrapper = jest.fn(({ children }) => {
return <div data-test-subj="mock-cell-action-wrapper">{children}</div>;
});
describe('FileHash', () => {
beforeEach(() => {
(CellActionsWrapper as unknown as jest.Mock).mockImplementation(MockedCellActionsWrapper);
});
const mount = useMountAppended();
const allProps = {
scopeId: 'some_scope',
contextId: 'test',
eventId: '1',
fileHashSha256: undefined,
@ -57,4 +72,18 @@ describe('FileHash', () => {
);
expect(wrapper.text()).toEqual('');
});
test('should passing correct scopeId to cell actions', () => {
mount(
<TestProviders>
<FileHash {...allProps} />
</TestProviders>
);
expect(MockedCellActionsWrapper).toHaveBeenCalledWith(
expect.objectContaining({
scopeId: 'some_scope',
}),
{}
);
});
});

View file

@ -21,9 +21,10 @@ interface Props {
contextId: string;
eventId: string;
fileHashSha256: string | null | undefined;
scopeId: string;
}
export const FileHash = React.memo<Props>(({ contextId, eventId, fileHashSha256 }) => {
export const FileHash = React.memo<Props>(({ contextId, eventId, fileHashSha256, scopeId }) => {
if (isNillEmptyOrNotFinite(fileHashSha256)) {
return null;
}
@ -32,6 +33,7 @@ export const FileHash = React.memo<Props>(({ contextId, eventId, fileHashSha256
<HashFlexGroup alignItems="center" direction="column" gutterSize="none">
<TokensFlexItem grow={false} component="div">
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={eventId}
field="file.hash.sha256"

View file

@ -11,6 +11,7 @@ import React from 'react';
import { mockTimelineData, TestProviders } from '../../../../../common/mock';
import { useMountAppended } from '../../../../../common/utils/use_mount_appended';
import { HostWorkingDir } from './host_working_dir';
import { CellActionsWrapper } from '../../../../../common/components/drag_and_drop/cell_actions_wrapper';
jest.mock('../../../../../common/lib/kibana');
@ -22,13 +23,27 @@ jest.mock('@elastic/eui', () => {
};
});
jest.mock('../../../../../common/components/drag_and_drop/cell_actions_wrapper', () => {
return {
CellActionsWrapper: jest.fn(),
};
});
const MockedCellActionsWrapper = jest.fn(({ children }) => {
return <div data-test-subj="mock-cell-action-wrapper">{children}</div>;
});
describe('HostWorkingDir', () => {
beforeEach(() => {
(CellActionsWrapper as unknown as jest.Mock).mockImplementation(MockedCellActionsWrapper);
});
const mount = useMountAppended();
test('renders correctly against snapshot', () => {
const wrapper = shallow(
<HostWorkingDir
eventId={mockTimelineData[0].ecs._id}
scopeId="some_scope"
contextId="test"
hostName="[hostname-123]"
workingDirectory="[working-directory-123]"
@ -43,6 +58,7 @@ describe('HostWorkingDir', () => {
<div>
<HostWorkingDir
eventId={mockTimelineData[0].ecs._id}
scopeId="some_scope"
contextId="test"
hostName="[hostname-123]"
workingDirectory={undefined}
@ -60,6 +76,7 @@ describe('HostWorkingDir', () => {
<div>
<HostWorkingDir
eventId={mockTimelineData[0].ecs._id}
scopeId="some_scope"
contextId="test"
hostName="[hostname-123]"
workingDirectory={null}
@ -77,6 +94,7 @@ describe('HostWorkingDir', () => {
<div>
<HostWorkingDir
eventId={mockTimelineData[0].ecs._id}
scopeId="some_scope"
contextId="test"
hostName={undefined}
workingDirectory="[working-directory-123]"
@ -94,6 +112,7 @@ describe('HostWorkingDir', () => {
<div>
<HostWorkingDir
eventId={mockTimelineData[0].ecs._id}
scopeId="some_scope"
contextId="test"
hostName={null}
workingDirectory="[working-directory-123]"
@ -104,4 +123,27 @@ describe('HostWorkingDir', () => {
expect(wrapper.text()).toEqual('in[working-directory-123]');
});
test('should passing correct scopeId to cell actions', () => {
mount(
<TestProviders>
<div>
<HostWorkingDir
eventId={mockTimelineData[0].ecs._id}
scopeId="some_scope"
contextId="test"
hostName={null}
workingDirectory="[working-directory-123]"
/>
</div>
</TestProviders>
);
expect(MockedCellActionsWrapper).toHaveBeenCalledWith(
expect.objectContaining({
scopeId: 'some_scope',
}),
{}
);
});
});

View file

@ -17,13 +17,15 @@ interface Props {
eventId: string;
hostName: string | null | undefined;
workingDirectory: string | null | undefined;
scopeId: string;
}
export const HostWorkingDir = React.memo<Props>(
({ contextId, eventId, hostName, workingDirectory }) => (
({ contextId, eventId, hostName, workingDirectory, scopeId }) => (
<>
<TokensFlexItem grow={false} component="span">
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={eventId}
field="host.name"
@ -39,6 +41,7 @@ export const HostWorkingDir = React.memo<Props>(
)}
<TokensFlexItem grow={false} component="span">
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={eventId}
field="process.working_directory"

View file

@ -64,6 +64,7 @@ interface NetflowRendererProps {
export const NetflowRenderer = React.memo<NetflowRendererProps>(({ data, timelineId }) => (
<Netflow
scopeId={timelineId}
contextId={`netflow-renderer-${timelineId}-${data._id}`}
destinationBytes={asArrayIfExists(get(DESTINATION_BYTES_FIELD_NAME, data))}
destinationGeoContinentName={asArrayIfExists(

View file

@ -93,6 +93,7 @@ export const netflowRowRenderer: RowRenderer = {
<RowRendererContainer>
<Details>
<Netflow
scopeId={scopeId}
contextId={`netflow-row-renderer-render-row-${scopeId}-${data._id}`}
destinationBytes={asArrayIfExists(get(DESTINATION_BYTES_FIELD_NAME, data))}
destinationGeoContinentName={asArrayIfExists(

View file

@ -11,6 +11,7 @@ import { TestProviders } from '../../../../../common/mock';
import { ParentProcessDraggable } from './parent_process_draggable';
import { useMountAppended } from '../../../../../common/utils/use_mount_appended';
import { CellActionsWrapper } from '../../../../../common/components/drag_and_drop/cell_actions_wrapper';
jest.mock('../../../../../common/lib/kibana');
@ -22,13 +23,27 @@ jest.mock('@elastic/eui', () => {
};
});
jest.mock('../../../../../common/components/drag_and_drop/cell_actions_wrapper', () => {
return {
CellActionsWrapper: jest.fn(),
};
});
const MockedCellActionsWrapper = jest.fn(({ children }) => {
return <div data-test-subj="mock-cell-action-wrapper">{children}</div>;
});
describe('ParentProcessDraggable', () => {
beforeEach(() => {
(CellActionsWrapper as unknown as jest.Mock).mockImplementation(MockedCellActionsWrapper);
});
const mount = useMountAppended();
test('displays the text, endgameParentProcessName, processParentName, processParentPid, and processPpid when they are all provided', () => {
const wrapper = mount(
<TestProviders>
<ParentProcessDraggable
scopeId="some_scope"
contextId="test"
endgameParentProcessName="[endgameParentProcessName]"
eventId="1"
@ -48,6 +63,7 @@ describe('ParentProcessDraggable', () => {
const wrapper = mount(
<TestProviders>
<ParentProcessDraggable
scopeId="some_scope"
contextId="test"
endgameParentProcessName={undefined}
eventId="1"
@ -65,6 +81,7 @@ describe('ParentProcessDraggable', () => {
const wrapper = mount(
<TestProviders>
<ParentProcessDraggable
scopeId="some_scope"
contextId="test"
endgameParentProcessName="[endgameParentProcessName]"
eventId="1"
@ -82,6 +99,7 @@ describe('ParentProcessDraggable', () => {
const wrapper = mount(
<TestProviders>
<ParentProcessDraggable
scopeId="some_scope"
contextId="test"
endgameParentProcessName={undefined}
eventId="1"
@ -99,6 +117,7 @@ describe('ParentProcessDraggable', () => {
const wrapper = mount(
<TestProviders>
<ParentProcessDraggable
scopeId="some_scope"
contextId="test"
endgameParentProcessName="[endgameParentProcessName]"
eventId="1"
@ -116,6 +135,7 @@ describe('ParentProcessDraggable', () => {
const wrapper = mount(
<TestProviders>
<ParentProcessDraggable
scopeId="some_scope"
contextId="test"
endgameParentProcessName={undefined}
eventId="1"
@ -128,4 +148,28 @@ describe('ParentProcessDraggable', () => {
);
expect(wrapper.text()).toEqual('[processParentName]');
});
test('should passing correct scopeId to cell actions', () => {
mount(
<TestProviders>
<ParentProcessDraggable
scopeId="some_scope"
contextId="test"
endgameParentProcessName={undefined}
eventId="1"
processParentName="[processParentName]"
processParentPid={undefined}
processPpid={undefined}
text={undefined}
/>
</TestProviders>
);
expect(MockedCellActionsWrapper).toHaveBeenCalledWith(
expect.objectContaining({
scopeId: 'some_scope',
}),
{}
);
});
});

View file

@ -19,6 +19,7 @@ interface Props {
processParentName: string | null | undefined;
processPpid: number | undefined | null;
text: string | null | undefined;
scopeId: string;
}
export const ParentProcessDraggable = React.memo<Props>(
@ -30,6 +31,7 @@ export const ParentProcessDraggable = React.memo<Props>(
processParentPid,
processPpid,
text,
scopeId,
}) => {
if (
isNillEmptyOrNotFinite(processParentName) &&
@ -53,6 +55,7 @@ export const ParentProcessDraggable = React.memo<Props>(
{!isNillEmptyOrNotFinite(processParentName) && (
<TokensFlexItem grow={false} component="span">
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={eventId}
field="process.parent.name"
@ -66,6 +69,7 @@ export const ParentProcessDraggable = React.memo<Props>(
{!isNillEmptyOrNotFinite(endgameParentProcessName) && (
<TokensFlexItem grow={false} component="span">
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={eventId}
field="endgame.parent_process_name"
@ -79,6 +83,7 @@ export const ParentProcessDraggable = React.memo<Props>(
{!isNillEmptyOrNotFinite(processParentPid) && (
<TokensFlexItem grow={false} component="span">
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={eventId}
field="process.parent.pid"
@ -93,6 +98,7 @@ export const ParentProcessDraggable = React.memo<Props>(
{!isNillEmptyOrNotFinite(processPpid) && (
<TokensFlexItem grow={false} component="span">
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={eventId}
field="process.ppid"

View file

@ -10,6 +10,7 @@ import React from 'react';
import { TestProviders } from '../../../../../common/mock';
import { ProcessDraggable, ProcessDraggableWithNonExistentProcess } from './process_draggable';
import { CellActionsWrapper } from '../../../../../common/components/drag_and_drop/cell_actions_wrapper';
import { useMountAppended } from '../../../../../common/utils/use_mount_appended';
jest.mock('../../../../../common/lib/kibana');
@ -22,13 +23,27 @@ jest.mock('@elastic/eui', () => {
};
});
jest.mock('../../../../../common/components/drag_and_drop/cell_actions_wrapper', () => {
return {
CellActionsWrapper: jest.fn(),
};
});
const MockedCellActionsWrapper = jest.fn(({ children }) => {
return <div data-test-subj="mock-cell-action-wrapper">{children}</div>;
});
describe('ProcessDraggable', () => {
beforeEach(() => {
(CellActionsWrapper as unknown as jest.Mock).mockImplementation(MockedCellActionsWrapper);
});
const mount = useMountAppended();
describe('rendering', () => {
test('it renders against shallow snapshot', () => {
const wrapper = shallow(
<ProcessDraggable
scopeId="some_scope"
contextId="context-123"
endgamePid={456}
endgameProcessName="endgame-process-name-123"
@ -44,6 +59,7 @@ describe('ProcessDraggable', () => {
test('it returns null if everything is null', () => {
const wrapper = shallow(
<ProcessDraggable
scopeId="some_scope"
contextId="context-123"
endgamePid={null}
endgameProcessName={null}
@ -59,6 +75,7 @@ describe('ProcessDraggable', () => {
test('it returns null if everything is undefined', () => {
const wrapper = shallow(
<ProcessDraggable
scopeId="some_scope"
contextId="context-123"
endgamePid={undefined}
endgameProcessName={undefined}
@ -75,6 +92,7 @@ describe('ProcessDraggable', () => {
const wrapper = mount(
<TestProviders>
<ProcessDraggable
scopeId="some_scope"
contextId="context-123"
endgamePid={undefined}
endgameProcessName={undefined}
@ -92,6 +110,7 @@ describe('ProcessDraggable', () => {
const wrapper = mount(
<TestProviders>
<ProcessDraggable
scopeId="some_scope"
contextId="context-123"
endgamePid={undefined}
endgameProcessName={undefined}
@ -109,6 +128,7 @@ describe('ProcessDraggable', () => {
const wrapper = mount(
<TestProviders>
<ProcessDraggable
scopeId="some_scope"
contextId="context-123"
endgamePid={null}
endgameProcessName={null}
@ -126,6 +146,7 @@ describe('ProcessDraggable', () => {
const wrapper = mount(
<TestProviders>
<ProcessDraggable
scopeId="some_scope"
contextId="context-123"
endgamePid={NaN}
endgameProcessName={undefined}
@ -143,6 +164,7 @@ describe('ProcessDraggable', () => {
const wrapper = mount(
<TestProviders>
<ProcessDraggable
scopeId="some_scope"
contextId="context-123"
endgamePid={NaN}
endgameProcessName={null}
@ -160,6 +182,7 @@ describe('ProcessDraggable', () => {
const wrapper = mount(
<TestProviders>
<ProcessDraggable
scopeId="some_scope"
contextId="context-123"
endgamePid={NaN}
endgameProcessName=""
@ -177,6 +200,7 @@ describe('ProcessDraggable', () => {
const wrapper = mount(
<TestProviders>
<ProcessDraggable
scopeId="some_scope"
contextId="context-123"
endgamePid={NaN}
endgameProcessName="[endgame-process_name]"
@ -194,6 +218,7 @@ describe('ProcessDraggable', () => {
const wrapper = mount(
<TestProviders>
<ProcessDraggable
scopeId="some_scope"
contextId="context-123"
endgamePid={456}
endgameProcessName="[endgame-process_name]"
@ -211,6 +236,7 @@ describe('ProcessDraggable', () => {
const wrapper = mount(
<TestProviders>
<ProcessDraggable
scopeId="some_scope"
contextId="context-123"
endgamePid={456}
endgameProcessName=""
@ -228,6 +254,7 @@ describe('ProcessDraggable', () => {
const wrapper = mount(
<TestProviders>
<ProcessDraggable
scopeId="some_scope"
contextId="context-123"
endgamePid={456}
endgameProcessName=""
@ -245,6 +272,7 @@ describe('ProcessDraggable', () => {
const wrapper = mount(
<TestProviders>
<ProcessDraggable
scopeId="some_scope"
contextId="context-123"
endgamePid={456}
endgameProcessName="[endgame-process_name]"
@ -262,6 +290,7 @@ describe('ProcessDraggable', () => {
const wrapper = mount(
<TestProviders>
<ProcessDraggable
scopeId="some_scope"
contextId="context-123"
endgamePid={null}
endgameProcessName={null}
@ -279,6 +308,7 @@ describe('ProcessDraggable', () => {
const wrapper = mount(
<TestProviders>
<ProcessDraggable
scopeId="some_scope"
contextId="context-123"
endgamePid={456}
endgameProcessName={null}
@ -296,6 +326,7 @@ describe('ProcessDraggable', () => {
const wrapper = mount(
<TestProviders>
<ProcessDraggable
scopeId="some_scope"
contextId="context-123"
endgamePid={undefined}
endgameProcessName={undefined}
@ -313,6 +344,7 @@ describe('ProcessDraggable', () => {
const wrapper = mount(
<TestProviders>
<ProcessDraggable
scopeId="some_scope"
contextId="context-123"
endgamePid={null}
endgameProcessName=""
@ -330,6 +362,7 @@ describe('ProcessDraggable', () => {
const wrapper = mount(
<TestProviders>
<ProcessDraggable
scopeId="some_scope"
contextId="context-123"
endgamePid={null}
endgameProcessName="[endgame-process-name]"
@ -347,6 +380,7 @@ describe('ProcessDraggable', () => {
const wrapper = mount(
<TestProviders>
<ProcessDraggable
scopeId="some_scope"
contextId="context-123"
endgamePid={null}
endgameProcessName="[endgame-process-name]"
@ -364,6 +398,7 @@ describe('ProcessDraggable', () => {
const wrapper = mount(
<TestProviders>
<ProcessDraggable
scopeId="some_scope"
contextId="context-123"
endgamePid={null}
endgameProcessName="[endgame-process-name]"
@ -381,6 +416,7 @@ describe('ProcessDraggable', () => {
const wrapper = mount(
<TestProviders>
<ProcessDraggable
scopeId="some_scope"
contextId="context-123"
endgamePid={999}
endgameProcessName={undefined}
@ -398,6 +434,7 @@ describe('ProcessDraggable', () => {
const wrapper = mount(
<TestProviders>
<ProcessDraggable
scopeId="some_scope"
contextId="context-123"
endgamePid={999}
endgameProcessName={undefined}
@ -411,6 +448,30 @@ describe('ProcessDraggable', () => {
expect(wrapper.text()).toEqual('(999)');
});
});
test('should passing correct scopeId to cell actions', () => {
mount(
<TestProviders>
<ProcessDraggable
scopeId="some_scope"
contextId="context-123"
endgamePid={999}
endgameProcessName={undefined}
eventId="event-123"
processExecutable={undefined}
processName={undefined}
processPid={undefined}
/>
</TestProviders>
);
expect(MockedCellActionsWrapper).toHaveBeenCalledWith(
expect.objectContaining({
scopeId: 'some_scope',
}),
{}
);
});
});
describe('ProcessDraggableWithNonExistentProcess', () => {
@ -420,6 +481,7 @@ describe('ProcessDraggableWithNonExistentProcess', () => {
const wrapper = mount(
<TestProviders>
<ProcessDraggableWithNonExistentProcess
scopeId="some_scope"
contextId="context-123"
endgamePid={undefined}
endgameProcessName={undefined}
@ -437,6 +499,7 @@ describe('ProcessDraggableWithNonExistentProcess', () => {
const wrapper = mount(
<TestProviders>
<ProcessDraggableWithNonExistentProcess
scopeId="some_scope"
contextId="context-123"
endgamePid={999}
endgameProcessName={undefined}
@ -454,6 +517,7 @@ describe('ProcessDraggableWithNonExistentProcess', () => {
const wrapper = mount(
<TestProviders>
<ProcessDraggableWithNonExistentProcess
scopeId="some_scope"
contextId="context-123"
endgamePid={undefined}
endgameProcessName="[endgameProcessName]"
@ -471,6 +535,7 @@ describe('ProcessDraggableWithNonExistentProcess', () => {
const wrapper = mount(
<TestProviders>
<ProcessDraggableWithNonExistentProcess
scopeId="some_scope"
contextId="context-123"
endgamePid={undefined}
endgameProcessName={undefined}
@ -488,6 +553,7 @@ describe('ProcessDraggableWithNonExistentProcess', () => {
const wrapper = mount(
<TestProviders>
<ProcessDraggableWithNonExistentProcess
scopeId="some_scope"
contextId="context-123"
endgamePid={undefined}
endgameProcessName={undefined}
@ -505,6 +571,7 @@ describe('ProcessDraggableWithNonExistentProcess', () => {
const wrapper = mount(
<TestProviders>
<ProcessDraggableWithNonExistentProcess
scopeId="some_scope"
contextId="context-123"
endgamePid={undefined}
endgameProcessName={undefined}
@ -522,6 +589,7 @@ describe('ProcessDraggableWithNonExistentProcess', () => {
const wrapper = mount(
<TestProviders>
<ProcessDraggableWithNonExistentProcess
scopeId="some_scope"
contextId="context-123"
endgamePid={999}
endgameProcessName="[endgameProcessName]"
@ -534,4 +602,28 @@ describe('ProcessDraggableWithNonExistentProcess', () => {
);
expect(wrapper.text()).toEqual('[processName](123)');
});
test('should passing correct scopeId to cell actions', () => {
mount(
<TestProviders>
<ProcessDraggableWithNonExistentProcess
scopeId="some_scope"
contextId="context-123"
endgamePid={999}
endgameProcessName="[endgameProcessName]"
eventId="event-123"
processExecutable="[processExecutable]"
processName="[processName]"
processPid={123}
/>
</TestProviders>
);
expect(MockedCellActionsWrapper).toHaveBeenCalledWith(
expect.objectContaining({
scopeId: 'some_scope',
}),
{}
);
});
});

View file

@ -21,6 +21,7 @@ interface Props {
processExecutable: string | undefined | null;
processPid: number | undefined | null;
processName: string | undefined | null;
scopeId: string;
}
export const ProcessDraggable = React.memo<Props>(
@ -32,6 +33,7 @@ export const ProcessDraggable = React.memo<Props>(
processExecutable,
processName,
processPid,
scopeId,
}) => {
if (
isNillEmptyOrNotFinite(processName) &&
@ -48,6 +50,7 @@ export const ProcessDraggable = React.memo<Props>(
{!isNillEmptyOrNotFinite(processName) ? (
<EuiFlexItem grow={false}>
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={eventId}
field="process.name"
@ -60,6 +63,7 @@ export const ProcessDraggable = React.memo<Props>(
) : !isNillEmptyOrNotFinite(processExecutable) ? (
<EuiFlexItem grow={false}>
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={eventId}
field="process.executable"
@ -72,6 +76,7 @@ export const ProcessDraggable = React.memo<Props>(
) : !isNillEmptyOrNotFinite(endgameProcessName) ? (
<EuiFlexItem grow={false}>
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={eventId}
field="endgame.process_name"
@ -86,6 +91,7 @@ export const ProcessDraggable = React.memo<Props>(
{!isNillEmptyOrNotFinite(processPid) ? (
<EuiFlexItem grow={false}>
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={eventId}
field="process.pid"
@ -98,6 +104,7 @@ export const ProcessDraggable = React.memo<Props>(
) : !isNillEmptyOrNotFinite(endgamePid) ? (
<EuiFlexItem grow={false}>
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={eventId}
field="endgame.pid"
@ -124,6 +131,7 @@ export const ProcessDraggableWithNonExistentProcess = React.memo<Props>(
processExecutable,
processName,
processPid,
scopeId,
}) => {
if (
endgamePid == null &&
@ -143,6 +151,7 @@ export const ProcessDraggableWithNonExistentProcess = React.memo<Props>(
processExecutable={processExecutable}
processName={processName}
processPid={processPid}
scopeId={scopeId}
/>
);
}

View file

@ -9,6 +9,7 @@ import React from 'react';
import { TestProviders } from '../../../../../common/mock';
import { useMountAppended } from '../../../../../common/utils/use_mount_appended';
import { CellActionsWrapper } from '../../../../../common/components/drag_and_drop/cell_actions_wrapper';
import { ProcessHash } from './process_hash';
@ -23,12 +24,26 @@ jest.mock('@elastic/eui', () => {
});
const allProps = {
scopeId: 'some_scope',
contextId: 'test',
eventId: '1',
processHashSha256: undefined,
};
jest.mock('../../../../../common/components/drag_and_drop/cell_actions_wrapper', () => {
return {
CellActionsWrapper: jest.fn(),
};
});
const MockedCellActionsWrapper = jest.fn(({ children }) => {
return <div data-test-subj="mock-cell-action-wrapper">{children}</div>;
});
describe('ProcessHash', () => {
beforeEach(() => {
(CellActionsWrapper as unknown as jest.Mock).mockImplementation(MockedCellActionsWrapper);
});
const mount = useMountAppended();
test('displays the processHashSha256 when provided', () => {
@ -57,4 +72,19 @@ describe('ProcessHash', () => {
);
expect(wrapper.text()).toEqual('');
});
test('should passing correct scopeId to cell actions', () => {
mount(
<TestProviders>
<ProcessHash {...allProps} />
</TestProviders>
);
expect(MockedCellActionsWrapper).toHaveBeenCalledWith(
expect.objectContaining({
scopeId: 'some_scope',
}),
{}
);
});
});

View file

@ -21,28 +21,32 @@ interface Props {
contextId: string;
eventId: string;
processHashSha256: string | null | undefined;
scopeId: string;
}
export const ProcessHash = React.memo<Props>(({ contextId, eventId, processHashSha256 }) => {
if (isNillEmptyOrNotFinite(processHashSha256)) {
return null;
}
export const ProcessHash = React.memo<Props>(
({ contextId, eventId, processHashSha256, scopeId }) => {
if (isNillEmptyOrNotFinite(processHashSha256)) {
return null;
}
return (
<HashFlexGroup alignItems="center" direction="column" gutterSize="none">
<TokensFlexItem grow={false} component="div">
<DraggableBadge
contextId={contextId}
eventId={eventId}
field="process.hash.sha256"
iconType="number"
value={processHashSha256}
fieldType="keyword"
isAggregatable={true}
/>
</TokensFlexItem>
</HashFlexGroup>
);
});
return (
<HashFlexGroup alignItems="center" direction="column" gutterSize="none">
<TokensFlexItem grow={false} component="div">
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={eventId}
field="process.hash.sha256"
iconType="number"
value={processHashSha256}
fieldType="keyword"
isAggregatable={true}
/>
</TokensFlexItem>
</HashFlexGroup>
);
}
);
ProcessHash.displayName = 'ProcessHash';

View file

@ -33,6 +33,7 @@ describe('RegistryEventDetails', () => {
const wrapper = mount(
<TestProviders>
<RegistryEventDetails
scopeId="some_scope"
contextId="test-context"
data={mockEndpointRegistryModificationEvent}
text={MODIFIED_REGISTRY_KEY}

View file

@ -17,9 +17,10 @@ interface Props {
contextId: string;
data: Ecs;
text: string;
scopeId: string;
}
const RegistryEventDetailsComponent: React.FC<Props> = ({ contextId, data, text }) => {
const RegistryEventDetailsComponent: React.FC<Props> = ({ contextId, data, text, scopeId }) => {
const hostName: string | null | undefined = get('host.name[0]', data);
const id = data._id;
const processName: string | null | undefined = get('process.name[0]', data);
@ -36,6 +37,7 @@ const RegistryEventDetailsComponent: React.FC<Props> = ({ contextId, data, text
return (
<Details>
<RegistryEventDetailsLine
scopeId={scopeId}
contextId={contextId}
hostName={hostName}
id={id}

View file

@ -11,6 +11,7 @@ import { TestProviders } from '../../../../../../common/mock';
import { useMountAppended } from '../../../../../../common/utils/use_mount_appended';
import { RegistryEventDetailsLine } from './registry_event_details_line';
import { MODIFIED_REGISTRY_KEY } from '../system/translations';
import { CellActionsWrapper } from '../../../../../../common/components/drag_and_drop/cell_actions_wrapper';
jest.mock('../../../../../../common/lib/kibana');
@ -22,10 +23,24 @@ jest.mock('@elastic/eui', () => {
};
});
jest.mock('../../../../../../common/components/drag_and_drop/cell_actions_wrapper', () => {
return {
CellActionsWrapper: jest.fn(),
};
});
const MockedCellActionsWrapper = jest.fn(({ children }) => {
return <div data-test-subj="mock-cell-action-wrapper">{children}</div>;
});
describe('DnsRequestEventDetailsLine', () => {
beforeEach(() => {
(CellActionsWrapper as unknown as jest.Mock).mockImplementation(MockedCellActionsWrapper);
});
const mount = useMountAppended();
const allProps = {
scopeId: 'some_scope',
contextId: 'test',
hostName: '[hostName]',
id: '1',
@ -132,4 +147,19 @@ describe('DnsRequestEventDetailsLine', () => {
'\\[userDomain][hostName]modified registry key[registryKey]with new value[registryPath]via[processName](123)'
);
});
test('should passing correct scopeId to cell actions', () => {
mount(
<TestProviders>
<RegistryEventDetailsLine {...allProps} userName={undefined} />
</TestProviders>
);
expect(MockedCellActionsWrapper).toHaveBeenCalledWith(
expect.objectContaining({
scopeId: 'some_scope',
}),
{}
);
});
});

View file

@ -26,6 +26,7 @@ interface Props {
text: string;
userDomain: string | null | undefined;
userName: string | null | undefined;
scopeId: string;
}
const RegistryEventDetailsLineComponent: React.FC<Props> = ({
@ -39,6 +40,7 @@ const RegistryEventDetailsLineComponent: React.FC<Props> = ({
text,
userDomain,
userName,
scopeId,
}) => {
const registryKeyTooltipContent = useMemo(
() => (
@ -68,6 +70,7 @@ const RegistryEventDetailsLineComponent: React.FC<Props> = ({
<>
<EuiFlexGroup alignItems="center" justifyContent="center" gutterSize="none" wrap={true}>
<UserHostWorkingDir
scopeId={scopeId}
contextId={contextId}
eventId={id}
hostName={hostName}
@ -83,6 +86,7 @@ const RegistryEventDetailsLineComponent: React.FC<Props> = ({
</TokensFlexItem>
<TokensFlexItem component="span" grow={false}>
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={id}
field="registry.key"
@ -102,6 +106,7 @@ const RegistryEventDetailsLineComponent: React.FC<Props> = ({
</TokensFlexItem>
<TokensFlexItem component="span" grow={false}>
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={id}
field="registry.path"
@ -120,6 +125,7 @@ const RegistryEventDetailsLineComponent: React.FC<Props> = ({
<TokensFlexItem component="span" grow={false}>
<ProcessDraggableWithNonExistentProcess
scopeId={scopeId}
contextId={contextId}
endgamePid={undefined}
endgameProcessName={undefined}

View file

@ -13,6 +13,7 @@ exports[`AuthSsh rendering it renders against shallow snapshot 1`] = `
fieldType="keyword"
iconType="document"
isAggregatable={true}
scopeId="some_scope"
value="[ssh-signature]"
/>
</TokensFlexItem>
@ -27,6 +28,7 @@ exports[`AuthSsh rendering it renders against shallow snapshot 1`] = `
fieldType="keyword"
iconType="document"
isAggregatable={true}
scopeId="some_scope"
value="[ssh-method]"
/>
</TokensFlexItem>

View file

@ -9,6 +9,7 @@ exports[`SystemGenericDetails rendering it renders the default SystemGenericDeta
message={null}
outcome="failure"
processPid={6278}
scopeId="test"
text="[generic-text-123]"
userName="Braden"
/>

View file

@ -10,6 +10,7 @@ exports[`SystemGenericFileDetails rendering it renders the default SystemGeneric
message={null}
outcome="failure"
processPid={6278}
scopeId="some_scope"
showMessage={true}
skipRedundantFileDetails={false}
skipRedundantProcessDetails={false}
@ -70,7 +71,7 @@ exports[`SystemGenericFileDetails rendering it renders the default SystemGeneric
},
}
}
timelineId="test"
timelineId="some_scope"
/>
</Details>
`;

View file

@ -55,8 +55,8 @@ exports[`GenericRowRenderer #createGenericFileRowRenderer renders correctly agai
},
}
}
scopeId="timeline-test"
text="some text"
timelineId="timeline-test"
/>
</RowRendererContainer>
</span>

View file

@ -13,6 +13,7 @@ exports[`Package rendering it renders against shallow snapshot 1`] = `
fieldType="keyword"
iconType="document"
isAggregatable={true}
scopeId="some_scope"
value="package-name-123"
/>
</TokensFlexItem>
@ -27,6 +28,7 @@ exports[`Package rendering it renders against shallow snapshot 1`] = `
fieldType="keyword"
iconType="document"
isAggregatable={true}
scopeId="some_scope"
value="package-version-123"
/>
</TokensFlexItem>
@ -40,6 +42,7 @@ exports[`Package rendering it renders against shallow snapshot 1`] = `
field="system.audit.package.summary"
fieldType="keyword"
isAggregatable={true}
scopeId="some_scope"
value="package-summary-123"
/>
</TokensFlexItem>

View file

@ -5,16 +5,31 @@
* 2.0.
*/
import { shallow } from 'enzyme';
import { shallow, mount } from 'enzyme';
import React from 'react';
import { AuthSsh } from './auth_ssh';
import { CellActionsWrapper } from '../../../../../../common/components/drag_and_drop/cell_actions_wrapper';
jest.mock('../../../../../../common/components/drag_and_drop/cell_actions_wrapper', () => {
return {
CellActionsWrapper: jest.fn(),
};
});
const MockedCellActionsWrapper = jest.fn(({ children }) => {
return <div data-test-subj="mock-cell-action-wrapper">{children}</div>;
});
describe('AuthSsh', () => {
beforeEach(() => {
(CellActionsWrapper as unknown as jest.Mock).mockImplementation(MockedCellActionsWrapper);
});
describe('rendering', () => {
test('it renders against shallow snapshot', () => {
const wrapper = shallow(
<AuthSsh
scopeId="some_scope"
contextId="[context-123]"
eventId="[event-123]"
sshSignature="[ssh-signature]"
@ -27,6 +42,7 @@ describe('AuthSsh', () => {
test('it returns null if sshSignature and sshMethod are both null', () => {
const wrapper = shallow(
<AuthSsh
scopeId="some_scope"
contextId="[context-123]"
eventId="[event-123]"
sshSignature={null}
@ -39,6 +55,7 @@ describe('AuthSsh', () => {
test('it returns null if sshSignature and sshMethod are both undefined', () => {
const wrapper = shallow(
<AuthSsh
scopeId="some_scope"
contextId="[context-123]"
eventId="[event-123]"
sshSignature={undefined}
@ -51,6 +68,7 @@ describe('AuthSsh', () => {
test('it returns null if sshSignature is null and sshMethod is undefined', () => {
const wrapper = shallow(
<AuthSsh
scopeId="some_scope"
contextId="[context-123]"
eventId="[event-123]"
sshSignature={null}
@ -63,6 +81,7 @@ describe('AuthSsh', () => {
test('it returns null if sshSignature is undefined and sshMethod is null', () => {
const wrapper = shallow(
<AuthSsh
scopeId="some_scope"
contextId="[context-123]"
eventId="[event-123]"
sshSignature={undefined}
@ -75,6 +94,7 @@ describe('AuthSsh', () => {
test('it returns sshSignature if sshMethod is null', () => {
const wrapper = shallow(
<AuthSsh
scopeId="some_scope"
contextId="[context-123]"
eventId="[event-123]"
sshSignature="[sshSignature-1]"
@ -87,6 +107,7 @@ describe('AuthSsh', () => {
test('it returns sshMethod if sshSignature is null', () => {
const wrapper = shallow(
<AuthSsh
scopeId="some_scope"
contextId="[context-123]"
eventId="[event-123]"
sshSignature={null}
@ -95,5 +116,24 @@ describe('AuthSsh', () => {
);
expect(wrapper.find('DraggableBadge').prop('value')).toEqual('[sshMethod-1]');
});
test('should passing correct scopeId to cell actions', () => {
mount(
<AuthSsh
scopeId="some_scope"
contextId="[context-123]"
eventId="[event-123]"
sshSignature={null}
sshMethod="[sshMethod-1]"
/>
);
expect(MockedCellActionsWrapper).toHaveBeenCalledWith(
expect.objectContaining({
scopeId: 'some_scope',
}),
{}
);
});
});
});

View file

@ -15,37 +15,42 @@ interface Props {
eventId: string;
sshSignature: string | null | undefined;
sshMethod: string | null | undefined;
scopeId: string;
}
export const AuthSsh = React.memo<Props>(({ contextId, eventId, sshSignature, sshMethod }) => (
<>
{sshSignature != null && (
<TokensFlexItem grow={false} component="span">
<DraggableBadge
contextId={contextId}
eventId={eventId}
field="system.audit.package.name"
value={sshSignature}
iconType="document"
isAggregatable={true}
fieldType="keyword"
/>
</TokensFlexItem>
)}
{sshMethod != null && (
<TokensFlexItem grow={false} component="span">
<DraggableBadge
contextId={contextId}
eventId={eventId}
field="system.audit.package.version"
value={sshMethod}
iconType="document"
isAggregatable={true}
fieldType="keyword"
/>
</TokensFlexItem>
)}
</>
));
export const AuthSsh = React.memo<Props>(
({ contextId, eventId, sshSignature, sshMethod, scopeId }) => (
<>
{sshSignature != null && (
<TokensFlexItem grow={false} component="span">
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={eventId}
field="system.audit.package.name"
value={sshSignature}
iconType="document"
isAggregatable={true}
fieldType="keyword"
/>
</TokensFlexItem>
)}
{sshMethod != null && (
<TokensFlexItem grow={false} component="span">
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={eventId}
field="system.audit.package.version"
value={sshMethod}
iconType="document"
isAggregatable={true}
fieldType="keyword"
/>
</TokensFlexItem>
)}
</>
)
);
AuthSsh.displayName = 'AuthSsh';

View file

@ -63,6 +63,7 @@ describe('SystemGenericDetails', () => {
<TestProviders>
<div>
<SystemGenericLine
scopeId="some_scope"
contextId="[context-123]"
hostName="[hostname-123]"
id="[id-123]"
@ -94,6 +95,7 @@ describe('SystemGenericDetails', () => {
<TestProviders>
<div>
<SystemGenericLine
scopeId="some_scope"
contextId="[context-123]"
hostName={null}
id="[id-123]"
@ -123,6 +125,7 @@ describe('SystemGenericDetails', () => {
<TestProviders>
<div>
<SystemGenericLine
scopeId="some_scope"
contextId="[context-123]"
hostName="[hostname-123]"
id="[id-123]"
@ -152,6 +155,7 @@ describe('SystemGenericDetails', () => {
<TestProviders>
<div>
<SystemGenericLine
scopeId="some_scope"
contextId="[context-123]"
hostName="[hostname-123]"
id="[id-123]"
@ -181,6 +185,7 @@ describe('SystemGenericDetails', () => {
<TestProviders>
<div>
<SystemGenericLine
scopeId="some_scope"
contextId="[context-123]"
hostName="[hostname-123]"
id="[id-123]"
@ -210,6 +215,7 @@ describe('SystemGenericDetails', () => {
<TestProviders>
<div>
<SystemGenericLine
scopeId="some_scope"
contextId="[context-123]"
hostName="[hostname-123]"
id="[id-123]"
@ -241,6 +247,7 @@ describe('SystemGenericDetails', () => {
<TestProviders>
<div>
<SystemGenericLine
scopeId="some_scope"
contextId="[context-123]"
hostName="[hostname-123]"
id="[id-123]"
@ -272,6 +279,7 @@ describe('SystemGenericDetails', () => {
<TestProviders>
<div>
<SystemGenericLine
scopeId="some_scope"
contextId="[context-123]"
hostName="[hostname-123]"
id="[id-123]"
@ -303,6 +311,7 @@ describe('SystemGenericDetails', () => {
<TestProviders>
<div>
<SystemGenericLine
scopeId="some_scope"
contextId="[context-123]"
hostName="[hostname-123]"
id="[id-123]"
@ -334,6 +343,7 @@ describe('SystemGenericDetails', () => {
<TestProviders>
<div>
<SystemGenericLine
scopeId="some_scope"
contextId="[context-123]"
hostName="[hostname-123]"
id="[id-123]"
@ -365,6 +375,7 @@ describe('SystemGenericDetails', () => {
<TestProviders>
<div>
<SystemGenericLine
scopeId="some_scope"
contextId="[context-123]"
hostName="[hostname-123]"
id="[id-123]"
@ -396,6 +407,7 @@ describe('SystemGenericDetails', () => {
<TestProviders>
<div>
<SystemGenericLine
scopeId="some_scope"
contextId="[context-123]"
hostName="[hostname-123]"
id="[id-123]"
@ -427,6 +439,7 @@ describe('SystemGenericDetails', () => {
<TestProviders>
<div>
<SystemGenericLine
scopeId="some_scope"
contextId="[context-123]"
hostName="[hostname-123]"
id="[id-123]"
@ -458,6 +471,7 @@ describe('SystemGenericDetails', () => {
<TestProviders>
<div>
<SystemGenericLine
scopeId="some_scope"
contextId="[context-123]"
hostName="[hostname-123]"
id="[id-123]"
@ -489,6 +503,7 @@ describe('SystemGenericDetails', () => {
<TestProviders>
<div>
<SystemGenericLine
scopeId="some_scope"
contextId="[context-123]"
hostName="[hostname-123]"
id="[id-123]"
@ -520,6 +535,7 @@ describe('SystemGenericDetails', () => {
<TestProviders>
<div>
<SystemGenericLine
scopeId="some_scope"
contextId="[context-123]"
hostName="[hostname-123]"
id="[id-123]"

View file

@ -40,6 +40,7 @@ interface Props {
userDomain: string | null | undefined;
userName: string | null | undefined;
workingDirectory: string | null | undefined;
scopeId: string;
}
export const SystemGenericLine = React.memo<Props>(
@ -61,10 +62,12 @@ export const SystemGenericLine = React.memo<Props>(
userDomain,
userName,
workingDirectory,
scopeId,
}) => (
<>
<EuiFlexGroup alignItems="center" justifyContent="center" gutterSize="none" wrap={true}>
<UserHostWorkingDir
scopeId={scopeId}
contextId={contextId}
eventId={id}
hostName={hostName}
@ -77,6 +80,7 @@ export const SystemGenericLine = React.memo<Props>(
</TokensFlexItem>
<TokensFlexItem grow={false} component="span">
<ProcessDraggable
scopeId={scopeId}
contextId={contextId}
endgamePid={undefined}
endgameProcessName={undefined}
@ -93,6 +97,7 @@ export const SystemGenericLine = React.memo<Props>(
)}
<TokensFlexItem grow={false} component="span">
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={id}
field="event.outcome"
@ -103,12 +108,14 @@ export const SystemGenericLine = React.memo<Props>(
/>
</TokensFlexItem>
<AuthSsh
scopeId={scopeId}
contextId={contextId}
eventId={id}
sshSignature={sshSignature}
sshMethod={sshMethod}
/>
<Package
scopeId={scopeId}
contextId={contextId}
eventId={id}
packageName={packageName}
@ -162,6 +169,7 @@ export const SystemGenericDetails = React.memo<GenericDetailsProps>(
return (
<Details>
<SystemGenericLine
scopeId={timelineId}
contextId={contextId}
hostName={hostName}
id={id}

View file

@ -12,6 +12,7 @@ import { mockTimelineData, TestProviders } from '../../../../../../common/mock';
import { mockEndgameCreationEvent } from '../../../../../../common/mock/mock_endgame_ecs_data';
import { SystemGenericFileDetails, SystemGenericFileLine } from './generic_file_details';
import { useMountAppended } from '../../../../../../common/utils/use_mount_appended';
import { CellActionsWrapper } from '../../../../../../common/components/drag_and_drop/cell_actions_wrapper';
jest.mock('../../../../../../common/lib/kibana');
@ -35,17 +36,31 @@ jest.mock('react-router-dom', () => {
};
});
jest.mock('../../../../../../common/components/drag_and_drop/cell_actions_wrapper', () => {
return {
CellActionsWrapper: jest.fn(),
};
});
const MockedCellActionsWrapper = jest.fn(({ children }) => {
return <div data-test-subj="mock-cell-action-wrapper">{children}</div>;
});
describe('SystemGenericFileDetails', () => {
beforeEach(() => {
(CellActionsWrapper as unknown as jest.Mock).mockImplementation(MockedCellActionsWrapper);
});
const mount = useMountAppended();
describe('rendering', () => {
test('it renders the default SystemGenericDetails', () => {
const wrapper = shallow(
<SystemGenericFileDetails
scopeId="some_scope"
contextId="[contextid-123]"
text="[generic-text-123]"
data={mockTimelineData[29].ecs}
timelineId="test"
/>
);
expect(wrapper).toMatchSnapshot();
@ -55,10 +70,10 @@ describe('SystemGenericFileDetails', () => {
const wrapper = mount(
<TestProviders>
<SystemGenericFileDetails
scopeId="some_scope"
contextId="[contextid-123]"
text="[generic-text-123]"
data={mockTimelineData[29].ecs}
timelineId="test"
/>
</TestProviders>
);
@ -71,10 +86,10 @@ describe('SystemGenericFileDetails', () => {
const wrapper = mount(
<TestProviders>
<SystemGenericFileDetails
scopeId="some_scope"
contextId="[contextid-123]"
text="[generic-text-123]"
data={mockEndgameCreationEvent}
timelineId="test"
/>
</TestProviders>
);
@ -82,6 +97,26 @@ describe('SystemGenericFileDetails', () => {
'd4c97ed46046893141652e2ec0056a698f6445109949d7fcabbce331146889ee'
);
});
test('should passing correct scopeId to cell actions', () => {
mount(
<TestProviders>
<SystemGenericFileDetails
scopeId="some_scope"
contextId="[contextid-123]"
text="[generic-text-123]"
data={mockTimelineData[29].ecs}
/>
</TestProviders>
);
expect(MockedCellActionsWrapper).toHaveBeenCalledWith(
expect.objectContaining({
scopeId: 'some_scope',
}),
{}
);
});
});
describe('#SystemGenericFileLine', () => {
@ -91,6 +126,7 @@ describe('SystemGenericFileDetails', () => {
<div>
<SystemGenericFileLine
id="[id-123]"
scopeId="some_scope"
contextId="[context-123]"
endgameExitCode="[endgameExitCode-123]"
endgameFileName="[endgameFileName-123]"
@ -140,6 +176,7 @@ describe('SystemGenericFileDetails', () => {
<TestProviders>
<div>
<SystemGenericFileLine
scopeId="some_scope"
contextId="[context-123]"
endgameExitCode={null}
endgameFileName={null}
@ -188,6 +225,7 @@ describe('SystemGenericFileDetails', () => {
<TestProviders>
<div>
<SystemGenericFileLine
scopeId="some_scope"
contextId="[context-123]"
endgameExitCode={null}
endgameFileName={null}
@ -236,6 +274,7 @@ describe('SystemGenericFileDetails', () => {
<TestProviders>
<div>
<SystemGenericFileLine
scopeId="some_scope"
contextId="[context-123]"
endgameExitCode={null}
endgameFileName={null}
@ -284,6 +323,7 @@ describe('SystemGenericFileDetails', () => {
<TestProviders>
<div>
<SystemGenericFileLine
scopeId="some_scope"
contextId="[context-123]"
endgameExitCode={null}
endgameFileName={null}
@ -334,6 +374,7 @@ describe('SystemGenericFileDetails', () => {
<TestProviders>
<div>
<SystemGenericFileLine
scopeId="some_scope"
contextId="[context-123]"
endgameExitCode={null}
endgameFileName={null}
@ -384,6 +425,7 @@ describe('SystemGenericFileDetails', () => {
<TestProviders>
<div>
<SystemGenericFileLine
scopeId="some_scope"
contextId="[context-123]"
endgameExitCode={null}
endgameFileName={null}
@ -434,6 +476,7 @@ describe('SystemGenericFileDetails', () => {
<TestProviders>
<div>
<SystemGenericFileLine
scopeId="some_scope"
contextId="[context-123]"
endgameExitCode={null}
endgameFileName={null}
@ -484,6 +527,7 @@ describe('SystemGenericFileDetails', () => {
<TestProviders>
<div>
<SystemGenericFileLine
scopeId="some_scope"
contextId="[context-123]"
endgameExitCode={null}
endgameFileName={null}
@ -534,6 +578,7 @@ describe('SystemGenericFileDetails', () => {
<TestProviders>
<div>
<SystemGenericFileLine
scopeId="some_scope"
contextId="[context-123]"
endgameExitCode={null}
endgameFileName={null}
@ -584,6 +629,7 @@ describe('SystemGenericFileDetails', () => {
<TestProviders>
<div>
<SystemGenericFileLine
scopeId="some_scope"
contextId="[context-123]"
endgameExitCode={null}
endgameFileName={null}
@ -634,6 +680,7 @@ describe('SystemGenericFileDetails', () => {
<TestProviders>
<div>
<SystemGenericFileLine
scopeId="some_scope"
contextId="[context-123]"
endgameExitCode={null}
endgameFileName={null}
@ -684,6 +731,7 @@ describe('SystemGenericFileDetails', () => {
<TestProviders>
<div>
<SystemGenericFileLine
scopeId="some_scope"
contextId="[context-123]"
endgameExitCode={null}
endgameFileName={null}
@ -734,6 +782,7 @@ describe('SystemGenericFileDetails', () => {
<TestProviders>
<div>
<SystemGenericFileLine
scopeId="some_scope"
contextId="[context-123]"
endgameExitCode={null}
endgameFileName={null}
@ -784,6 +833,7 @@ describe('SystemGenericFileDetails', () => {
<TestProviders>
<div>
<SystemGenericFileLine
scopeId="some_scope"
contextId="[context-123]"
endgameExitCode={null}
endgameFileName={null}
@ -834,6 +884,7 @@ describe('SystemGenericFileDetails', () => {
<TestProviders>
<div>
<SystemGenericFileLine
scopeId="some_scope"
contextId="[context-123]"
endgameExitCode="[endgameExitCode-123]"
endgameFileName={null}
@ -884,6 +935,7 @@ describe('SystemGenericFileDetails', () => {
<TestProviders>
<div>
<SystemGenericFileLine
scopeId="some_scope"
contextId="[context-123]"
endgameExitCode="[endgameExitCode-123]"
endgameFileName={null}
@ -934,6 +986,7 @@ describe('SystemGenericFileDetails', () => {
<TestProviders>
<div>
<SystemGenericFileLine
scopeId="some_scope"
contextId="[context-123]"
endgameExitCode="[endgameExitCode-123]"
endgameFileName={null}
@ -984,6 +1037,7 @@ describe('SystemGenericFileDetails', () => {
<TestProviders>
<div>
<SystemGenericFileLine
scopeId="some_scope"
contextId="[context-123]"
endgameExitCode="[endgameExitCode-123]"
endgameFileName={null}
@ -1034,6 +1088,7 @@ describe('SystemGenericFileDetails', () => {
<TestProviders>
<div>
<SystemGenericFileLine
scopeId="some_scope"
contextId="[context-123]"
endgameExitCode="[endgameExitCode-123]"
endgameFileName={null}
@ -1084,6 +1139,7 @@ describe('SystemGenericFileDetails', () => {
<TestProviders>
<div>
<SystemGenericFileLine
scopeId="some_scope"
contextId="[context-123]"
endgameExitCode="[endgameExitCode-123]"
endgameFileName={null}
@ -1134,6 +1190,7 @@ describe('SystemGenericFileDetails', () => {
<TestProviders>
<div>
<SystemGenericFileLine
scopeId="some_scope"
contextId="[context-123]"
endgameExitCode="[endgameExitCode-123]"
endgameFileName={null}
@ -1184,6 +1241,7 @@ describe('SystemGenericFileDetails', () => {
<TestProviders>
<div>
<SystemGenericFileLine
scopeId="some_scope"
contextId="[context-123]"
endgameExitCode="[endgameExitCode-123]"
endgameFileName={null}
@ -1234,6 +1292,7 @@ describe('SystemGenericFileDetails', () => {
<TestProviders>
<div>
<SystemGenericFileLine
scopeId="some_scope"
contextId="[context-123]"
endgameExitCode={undefined}
endgameFileName="[endgameFileName]"
@ -1282,6 +1341,7 @@ describe('SystemGenericFileDetails', () => {
<TestProviders>
<div>
<SystemGenericFileLine
scopeId="some_scope"
contextId="[context-123]"
endgameExitCode={undefined}
endgameFileName="[endgameFileName]"
@ -1332,6 +1392,7 @@ describe('SystemGenericFileDetails', () => {
<TestProviders>
<div>
<SystemGenericFileLine
scopeId="some_scope"
contextId="[context-123]"
endgameExitCode={undefined}
endgameFileName={undefined}
@ -1384,6 +1445,7 @@ describe('SystemGenericFileDetails', () => {
<TestProviders>
<div>
<SystemGenericFileLine
scopeId="some_scope"
contextId="[context-123]"
endgameExitCode={undefined}
endgameFileName={undefined}
@ -1435,6 +1497,7 @@ describe('SystemGenericFileDetails', () => {
<TestProviders>
<div>
<SystemGenericFileLine
scopeId="some_scope"
contextId="[context-123]"
endgameExitCode={undefined}
endgameFileName={undefined}
@ -1488,6 +1551,7 @@ describe('SystemGenericFileDetails', () => {
<TestProviders>
<div>
<SystemGenericFileLine
scopeId="some_scope"
contextId="[context-123]"
endgameExitCode={undefined}
endgameFileName={undefined}
@ -1539,6 +1603,7 @@ describe('SystemGenericFileDetails', () => {
<TestProviders>
<div>
<SystemGenericFileLine
scopeId="some_scope"
contextId="[context-123]"
endgameExitCode={undefined}
endgameFileName={undefined}
@ -1588,6 +1653,7 @@ describe('SystemGenericFileDetails', () => {
<TestProviders>
<div>
<SystemGenericFileLine
scopeId="some_scope"
contextId="[context-123]"
endgameExitCode={undefined}
endgameFileName={undefined}
@ -1637,6 +1703,7 @@ describe('SystemGenericFileDetails', () => {
<TestProviders>
<div>
<SystemGenericFileLine
scopeId="some_scope"
contextId="[context-123]"
endgameExitCode={undefined}
endgameFileName={undefined}
@ -1686,6 +1753,7 @@ describe('SystemGenericFileDetails', () => {
<TestProviders>
<div>
<SystemGenericFileLine
scopeId="some_scope"
contextId="[context-123]"
endgameExitCode={undefined}
endgameFileName={undefined}
@ -1735,6 +1803,7 @@ describe('SystemGenericFileDetails', () => {
<TestProviders>
<div>
<SystemGenericFileLine
scopeId="some_scope"
contextId="[context-123]"
endgameExitCode={undefined}
endgameFileName={undefined}
@ -1778,5 +1847,58 @@ describe('SystemGenericFileDetails', () => {
expect(wrapper.text()).toEqual('[processName](123)');
});
test('should passing correct scopeId to cell actions', () => {
mount(
<TestProviders>
<SystemGenericFileLine
scopeId="some_scope"
contextId="[context-123]"
endgameExitCode={undefined}
endgameFileName={undefined}
endgameFilePath={undefined}
endgameParentProcessName={undefined}
endgamePid={789}
endgameProcessName="[endgameProcessName]"
eventAction={undefined}
fileExtOriginalPath={undefined}
fileHashSha256={undefined}
fileName={undefined}
filePath={undefined}
hostName={undefined}
id="[id-123]"
message={undefined}
outcome={undefined}
packageName={undefined}
packageSummary={undefined}
packageVersion={undefined}
processExecutable={undefined}
processExitCode={undefined}
processHashSha256={undefined}
processParentName={undefined}
processParentPid={undefined}
processPid={123}
processPpid={undefined}
processName="[processName]"
showMessage={true}
sshMethod={undefined}
processTitle={undefined}
args={undefined}
sshSignature={undefined}
text={undefined}
userDomain={undefined}
userName={undefined}
workingDirectory={undefined}
/>
</TestProviders>
);
expect(MockedCellActionsWrapper).toHaveBeenCalledWith(
expect.objectContaining({
scopeId: 'some_scope',
}),
{}
);
});
});
});

View file

@ -67,6 +67,7 @@ interface Props {
userDomain: string | null | undefined;
userName: string | null | undefined;
workingDirectory: string | null | undefined;
scopeId: string;
}
export const SystemGenericFileLine = React.memo<Props>(
@ -109,6 +110,7 @@ export const SystemGenericFileLine = React.memo<Props>(
userDomain,
userName,
workingDirectory,
scopeId,
}) => (
<>
<EuiFlexGroup alignItems="center" justifyContent="center" gutterSize="none" wrap={true}>
@ -119,6 +121,7 @@ export const SystemGenericFileLine = React.memo<Props>(
userName={userName}
workingDirectory={workingDirectory}
hostName={hostName}
scopeId={scopeId}
/>
<TokensFlexItem grow={false} component="span">
{text}
@ -133,6 +136,7 @@ export const SystemGenericFileLine = React.memo<Props>(
fileExtOriginalPath={fileExtOriginalPath}
fileName={fileName}
filePath={filePath}
scopeId={scopeId}
/>
)}
{showVia(eventAction) && (
@ -149,10 +153,18 @@ export const SystemGenericFileLine = React.memo<Props>(
processPid={processPid}
processName={processName}
processExecutable={processExecutable}
scopeId={scopeId}
/>
</TokensFlexItem>
<Args args={args} contextId={contextId} eventId={id} processTitle={processTitle} />
<Args
scopeId={scopeId}
args={args}
contextId={contextId}
eventId={id}
processTitle={processTitle}
/>
<ExitCodeDraggable
scopeId={scopeId}
contextId={contextId}
endgameExitCode={endgameExitCode}
eventId={id}
@ -161,6 +173,7 @@ export const SystemGenericFileLine = React.memo<Props>(
/>
{!isProcessStoppedOrTerminationEvent(eventAction) && (
<ParentProcessDraggable
scopeId={scopeId}
contextId={contextId}
endgameParentProcessName={endgameParentProcessName}
eventId={id}
@ -177,6 +190,7 @@ export const SystemGenericFileLine = React.memo<Props>(
)}
<TokensFlexItem grow={false} component="span">
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={id}
field="event.outcome"
@ -187,12 +201,14 @@ export const SystemGenericFileLine = React.memo<Props>(
/>
</TokensFlexItem>
<AuthSsh
scopeId={scopeId}
contextId={contextId}
eventId={id}
sshSignature={sshSignature}
sshMethod={sshMethod}
/>
<Package
scopeId={scopeId}
contextId={contextId}
eventId={id}
packageName={packageName}
@ -201,10 +217,20 @@ export const SystemGenericFileLine = React.memo<Props>(
/>
</EuiFlexGroup>
{!skipRedundantFileDetails && (
<FileHash contextId={contextId} eventId={id} fileHashSha256={fileHashSha256} />
<FileHash
scopeId={scopeId}
contextId={contextId}
eventId={id}
fileHashSha256={fileHashSha256}
/>
)}
{!skipRedundantProcessDetails && (
<ProcessHash contextId={contextId} eventId={id} processHashSha256={processHashSha256} />
<ProcessHash
scopeId={scopeId}
contextId={contextId}
eventId={id}
processHashSha256={processHashSha256}
/>
)}
{message != null && showMessage && (
@ -232,7 +258,7 @@ interface GenericDetailsProps {
skipRedundantFileDetails?: boolean;
skipRedundantProcessDetails?: boolean;
text: string;
timelineId: string;
scopeId: string;
}
export const SystemGenericFileDetails = React.memo<GenericDetailsProps>(
@ -243,7 +269,7 @@ export const SystemGenericFileDetails = React.memo<GenericDetailsProps>(
skipRedundantFileDetails = false,
skipRedundantProcessDetails = false,
text,
timelineId,
scopeId,
}) => {
const id = data._id;
const message: string | null = data.message != null ? data.message[0] : null;
@ -323,9 +349,10 @@ export const SystemGenericFileDetails = React.memo<GenericDetailsProps>(
sshSignature={sshSignature}
sshMethod={sshMethod}
outcome={outcome}
scopeId={scopeId}
/>
<EuiSpacer size="s" />
<NetflowRenderer data={data} timelineId={timelineId} />
<NetflowRenderer data={data} timelineId={scopeId} />
</Details>
);
}

View file

@ -76,7 +76,7 @@ export const createEndgameProcessRowRenderer = ({
contextId={`endgame-process-${actionName}-${scopeId}`}
showMessage={false}
text={text}
timelineId={scopeId}
scopeId={scopeId}
/>
</RowRendererContainer>
),
@ -106,7 +106,7 @@ export const createFimRowRenderer = ({
contextId={`fim-${actionName}-${scopeId}`}
showMessage={false}
text={text}
timelineId={scopeId}
scopeId={scopeId}
/>
</RowRendererContainer>
),
@ -156,7 +156,7 @@ export const createEndpointAlertsRowRenderer = ({
skipRedundantFileDetails={skipRedundantFileDetails}
skipRedundantProcessDetails={skipRedundantProcessDetails}
text={text}
timelineId={scopeId}
scopeId={scopeId}
/>
</RowRendererContainer>
),
@ -184,7 +184,7 @@ export const createEndpointLibraryRowRenderer = ({
data={data}
showMessage={false}
text={text}
timelineId={scopeId}
scopeId={scopeId}
/>
</RowRendererContainer>
),
@ -214,7 +214,7 @@ export const createGenericFileRowRenderer = ({
contextId={`${actionName}-${scopeId}`}
data={data}
text={text}
timelineId={scopeId}
scopeId={scopeId}
/>
</RowRendererContainer>
),
@ -238,7 +238,7 @@ export const createSocketRowRenderer = ({
contextId={`socket-${actionName}-${scopeId}`}
data={data}
text={text}
timelineId={scopeId}
scopeId={scopeId}
/>
</RowRendererContainer>
),
@ -307,7 +307,12 @@ export const createEndpointRegistryRowRenderer = ({
},
renderRow: ({ data, scopeId }) => (
<RowRendererContainer>
<RegistryEventDetails contextId={`registry-event-${scopeId}`} data={data} text={text} />
<RegistryEventDetails
contextId={`registry-event-${scopeId}`}
data={data}
text={text}
scopeId={scopeId}
/>
</RowRendererContainer>
),
});

View file

@ -11,6 +11,7 @@ import React from 'react';
import { TestProviders } from '../../../../../../common/mock';
import { useMountAppended } from '../../../../../../common/utils/use_mount_appended';
import { Package } from './package';
import { CellActionsWrapper } from '../../../../../../common/components/drag_and_drop/cell_actions_wrapper';
jest.mock('../../../../../../common/lib/kibana');
@ -22,13 +23,27 @@ jest.mock('@elastic/eui', () => {
};
});
jest.mock('../../../../../../common/components/drag_and_drop/cell_actions_wrapper', () => {
return {
CellActionsWrapper: jest.fn(),
};
});
const MockedCellActionsWrapper = jest.fn(({ children }) => {
return <div data-test-subj="mock-cell-action-wrapper">{children}</div>;
});
describe('Package', () => {
beforeEach(() => {
(CellActionsWrapper as unknown as jest.Mock).mockImplementation(MockedCellActionsWrapper);
});
const mount = useMountAppended();
describe('rendering', () => {
test('it renders against shallow snapshot', () => {
const wrapper = shallow(
<Package
scopeId="some_scope"
contextId="[context-123]"
eventId="[event-123]"
packageName="package-name-123"
@ -42,6 +57,7 @@ describe('Package', () => {
test('it returns null if all of the package information is null ', () => {
const wrapper = shallow(
<Package
scopeId="some_scope"
contextId="[context-123]"
eventId="[event-123]"
packageName={null}
@ -55,6 +71,7 @@ describe('Package', () => {
test('it returns null if all of the package information is undefined ', () => {
const wrapper = shallow(
<Package
scopeId="some_scope"
contextId="[context-123]"
eventId="[event-123]"
packageName={undefined}
@ -70,6 +87,7 @@ describe('Package', () => {
<TestProviders>
<div>
<Package
scopeId="some_scope"
contextId="[context-123]"
eventId="[event-123]"
packageName="[package-name-123]"
@ -87,6 +105,7 @@ describe('Package', () => {
<TestProviders>
<div>
<Package
scopeId="some_scope"
contextId="[context-123]"
eventId="[event-123]"
packageName="[package-name-123]"
@ -104,6 +123,7 @@ describe('Package', () => {
<TestProviders>
<div>
<Package
scopeId="some_scope"
contextId="[context-123]"
eventId="[event-123]"
packageName="[package-name-123]"
@ -117,5 +137,29 @@ describe('Package', () => {
'[package-name-123][package-version-123][package-summary-123]'
);
});
test('should passing correct scopeId to cell actions', () => {
mount(
<TestProviders>
<div>
<Package
scopeId="some_scope"
contextId="[context-123]"
eventId="[event-123]"
packageName="[package-name-123]"
packageSummary="[package-summary-123]"
packageVersion="[package-version-123]"
/>
</div>
</TestProviders>
);
expect(MockedCellActionsWrapper).toHaveBeenCalledWith(
expect.objectContaining({
scopeId: 'some_scope',
}),
{}
);
});
});
});

View file

@ -16,15 +16,17 @@ interface Props {
packageName: string | null | undefined;
packageSummary: string | null | undefined;
packageVersion: string | null | undefined;
scopeId: string;
}
export const Package = React.memo<Props>(
({ contextId, eventId, packageName, packageSummary, packageVersion }) => {
({ contextId, eventId, packageName, packageSummary, packageVersion, scopeId }) => {
if (packageName != null || packageSummary != null || packageVersion != null) {
return (
<>
<TokensFlexItem grow={false} component="span">
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={eventId}
field="system.audit.package.name"
@ -36,6 +38,7 @@ export const Package = React.memo<Props>(
</TokensFlexItem>
<TokensFlexItem grow={false} component="span">
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={eventId}
field="system.audit.package.version"
@ -47,6 +50,7 @@ export const Package = React.memo<Props>(
</TokensFlexItem>
<TokensFlexItem grow={false} component="span">
<DraggableBadge
scopeId={scopeId}
contextId={contextId}
eventId={eventId}
field="system.audit.package.summary"

View file

@ -11,6 +11,7 @@ import React from 'react';
import { TestProviders } from '../../../../../common/mock';
import { UserHostWorkingDir } from './user_host_working_dir';
import { useMountAppended } from '../../../../../common/utils/use_mount_appended';
import { CellActionsWrapper } from '../../../../../common/components/drag_and_drop/cell_actions_wrapper';
jest.mock('../../../../../common/lib/kibana');
@ -22,13 +23,27 @@ jest.mock('@elastic/eui', () => {
};
});
jest.mock('../../../../../common/components/drag_and_drop/cell_actions_wrapper', () => {
return {
CellActionsWrapper: jest.fn(),
};
});
const MockedCellActionsWrapper = jest.fn(({ children }) => {
return <div data-test-subj="mock-cell-action-wrapper">{children}</div>;
});
describe('UserHostWorkingDir', () => {
beforeEach(() => {
(CellActionsWrapper as unknown as jest.Mock).mockImplementation(MockedCellActionsWrapper);
});
const mount = useMountAppended();
describe('rendering', () => {
test('it renders against shallow snapshot', () => {
const wrapper = shallow(
<UserHostWorkingDir
scopeId="some_scope"
contextId="context-123"
eventId="event-123"
userDomain="[userDomain-123]"
@ -43,6 +58,7 @@ describe('UserHostWorkingDir', () => {
test('it returns null if userDomain, userName, hostName, and workingDirectory are all null', () => {
const wrapper = shallow(
<UserHostWorkingDir
scopeId="some_scope"
contextId="context-123"
eventId="event-123"
userDomain={null}
@ -57,6 +73,7 @@ describe('UserHostWorkingDir', () => {
test('it returns null if userDomain, userName, hostName, and workingDirectory are all undefined', () => {
const wrapper = shallow(
<UserHostWorkingDir
scopeId="some_scope"
contextId="context-123"
eventId="event-123"
userDomain={undefined}
@ -73,6 +90,7 @@ describe('UserHostWorkingDir', () => {
<TestProviders>
<div>
<UserHostWorkingDir
scopeId="some_scope"
contextId="context-123"
eventId="event-123"
userDomain="[user-domain-123]"
@ -91,6 +109,7 @@ describe('UserHostWorkingDir', () => {
<TestProviders>
<div>
<UserHostWorkingDir
scopeId="some_scope"
contextId="context-123"
eventId="event-123"
userDomain={undefined}
@ -109,6 +128,7 @@ describe('UserHostWorkingDir', () => {
<TestProviders>
<div>
<UserHostWorkingDir
scopeId="some_scope"
contextId="context-123"
eventId="event-123"
userDomain={undefined}
@ -127,6 +147,7 @@ describe('UserHostWorkingDir', () => {
<TestProviders>
<div>
<UserHostWorkingDir
scopeId="some_scope"
contextId="context-123"
eventId="event-123"
userDomain={null}
@ -145,6 +166,7 @@ describe('UserHostWorkingDir', () => {
<TestProviders>
<div>
<UserHostWorkingDir
scopeId="some_scope"
contextId="context-123"
eventId="event-123"
userDomain={null}
@ -163,6 +185,7 @@ describe('UserHostWorkingDir', () => {
<TestProviders>
<div>
<UserHostWorkingDir
scopeId="some_scope"
contextId="context-123"
eventId="event-123"
userDomain={null}
@ -181,6 +204,7 @@ describe('UserHostWorkingDir', () => {
<TestProviders>
<div>
<UserHostWorkingDir
scopeId="some_scope"
contextId="context-123"
eventId="event-123"
userDomain="[user-domain-123]"
@ -199,6 +223,7 @@ describe('UserHostWorkingDir', () => {
<TestProviders>
<div>
<UserHostWorkingDir
scopeId="some_scope"
contextId="context-123"
eventId="event-123"
userDomain={null}
@ -218,6 +243,7 @@ describe('UserHostWorkingDir', () => {
<TestProviders>
<div>
<UserHostWorkingDir
scopeId="some_scope"
contextId="context-123"
eventId="event-123"
hostNameSeparator="custom separator"
@ -238,6 +264,7 @@ describe('UserHostWorkingDir', () => {
<TestProviders>
<div>
<UserHostWorkingDir
scopeId="some_scope"
contextId="context-123"
eventId="event-123"
userDomain="[user-domain-123]"
@ -257,6 +284,7 @@ describe('UserHostWorkingDir', () => {
<TestProviders>
<div>
<UserHostWorkingDir
scopeId="some_scope"
contextId="context-123"
eventId="event-123"
userDomain="[user-domain-123]"
@ -279,6 +307,7 @@ describe('UserHostWorkingDir', () => {
<TestProviders>
<div>
<UserHostWorkingDir
scopeId="some_scope"
contextId="context-123"
eventId="event-123"
userDomain={undefined}
@ -298,6 +327,7 @@ describe('UserHostWorkingDir', () => {
<TestProviders>
<div>
<UserHostWorkingDir
scopeId="some_scope"
contextId="context-123"
eventId="event-123"
userDomain={undefined}
@ -314,5 +344,31 @@ describe('UserHostWorkingDir', () => {
true
);
});
test('should passing correct scopeId to cell actions', () => {
mount(
<TestProviders>
<div>
<UserHostWorkingDir
scopeId="some_scope"
contextId="context-123"
eventId="event-123"
userDomain={undefined}
userName="[user-name-123]"
userNameField="overridden.field.name"
hostName={undefined}
workingDirectory={undefined}
/>
</div>
</TestProviders>
);
expect(MockedCellActionsWrapper).toHaveBeenCalledWith(
expect.objectContaining({
scopeId: 'some_scope',
}),
{}
);
});
});
});

View file

@ -21,6 +21,7 @@ interface Props {
userName: string | null | undefined;
userNameField?: string;
workingDirectory: string | null | undefined;
scopeId: string;
}
export const UserHostWorkingDir = React.memo<Props>(
@ -34,6 +35,7 @@ export const UserHostWorkingDir = React.memo<Props>(
userName,
userNameField = 'user.name',
workingDirectory,
scopeId,
}) =>
userName != null || userDomain != null || hostName != null || workingDirectory != null ? (
<>
@ -46,6 +48,7 @@ export const UserHostWorkingDir = React.memo<Props>(
iconType="user"
fieldType="keyword"
isAggregatable={true}
scopeId={scopeId}
/>
</TokensFlexItem>
@ -66,6 +69,7 @@ export const UserHostWorkingDir = React.memo<Props>(
value={userDomain}
fieldType="keyword"
isAggregatable={true}
scopeId={scopeId}
/>
</TokensFlexItem>
</>
@ -77,6 +81,7 @@ export const UserHostWorkingDir = React.memo<Props>(
</TokensFlexItem>
)}
<HostWorkingDir
scopeId={scopeId}
contextId={contextId}
eventId={eventId}
hostName={hostName}

View file

@ -10,67 +10,81 @@ exports[`ZeekSignature rendering it renders the default Zeek 1`] = `
<DraggableZeekElement
field="zeek.session_id"
id="zeek-signature-draggable-zeek-element-test-14"
scopeId="test"
value="C8DRTq362Fios6hw16"
/>
<DraggableZeekElement
field="event.dataset"
id="zeek-signature-draggable-zeek-element-test-14"
scopeId="test"
stringRenderer={[Function]}
value="zeek.connection"
/>
<DraggableZeekElement
field="zeek.files.sha1"
id="zeek-signature-draggable-zeek-element-test-14"
scopeId="test"
stringRenderer={[Function]}
/>
<DraggableZeekElement
field="zeek.files.md5"
id="zeek-signature-draggable-zeek-element-test-14"
scopeId="test"
stringRenderer={[Function]}
/>
<DraggableZeekElement
field="zeek.notice.dropped"
id="zeek-signature-draggable-zeek-element-test-14"
scopeId="test"
stringRenderer={[Function]}
value={null}
/>
<DraggableZeekElement
field="zeek.ssl.version"
id="zeek-signature-draggable-zeek-element-test-14"
scopeId="test"
/>
<DraggableZeekElement
field="zeek.ssl.cipher"
id="zeek-signature-draggable-zeek-element-test-14"
scopeId="test"
/>
<DraggableZeekElement
field="zeek.connection.state"
id="zeek-signature-draggable-zeek-element-test-14"
scopeId="test"
value="REJ"
/>
<DraggableZeekElement
field="http.request.method"
id="zeek-signature-draggable-zeek-element-test-14"
scopeId="test"
/>
<DraggableZeekElement
field="zeek.connection.history"
id="zeek-signature-draggable-zeek-element-test-14"
scopeId="test"
value="Sr"
/>
<DraggableZeekElement
field="zeek.notice.note"
id="zeek-signature-draggable-zeek-element-test-14"
scopeId="test"
/>
<DraggableZeekElement
field="zeek.dns.query"
id="zeek-signature-draggable-zeek-element-test-14"
scopeId="test"
/>
<DraggableZeekElement
field="zeek.dns.qclass_name"
id="zeek-signature-draggable-zeek-element-test-14"
scopeId="test"
/>
<DraggableZeekElement
field="http.response.status_code"
id="zeek-signature-draggable-zeek-element-test-14"
scopeId="test"
/>
</EuiFlexGroup>
<EuiFlexGroup

View file

@ -26,9 +26,20 @@ import {
moduleStringRenderer,
defaultStringRenderer,
} from './zeek_signature';
import { CellActionsWrapper } from '../../../../../../common/components/drag_and_drop/cell_actions_wrapper';
jest.mock('../../../../../../common/lib/kibana');
jest.mock('../../../../../../common/components/drag_and_drop/cell_actions_wrapper', () => {
return {
CellActionsWrapper: jest.fn(),
};
});
const MockedCellActionsWrapper = jest.fn(({ children }) => {
return <div data-test-subj="mock-cell-action-wrapper">{children}</div>;
});
jest.mock('@elastic/eui', () => {
const original = jest.requireActual('@elastic/eui');
return {
@ -116,10 +127,14 @@ describe('ZeekSignature', () => {
});
describe('DraggableZeekElement', () => {
beforeEach(() => {
(CellActionsWrapper as unknown as jest.Mock).mockImplementation(MockedCellActionsWrapper);
});
test('it returns null if value is null', () => {
const wrapper = mount(
<TestProviders>
<DraggableZeekElement id="id-123" field="zeek.notice" value={null} />
<DraggableZeekElement scopeId="some_scope" id="id-123" field="zeek.notice" value={null} />
</TestProviders>
);
expect(wrapper.find('DraggableZeekElement').children().exists()).toBeFalsy();
@ -128,7 +143,12 @@ describe('ZeekSignature', () => {
test('it renders the default ZeekSignature', () => {
const wrapper = mount(
<TestProviders>
<DraggableZeekElement id="id-123" field="zeek.notice" value={'mynote'} />
<DraggableZeekElement
scopeId="some_scope"
id="id-123"
field="zeek.notice"
value={'mynote'}
/>
</TestProviders>
);
expect(wrapper.text()).toEqual('mynote');
@ -138,6 +158,7 @@ describe('ZeekSignature', () => {
const wrapper = mount(
<TestProviders>
<DraggableZeekElement
scopeId="some_scope"
id="id-123"
field="zeek.notice"
value={'mynote'}
@ -148,12 +169,38 @@ describe('ZeekSignature', () => {
expect(wrapper.text()).toEqual('->mynote<-');
});
test('should passing correct scopeId to cell actions', () => {
mount(
<TestProviders>
<DraggableZeekElement
scopeId="some_scope"
id="id-123"
field="zeek.notice"
value={'mynote'}
stringRenderer={(value) => `->${value}<-`}
/>
</TestProviders>
);
expect(MockedCellActionsWrapper).toHaveBeenCalledWith(
expect.objectContaining({
scopeId: 'some_scope',
}),
{}
);
});
describe('#TagTooltip', () => {
test('it renders the name of the field in a tooltip', () => {
const field = 'zeek.notice';
const wrapper = mount(
<TestProviders>
<DraggableZeekElement id="id-123" field={field} value={'the people you love'} />
<DraggableZeekElement
scopeId="some_scope"
id="id-123"
field={field}
value={'the people you love'}
/>
</TestProviders>
);

View file

@ -67,7 +67,8 @@ export const DraggableZeekElement = React.memo<{
field: string;
value: string | null | undefined;
stringRenderer?: StringRenderer;
}>(({ id, field, value, stringRenderer = defaultStringRenderer }) => {
scopeId: string;
}>(({ id, field, value, stringRenderer = defaultStringRenderer, scopeId }) => {
const dataProviderProp = useMemo(
() => ({
and: [],
@ -99,6 +100,7 @@ export const DraggableZeekElement = React.memo<{
return value != null ? (
<TokensFlexItem grow={false}>
<DraggableWrapper
scopeId={scopeId}
dataProvider={dataProviderProp}
render={render}
isAggregatable={true}
@ -232,40 +234,80 @@ export const ZeekSignature = React.memo<ZeekSignatureProps>(({ data, timelineId
return (
<>
<EuiFlexGroup justifyContent="center" gutterSize="none" wrap={true}>
<DraggableZeekElement id={id} field="zeek.session_id" value={sessionId} />
<DraggableZeekElement
scopeId={timelineId}
id={id}
field="zeek.session_id"
value={sessionId}
/>
<DraggableZeekElement
id={id}
field="event.dataset"
value={dataSet}
stringRenderer={moduleStringRenderer}
scopeId={timelineId}
/>
<DraggableZeekElement
id={id}
field="zeek.files.sha1"
value={fileSha1}
stringRenderer={sha1StringRenderer}
scopeId={timelineId}
/>
<DraggableZeekElement
id={id}
field="zeek.files.md5"
value={filemd5}
stringRenderer={md5StringRenderer}
scopeId={timelineId}
/>
<DraggableZeekElement
id={id}
field="zeek.notice.dropped"
value={dropped}
stringRenderer={droppedStringRenderer}
scopeId={timelineId}
/>
<DraggableZeekElement id={id} field="zeek.ssl.version" value={sslVersion} />
<DraggableZeekElement id={id} field="zeek.ssl.cipher" value={cipher} />
<DraggableZeekElement id={id} field="zeek.connection.state" value={state} />
<DraggableZeekElement id={id} field="http.request.method" value={httpMethod} />
<DraggableZeekElement id={id} field="zeek.connection.history" value={history} />
<DraggableZeekElement id={id} field="zeek.notice.note" value={note} />
<DraggableZeekElement id={id} field="zeek.dns.query" value={dnsQuery} />
<DraggableZeekElement id={id} field="zeek.dns.qclass_name" value={qClassName} />
<DraggableZeekElement
scopeId={timelineId}
id={id}
field="zeek.ssl.version"
value={sslVersion}
/>
<DraggableZeekElement scopeId={timelineId} id={id} field="zeek.ssl.cipher" value={cipher} />
<DraggableZeekElement
scopeId={timelineId}
id={id}
field="zeek.connection.state"
value={state}
/>
<DraggableZeekElement
scopeId={timelineId}
id={id}
field="http.request.method"
value={httpMethod}
/>
<DraggableZeekElement
scopeId={timelineId}
id={id}
field="zeek.connection.history"
value={history}
/>
<DraggableZeekElement scopeId={timelineId} id={id} field="zeek.notice.note" value={note} />
<DraggableZeekElement
scopeId={timelineId}
id={id}
field="zeek.dns.query"
value={dnsQuery}
/>
<DraggableZeekElement
scopeId={timelineId}
id={id}
field="zeek.dns.qclass_name"
value={qClassName}
/>
<DraggableZeekElement
scopeId={timelineId}
id={id}
field="http.response.status_code"
value={httpResponseStatusCode}