Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revert "[8.11] [Security Solutions] Update risk score tables to filte… #169751

Merged
merged 4 commits into from
Oct 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,6 @@ export interface RiskScoreItem {
[RiskScoreFields.hostName]: Maybe<string>;
[RiskScoreFields.userName]: Maybe<string>;

[RiskScoreFields.timestamp]: Maybe<string>;

[RiskScoreFields.hostRisk]: Maybe<RiskSeverity>;
[RiskScoreFields.userRisk]: Maybe<RiskSeverity>;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import type { CommonFields, Maybe, RiskScoreFields, RiskSeverity, SortField } fr
export interface UserRiskScoreItem {
_id?: Maybe<string>;
[RiskScoreFields.userName]: Maybe<string>;
[RiskScoreFields.timestamp]: Maybe<string>;
[RiskScoreFields.userRisk]: Maybe<RiskSeverity>;
[RiskScoreFields.userRiskScore]: Maybe<number>;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import * as i18n from './translations';
import { RiskScoreHeaderTitle } from './risk_score_header_title';
import { RiskScoreRestartButton } from './risk_score_restart_button';
import type { inputsModel } from '../../../../common/store';
import * as overviewI18n from '../../../../overview/components/entity_analytics/common/translations';
import { useIsNewRiskScoreModuleInstalled } from '../../../../entity_analytics/api/hooks/use_risk_engine_status';

const RiskScoresNoDataDetectedComponent = ({
Expand All @@ -36,7 +37,15 @@ const RiskScoresNoDataDetectedComponent = ({

return (
<EuiPanel data-test-subj={`${entityType}-risk-score-no-data-detected`} hasBorder>
<HeaderSection title={<RiskScoreHeaderTitle riskScoreEntity={entityType} />} titleSize="s" />
<HeaderSection
title={<RiskScoreHeaderTitle riskScoreEntity={entityType} />}
titleSize="s"
tooltip={
entityType === RiskScoreEntity.user
? overviewI18n.USER_RISK_TABLE_TOOLTIP
: overviewI18n.HOST_RISK_TABLE_TOOLTIP
}
/>
<EuiEmptyPrompt
title={<h2>{translations.title}</h2>}
body={translations.body}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,13 @@ export const useRiskScore = <T extends RiskScoreEntity.host | RiskScoreEntity.us
}
}, [defaultIndex, refetch, refetchDeprecated]);

// since query does not take timerange arg, we need to manually refetch when time range updates
// the results can be different if the user has run the ML for the first time since pressing refresh
useEffect(() => {
refetchAll();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [timerange?.to, timerange?.from]);

const riskScoreResponse = useMemo(
() => ({
data: response.data,
Expand Down Expand Up @@ -161,7 +168,7 @@ export const useRiskScore = <T extends RiskScoreEntity.host | RiskScoreEntity.us
}
: undefined,
sort,
timerange: requestTimerange,
timerange: onlyLatest ? undefined : requestTimerange,
alertsTimerange: includeAlertsCount ? requestTimerange : undefined,
}
: null,
Expand All @@ -173,6 +180,7 @@ export const useRiskScore = <T extends RiskScoreEntity.host | RiskScoreEntity.us
querySize,
sort,
requestTimerange,
onlyLatest,
riskEntity,
includeAlertsCount,
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* 2.0.
*/

import { useEffect, useMemo, useCallback } from 'react';
import { useEffect, useMemo } from 'react';

import {
getHostRiskIndex,
Expand All @@ -26,7 +26,6 @@ import type { InspectResponse } from '../../../../types';
import type { inputsModel } from '../../../../common/store';
import { useAppToasts } from '../../../../common/hooks/use_app_toasts';
import { useIsNewRiskScoreModuleInstalled } from '../../../../entity_analytics/api/hooks/use_risk_engine_status';
import { useRiskScoreFeatureStatus } from '../feature_status';

interface RiskScoreKpi {
error: unknown;
Expand Down Expand Up @@ -61,14 +60,6 @@ export const useRiskScoreKpi = ({
: getUserRiskIndex(spaceId, true, isNewRiskScoreModuleInstalled)
: undefined;

const {
isDeprecated,
isEnabled,
isAuthorized,
isLoading: isDeprecatedLoading,
refetch: refetchFeatureStatus,
} = useRiskScoreFeatureStatus(riskEntity, defaultIndex);

const { loading, result, search, refetch, inspect, error } =
useSearchStrategy<RiskQueries.kpiRiskScore>({
factoryQueryType: RiskQueries.kpiRiskScore,
Expand All @@ -81,40 +72,21 @@ export const useRiskScoreKpi = ({

const isModuleDisabled = !!error && isIndexNotFoundError(error);

const requestTimerange = useMemo(
() => (timerange ? { to: timerange.to, from: timerange.from, interval: '' } : undefined),
[timerange]
);

useEffect(() => {
if (!skip && defaultIndex && featureEnabled) {
search({
filterQuery,
defaultIndex: [defaultIndex],
entity: riskEntity,
timerange: requestTimerange,
});
}
}, [
defaultIndex,
search,
filterQuery,
skip,
riskEntity,
requestTimerange,
isEnabled,
isDeprecated,
isAuthorized,
isDeprecatedLoading,
featureEnabled,
]);
}, [defaultIndex, search, filterQuery, skip, riskEntity, featureEnabled]);

const refetchAll = useCallback(() => {
if (defaultIndex) {
refetchFeatureStatus(defaultIndex);
refetch();
}
}, [defaultIndex, refetch, refetchFeatureStatus]);
// since query does not take timerange arg, we need to manually refetch when time range updates
useEffect(() => {
refetch();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [timerange?.to, timerange?.from]);

useEffect(() => {
if (error) {
Expand All @@ -138,5 +110,5 @@ export const useRiskScoreKpi = ({
};
}, [result, loading, error]);

return { error, severityCount, loading, isModuleDisabled, refetch: refetchAll, inspect };
return { error, severityCount, loading, isModuleDisabled, refetch, inspect };
};
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ describe('getHostRiskScoreColumns', () => {
});

const riskScore = 10.11111111;
const riskScoreColumn = columns[2];
const riskScoreColumn = columns[1];
const renderedColumn = riskScoreColumn.render!(riskScore, null);

const { queryByTestId } = render(<TestProviders>{renderedColumn}</TestProviders>);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,11 @@ import { HostDetailsLink } from '../../../../common/components/links';
import type { HostRiskScoreColumns } from '.';
import * as i18n from './translations';
import { HostsTableType } from '../../store/model';
import type { Maybe, RiskSeverity } from '../../../../../common/search_strategy';
import type { RiskSeverity } from '../../../../../common/search_strategy';
import { RiskScoreFields, RiskScoreEntity } from '../../../../../common/search_strategy';
import { RiskScoreLevel } from '../../../components/risk_score/severity/common';
import { ENTITY_RISK_LEVEL } from '../../../components/risk_score/translations';
import { CELL_ACTIONS_TELEMETRY } from '../../../components/risk_score/constants';
import { FormattedRelativePreferenceDate } from '../../../../common/components/formatted_date';

export const getHostRiskScoreColumns = ({
dispatchSeverityUpdate,
Expand All @@ -35,7 +34,6 @@ export const getHostRiskScoreColumns = ({
truncateText: false,
mobileOptions: { show: true },
sortable: true,
width: '35%',
render: (hostName) => {
if (hostName != null && hostName.length > 0) {
return (
Expand All @@ -59,19 +57,6 @@ export const getHostRiskScoreColumns = ({
return getEmptyTagValue();
},
},
{
field: RiskScoreFields.timestamp,
name: i18n.LAST_UPDATED,
truncateText: false,
mobileOptions: { show: true },
sortable: true,
render: (lastSeen: Maybe<string>) => {
if (lastSeen != null) {
return <FormattedRelativePreferenceDate value={lastSeen} />;
}
return getEmptyTagValue();
},
},
{
field: RiskScoreFields.hostRiskScore,
name: i18n.HOST_RISK_SCORE,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ interface HostRiskScoreTableProps {

export type HostRiskScoreColumns = [
Columns<RiskScoreItem[RiskScoreFields.hostName]>,
Columns<RiskScoreItem[RiskScoreFields.timestamp]>,
Columns<RiskScoreItem[RiskScoreFields.hostRiskScore]>,
Columns<RiskScoreItem[RiskScoreFields.hostRisk]>
];
Expand Down Expand Up @@ -192,6 +191,7 @@ const HostRiskScoreTableComponent: React.FC<HostRiskScoreTableProps> = ({
headerSupplement={risk}
headerTitle={i18nHosts.HOST_RISK_TITLE}
headerUnit={i18n.UNIT(totalCount)}
headerTooltip={i18nHosts.HOST_RISK_TABLE_TOOLTIP}
id={id}
isInspect={isInspect}
itemsPerRow={rowItems}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,16 @@ export const HOST_RISK_TITLE = i18n.translate(
}
);

export const HOST_RISK_TABLE_TOOLTIP = i18n.translate(
'xpack.securitySolution.hostsRiskTable.hostsTableTooltip',
{
defaultMessage:
'The host risk table is not affected by the KQL time range. This table shows the latest recorded risk score for each host.',
}
);

export const VIEW_HOSTS_BY_SEVERITY = (severity: string) =>
i18n.translate('xpack.securitySolution.hostsRiskTable.filteredHostsTitle', {
values: { severity },
defaultMessage: 'View {severity} risk hosts',
});

export const LAST_UPDATED = i18n.translate(
'xpack.securitySolution.hostsRiskTable.lastUpdatedTitle',
{
defaultMessage: 'Last updated',
}
);
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,8 @@ describe('getUserRiskScoreColumns', () => {
const columns = getUserRiskScoreColumns(defaultProps);

expect(columns[0].field).toBe('user.name');
expect(columns[1].field).toBe(RiskScoreFields.timestamp);
expect(columns[2].field).toBe(RiskScoreFields.userRiskScore);
expect(columns[3].field).toBe(RiskScoreFields.userRisk);
expect(columns[1].field).toBe(RiskScoreFields.userRiskScore);
expect(columns[2].field).toBe(RiskScoreFields.userRisk);

columns.forEach((column) => {
expect(column).toHaveProperty('name');
Expand All @@ -46,7 +45,7 @@ describe('getUserRiskScoreColumns', () => {
const columns: UserRiskScoreColumns = getUserRiskScoreColumns(defaultProps);

const riskScore = 10.11111111;
const riskScoreColumn = columns[2];
const riskScoreColumn = columns[1];
const renderedColumn = riskScoreColumn.render!(riskScore, null);

const { queryByTestId } = render(<TestProviders>{renderedColumn}</TestProviders>);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,12 @@ import { getEmptyTagValue } from '../../../../common/components/empty_value';
import type { UserRiskScoreColumns } from '.';
import * as i18n from './translations';
import { RiskScoreLevel } from '../../../components/risk_score/severity/common';
import type { Maybe, RiskSeverity } from '../../../../../common/search_strategy';
import type { RiskSeverity } from '../../../../../common/search_strategy';
import { RiskScoreEntity, RiskScoreFields } from '../../../../../common/search_strategy';
import { UserDetailsLink } from '../../../../common/components/links';
import { UsersTableType } from '../../store/model';
import { ENTITY_RISK_LEVEL } from '../../../components/risk_score/translations';
import { CELL_ACTIONS_TELEMETRY } from '../../../components/risk_score/constants';
import { FormattedRelativePreferenceDate } from '../../../../common/components/formatted_date';

export const getUserRiskScoreColumns = ({
dispatchSeverityUpdate,
Expand All @@ -36,7 +35,6 @@ export const getUserRiskScoreColumns = ({
truncateText: false,
mobileOptions: { show: true },
sortable: true,
width: '35%',
render: (userName) => {
if (userName != null && userName.length > 0) {
const id = escapeDataProviderId(`user-risk-score-table-userName-${userName}`);
Expand All @@ -62,19 +60,6 @@ export const getUserRiskScoreColumns = ({
return getEmptyTagValue();
},
},
{
field: RiskScoreFields.timestamp,
name: i18n.LAST_UPDATED,
truncateText: false,
mobileOptions: { show: true },
sortable: true,
render: (lastSeen: Maybe<string>) => {
if (lastSeen != null) {
return <FormattedRelativePreferenceDate value={lastSeen} />;
}
return getEmptyTagValue();
},
},
{
field: RiskScoreFields.userRiskScore,
name: i18n.USER_RISK_SCORE,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ interface UserRiskScoreTableProps {

export type UserRiskScoreColumns = [
Columns<UserRiskScoreItem[RiskScoreFields.userName]>,
Columns<UserRiskScoreItem[RiskScoreFields.timestamp]>,
Columns<UserRiskScoreItem[RiskScoreFields.userRiskScore]>,
Columns<UserRiskScoreItem[RiskScoreFields.userRisk]>
];
Expand Down Expand Up @@ -192,6 +191,7 @@ const UserRiskScoreTableComponent: React.FC<UserRiskScoreTableProps> = ({
}
headerSupplement={risk}
headerTitle={i18nUsers.NAVIGATION_RISK_TITLE}
headerTooltip={i18n.USER_RISK_TABLE_TOOLTIP}
headerUnit={i18n.UNIT(totalCount)}
id={id}
isInspect={isInspect}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ export const ROWS_10 = i18n.translate('xpack.securitySolution.usersTable.rows',
defaultMessage: '{numRows} {numRows, plural, =0 {rows} =1 {row} other {rows}}',
});

export const LAST_UPDATED = i18n.translate('xpack.securitySolution.usersTable.lastUpdatedTitle', {
defaultMessage: 'Last updated',
});
export const USER_RISK_TABLE_TOOLTIP = i18n.translate(
'xpack.securitySolution.hostsRiskTable.usersTableTooltip',
{
defaultMessage:
'The user risk table is not affected by the KQL time range. This table shows the latest recorded risk score for each user.',
}
);
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,19 @@ export const USER_RISK_TITLE = i18n.translate(
defaultMessage: 'User Risk Scores',
}
);

export const HOST_RISK_TABLE_TOOLTIP = i18n.translate(
'xpack.securitySolution.entityAnalytics.hostsRiskDashboard.hostsTableTooltip',
{
defaultMessage:
'The host risk table is not affected by the time range. This table shows the latest recorded risk score for each host.',
}
);

export const USER_RISK_TABLE_TOOLTIP = i18n.translate(
'xpack.securitySolution.entityAnalytics.usersRiskDashboard.usersTableTooltip',
{
defaultMessage:
'The user risk table is not affected by the time range. This table shows the latest recorded risk score for each user.',
}
);
Loading
Loading