forked from elastic/kibana
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Security Solution] Remove sourcerer browser fields hover actions to …
…help performance (elastic#131363) * Batch setState calls to make sure all state updates are applied evenly * Remove sourcerer hook from useHoverActions and pass needed fields as props * Update snapshots, remove ReactDOM batching * Make row renderers aggregatable where appropriate * add pagination to details table * Fix hover actions on host/network details * Remove unneeded props * fix table pagination tests * update test * Show top n for authentications and threat indicator match rules * Fix anomaly score, entity, influence, and user id show top N * Pass props on wrapper and not data provider * Add missing row renderer draggables to use top N props * Update snapshots * Pr feedback Co-authored-by: Michael Olorunnisola <michael.olorunnisola@elastic.co> Co-authored-by: Robert Austin <robert.austin@elastic.co> (cherry picked from commit f3c1ad7) # Conflicts: # x-pack/plugins/security_solution/public/common/components/authentication/helpers.tsx # x-pack/plugins/security_solution/public/common/lib/cell_actions/expanded_cell_value_actions.tsx
- Loading branch information
1 parent
bd49aeb
commit 02cc9a5
Showing
90 changed files
with
902 additions
and
107 deletions.
There are no files selected for viewing
309 changes: 309 additions & 0 deletions
309
x-pack/plugins/security_solution/public/common/components/authentication/helpers.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,309 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
import { has } from 'lodash/fp'; | ||
import React from 'react'; | ||
|
||
import { DragEffects, DraggableWrapper } from '../drag_and_drop/draggable_wrapper'; | ||
import { escapeDataProviderId } from '../drag_and_drop/helpers'; | ||
import { getEmptyTagValue } from '../empty_value'; | ||
import { FormattedRelativePreferenceDate } from '../formatted_date'; | ||
import { Columns, ItemsPerRow } from '../paginated_table'; | ||
import { IS_OPERATOR } from '../../../timelines/components/timeline/data_providers/data_provider'; | ||
import { Provider } from '../../../timelines/components/timeline/data_providers/provider'; | ||
import { getRowItemDraggables } from '../tables/helpers'; | ||
|
||
import * as i18n from './translations'; | ||
import { HostDetailsLink, NetworkDetailsLink, UserDetailsLink } from '../links'; | ||
import { AuthenticationsEdges, MatrixHistogramType } from '../../../../common/search_strategy'; | ||
import { AuthTableColumns } from './types'; | ||
import { | ||
MatrixHistogramConfigs, | ||
MatrixHistogramMappingTypes, | ||
MatrixHistogramOption, | ||
} from '../matrix_histogram/types'; | ||
import { LensAttributes } from '../visualization_actions/types'; | ||
import { authenticationLensAttributes } from '../visualization_actions/lens_attributes/common/authentication'; | ||
|
||
export const getHostDetailsAuthenticationColumns = (usersEnabled: boolean): AuthTableColumns => [ | ||
getUserColumn(usersEnabled), | ||
SUCCESS_COLUMN, | ||
FAILURES_COLUMN, | ||
LAST_SUCCESSFUL_TIME_COLUMN, | ||
LAST_SUCCESSFUL_SOURCE_COLUMN, | ||
LAST_FAILED_TIME_COLUMN, | ||
LAST_FAILED_SOURCE_COLUMN, | ||
]; | ||
|
||
export const getHostsPageAuthenticationColumns = (usersEnabled: boolean): AuthTableColumns => [ | ||
getUserColumn(usersEnabled), | ||
SUCCESS_COLUMN, | ||
FAILURES_COLUMN, | ||
LAST_SUCCESSFUL_TIME_COLUMN, | ||
LAST_SUCCESSFUL_SOURCE_COLUMN, | ||
LAST_SUCCESSFUL_DESTINATION_COLUMN, | ||
LAST_FAILED_TIME_COLUMN, | ||
LAST_FAILED_SOURCE_COLUMN, | ||
LAST_FAILED_DESTINATION_COLUMN, | ||
]; | ||
|
||
export const getUsersPageAuthenticationColumns = (): AuthTableColumns => | ||
getHostsPageAuthenticationColumns(true); | ||
|
||
export const getUserDetailsAuthenticationColumns = (): AuthTableColumns => [ | ||
HOST_COLUMN, | ||
SUCCESS_COLUMN, | ||
FAILURES_COLUMN, | ||
LAST_SUCCESSFUL_TIME_COLUMN, | ||
LAST_SUCCESSFUL_SOURCE_COLUMN, | ||
LAST_FAILED_TIME_COLUMN, | ||
LAST_FAILED_SOURCE_COLUMN, | ||
]; | ||
|
||
export const rowItems: ItemsPerRow[] = [ | ||
{ | ||
text: i18n.ROWS_5, | ||
numberOfRow: 5, | ||
}, | ||
{ | ||
text: i18n.ROWS_10, | ||
numberOfRow: 10, | ||
}, | ||
]; | ||
|
||
const FAILURES_COLUMN: Columns<AuthenticationsEdges, AuthenticationsEdges> = { | ||
name: i18n.FAILURES, | ||
truncateText: false, | ||
mobileOptions: { show: true }, | ||
render: ({ node }) => { | ||
const id = escapeDataProviderId(`authentications-table-${node._id}-failures-${node.failures}`); | ||
return ( | ||
<DraggableWrapper | ||
key={id} | ||
dataProvider={{ | ||
and: [], | ||
enabled: true, | ||
id, | ||
name: 'authentication_failure', | ||
excluded: false, | ||
kqlQuery: '', | ||
queryMatch: { | ||
field: 'event.type', | ||
value: 'authentication_failure', | ||
operator: IS_OPERATOR, | ||
}, | ||
}} | ||
isAggregatable={true} | ||
fieldType={'keyword'} | ||
render={(dataProvider, _, snapshot) => | ||
snapshot.isDragging ? ( | ||
<DragEffects> | ||
<Provider dataProvider={dataProvider} /> | ||
</DragEffects> | ||
) : ( | ||
node.failures | ||
) | ||
} | ||
/> | ||
); | ||
}, | ||
width: '8%', | ||
}; | ||
const LAST_SUCCESSFUL_TIME_COLUMN: Columns<AuthenticationsEdges, AuthenticationsEdges> = { | ||
name: i18n.LAST_SUCCESSFUL_TIME, | ||
truncateText: false, | ||
mobileOptions: { show: true }, | ||
render: ({ node }) => | ||
has('lastSuccess.timestamp', node) && node.lastSuccess?.timestamp != null ? ( | ||
<FormattedRelativePreferenceDate value={node.lastSuccess?.timestamp} /> | ||
) : ( | ||
getEmptyTagValue() | ||
), | ||
}; | ||
const LAST_SUCCESSFUL_SOURCE_COLUMN: Columns<AuthenticationsEdges, AuthenticationsEdges> = { | ||
name: i18n.LAST_SUCCESSFUL_SOURCE, | ||
truncateText: false, | ||
mobileOptions: { show: true }, | ||
render: ({ node }) => | ||
getRowItemDraggables({ | ||
rowItems: node.lastSuccess?.source?.ip || null, | ||
isAggregatable: true, | ||
fieldType: 'ip', | ||
attrName: 'source.ip', | ||
idPrefix: `authentications-table-${node._id}-lastSuccessSource`, | ||
render: (item) => <NetworkDetailsLink ip={item} />, | ||
}), | ||
}; | ||
const LAST_SUCCESSFUL_DESTINATION_COLUMN: Columns<AuthenticationsEdges, AuthenticationsEdges> = { | ||
name: i18n.LAST_SUCCESSFUL_DESTINATION, | ||
truncateText: false, | ||
mobileOptions: { show: true }, | ||
render: ({ node }) => | ||
getRowItemDraggables({ | ||
rowItems: node.lastSuccess?.host?.name ?? null, | ||
isAggregatable: true, | ||
fieldType: 'keyword', | ||
attrName: 'host.name', | ||
idPrefix: `authentications-table-${node._id}-lastSuccessfulDestination`, | ||
render: (item) => <HostDetailsLink hostName={item} />, | ||
}), | ||
}; | ||
const LAST_FAILED_TIME_COLUMN: Columns<AuthenticationsEdges, AuthenticationsEdges> = { | ||
name: i18n.LAST_FAILED_TIME, | ||
truncateText: false, | ||
mobileOptions: { show: true }, | ||
render: ({ node }) => | ||
has('lastFailure.timestamp', node) && node.lastFailure?.timestamp != null ? ( | ||
<FormattedRelativePreferenceDate value={node.lastFailure?.timestamp} /> | ||
) : ( | ||
getEmptyTagValue() | ||
), | ||
}; | ||
const LAST_FAILED_SOURCE_COLUMN: Columns<AuthenticationsEdges, AuthenticationsEdges> = { | ||
name: i18n.LAST_FAILED_SOURCE, | ||
truncateText: false, | ||
mobileOptions: { show: true }, | ||
render: ({ node }) => | ||
getRowItemDraggables({ | ||
rowItems: node.lastFailure?.source?.ip || null, | ||
isAggregatable: true, | ||
fieldType: 'ip', | ||
attrName: 'source.ip', | ||
idPrefix: `authentications-table-${node._id}-lastFailureSource`, | ||
render: (item) => <NetworkDetailsLink ip={item} />, | ||
}), | ||
}; | ||
const LAST_FAILED_DESTINATION_COLUMN: Columns<AuthenticationsEdges, AuthenticationsEdges> = { | ||
name: i18n.LAST_FAILED_DESTINATION, | ||
truncateText: false, | ||
mobileOptions: { show: true }, | ||
render: ({ node }) => | ||
getRowItemDraggables({ | ||
rowItems: node.lastFailure?.host?.name || null, | ||
attrName: 'host.name', | ||
idPrefix: `authentications-table-${node._id}-lastFailureDestination`, | ||
render: (item) => <HostDetailsLink hostName={item} />, | ||
isAggregatable: true, | ||
fieldType: 'ip', | ||
}), | ||
}; | ||
|
||
const getUserColumn = ( | ||
usersEnabled: boolean | ||
): Columns<AuthenticationsEdges, AuthenticationsEdges> => ({ | ||
name: i18n.USER, | ||
truncateText: false, | ||
mobileOptions: { show: true }, | ||
render: ({ node }) => | ||
getRowItemDraggables({ | ||
rowItems: node.stackedValue, | ||
attrName: 'user.name', | ||
isAggregatable: true, | ||
fieldType: 'keyword', | ||
idPrefix: `authentications-table-${node._id}-userName`, | ||
render: (item) => (usersEnabled ? <UserDetailsLink userName={item} /> : <>{item}</>), | ||
}), | ||
}); | ||
|
||
const HOST_COLUMN: Columns<AuthenticationsEdges, AuthenticationsEdges> = { | ||
name: i18n.HOST, | ||
truncateText: false, | ||
mobileOptions: { show: true }, | ||
render: ({ node }) => | ||
getRowItemDraggables({ | ||
rowItems: node.stackedValue, | ||
attrName: 'host.name', | ||
isAggregatable: true, | ||
fieldType: 'keyword', | ||
idPrefix: `authentications-table-${node._id}-hostName`, | ||
render: (item) => <HostDetailsLink hostName={item} />, | ||
}), | ||
}; | ||
|
||
const SUCCESS_COLUMN: Columns<AuthenticationsEdges, AuthenticationsEdges> = { | ||
name: i18n.SUCCESSES, | ||
truncateText: false, | ||
mobileOptions: { show: true }, | ||
render: ({ node }) => { | ||
const id = escapeDataProviderId( | ||
`authentications-table-${node._id}-node-successes-${node.successes}` | ||
); | ||
return ( | ||
<DraggableWrapper | ||
key={id} | ||
dataProvider={{ | ||
and: [], | ||
enabled: true, | ||
id, | ||
name: 'authentication_success', | ||
excluded: false, | ||
kqlQuery: '', | ||
queryMatch: { | ||
field: 'event.type', | ||
value: 'authentication_success', | ||
operator: IS_OPERATOR, | ||
}, | ||
}} | ||
isAggregatable={true} | ||
fieldType="keyword" | ||
render={(dataProvider, _, snapshot) => | ||
snapshot.isDragging ? ( | ||
<DragEffects> | ||
<Provider dataProvider={dataProvider} /> | ||
</DragEffects> | ||
) : ( | ||
node.successes | ||
) | ||
} | ||
/> | ||
); | ||
}, | ||
width: '8%', | ||
}; | ||
|
||
export const authenticationsStackByOptions: MatrixHistogramOption[] = [ | ||
{ | ||
text: 'event.outcome', | ||
value: 'event.outcome', | ||
}, | ||
]; | ||
const DEFAULT_STACK_BY = 'event.outcome'; | ||
|
||
enum AuthenticationsMatrixDataGroup { | ||
authenticationsSuccess = 'success', | ||
authenticationsFailure = 'failure', | ||
} | ||
|
||
export enum ChartColors { | ||
authenticationsSuccess = '#54B399', | ||
authenticationsFailure = '#E7664C', | ||
} | ||
|
||
export const authenticationsMatrixDataMappingFields: MatrixHistogramMappingTypes = { | ||
[AuthenticationsMatrixDataGroup.authenticationsSuccess]: { | ||
key: AuthenticationsMatrixDataGroup.authenticationsSuccess, | ||
value: null, | ||
color: ChartColors.authenticationsSuccess, | ||
}, | ||
[AuthenticationsMatrixDataGroup.authenticationsFailure]: { | ||
key: AuthenticationsMatrixDataGroup.authenticationsFailure, | ||
value: null, | ||
color: ChartColors.authenticationsFailure, | ||
}, | ||
}; | ||
|
||
export const histogramConfigs: MatrixHistogramConfigs = { | ||
defaultStackByOption: | ||
authenticationsStackByOptions.find((o) => o.text === DEFAULT_STACK_BY) ?? | ||
authenticationsStackByOptions[0], | ||
errorMessage: i18n.ERROR_FETCHING_AUTHENTICATIONS_DATA, | ||
histogramType: MatrixHistogramType.authentications, | ||
mapping: authenticationsMatrixDataMappingFields, | ||
stackByOptions: authenticationsStackByOptions, | ||
title: i18n.NAVIGATION_AUTHENTICATIONS_TITLE, | ||
lensAttributes: authenticationLensAttributes as LensAttributes, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.