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

[Security Solution] Co-locate Frontend Entity Analytics Code #173499

Merged
merged 13 commits into from
Dec 21, 2023
5 changes: 0 additions & 5 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -1497,17 +1497,12 @@ x-pack/test/threat_intelligence_cypress @elastic/protections-experience
x-pack/plugins/security_solution/common/entity_analytics @elastic/security-entity-analytics
x-pack/plugins/security_solution/common/search_strategy/security_solution/risk_score @elastic/security-entity-analytics
x-pack/plugins/security_solution/public/entity_analytics @elastic/security-entity-analytics
x-pack/plugins/security_solution/public/explore/components/risk_score @elastic/security-entity-analytics
x-pack/plugins/security_solution/public/overview/pages/entity_analytics.tsx @elastic/security-entity-analytics
x-pack/plugins/security_solution/public/overview/components/entity_analytics
x-pack/plugins/security_solution/server/lib/entity_analytics @elastic/security-entity-analytics
x-pack/plugins/security_solution/server/lib/risk_score @elastic/security-entity-analytics
x-pack/test/security_solution_api_integration/test_suites/entity_analytics @elastic/security-entity-analytics
x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics @elastic/security-entity-analytics
x-pack/plugins/security_solution/public/flyout/entity_details @elastic/security-entity-analytics
x-pack/plugins/security_solution/common/api/entity_analytics @elastic/security-entity-analytics
/x-pack/plugins/security_solution/public/entity_analytics @elastic/security-entity-analytics
/x-pack/test/security_solution_cypress/cypress/e2e/entity_analytics @elastic/security-entity-analytics

# Security Defend Workflows - OSQuery Ownership
/x-pack/plugins/security_solution/common/api/detection_engine/model/rule_response_actions @elastic/security-defend-workflows
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import styled from 'styled-components';
import React from 'react';
import { EuiTitle, EuiHorizontalRule, EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui';
import type { HostRisk, UserRisk } from '../../../../entity_analytics/api/types';
import * as i18n from './translations';
import type { CtiEnrichment } from '../../../../../common/search_strategy/security_solution/cti';

Expand All @@ -16,9 +17,8 @@ import type {
TimelineEventsDetailsItem,
RiskSeverity,
} from '../../../../../common/search_strategy';
import { RiskSummary } from './risk_summary';
import { RiskSummary } from '../../../../entity_analytics/components/risk_summary';
import { EnrichmentSummary } from './enrichment_summary';
import type { HostRisk, UserRisk } from '../../../../explore/containers/risk_score';
import { RiskScoreEntity } from '../../../../../common/search_strategy';
import { useHasSecurityCapability } from '../../../../helper_hooks';
import { RiskScoreInfoTooltip } from '../../../../overview/components/common';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
*/

import { i18n } from '@kbn/i18n';
import { getRiskEntityTranslation } from '../../../../explore/components/risk_score/translations';
import { getRiskEntityTranslation } from '../../../../entity_analytics/components/risk_score/translations';
import type { RiskScoreEntity } from '../../../../../common/search_strategy';
export * from '../../../../explore/components/risk_score/translations';
export * from '../../../../entity_analytics/components/risk_score/translations';

export const FEED_NAME_PREPOSITION = i18n.translate(
'xpack.securitySolution.eventDetails.ctiSummary.feedNamePreposition',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ import { EnrichmentRangePicker } from './cti_details/enrichment_range_picker';
import { InvestigationGuideView } from './investigation_guide_view';
import { Overview } from './overview';
import { Insights } from './insights/insights';
import { useRiskScoreData } from './use_risk_score_data';
import { useRiskScoreData } from '../../../entity_analytics/api/hooks/use_risk_score_data';
import { getRowRenderer } from '../../../timelines/components/timeline/body/renderers/get_row_renderer';
import { DETAILS_CLASS_NAME } from '../../../timelines/components/timeline/body/renderers/helpers';
import { defaultRowRenderers } from '../../../timelines/components/timeline/body/renderers';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
import { useState, useEffect, useMemo } from 'react';
import { has, sortBy } from 'lodash/fp';

import { getAggregatedAnomaliesQuery } from '../../../../entity_analytics/components/entity_analytics_anomalies/query';
import { DEFAULT_ANOMALY_SCORE } from '../../../../../common/constants';
import * as i18n from './translations';
import { useUiSetting$ } from '../../../lib/kibana';
import { useAppToasts } from '../../../hooks/use_app_toasts';
import { anomaliesSearch } from '../api/anomalies_search';
import { getAggregatedAnomaliesQuery } from '../../../../overview/components/entity_analytics/anomalies/query';
import type { inputsModel } from '../../../store';
import { useSecurityJobs } from '../../ml_popover/hooks/use_security_jobs';
import type { SecurityJob } from '../../ml_popover/types';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ import {
import { createStore } from '../../store';
import type { State } from '../../store';
import { useRefetchByRestartingSession } from '../page/use_refetch_by_session';
import { getRiskScoreDonutAttributes } from './lens_attributes/common/risk_scores/risk_score_donut';
import { TOTAL_LABEL } from '../../../overview/components/entity_analytics/common/translations';
import { getRiskScoreDonutAttributes } from '../../../entity_analytics/lens_attributes/risk_score_donut';

jest.mock('./lens_embeddable');
jest.mock('../page/use_refetch_by_session', () => ({
Expand Down Expand Up @@ -183,7 +182,7 @@ describe('VisualizationEmbeddable', () => {
getLensAttributes={getRiskScoreDonutAttributes}
id="testId"
isDonut={true}
label={TOTAL_LABEL}
label={'Total'}
timerange={{ from: '2022-10-27T23:00:00.000Z', to: '2022-11-04T10:46:16.204Z' }}
/>
</TestProviders>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* 2.0.
*/

import type { RiskScoreEntity } from '../../../common/search_strategy';
import {
RISK_ENGINE_STATUS_URL,
RISK_SCORE_PREVIEW_URL,
Expand All @@ -13,6 +14,7 @@ import {
RISK_ENGINE_INIT_URL,
RISK_ENGINE_PRIVILEGES_URL,
ASSET_CRITICALITY_PRIVILEGES_URL,
RISK_SCORE_INDEX_STATUS_API_URL,
} from '../../../common/constants';

import type {
Expand Down Expand Up @@ -101,6 +103,27 @@ export const useEntityAnalyticsRoutes = () => {
method: 'GET',
});

const getRiskScoreIndexStatus = ({
query,
signal,
}: {
query: {
indexName: string;
entity: RiskScoreEntity;
};
signal?: AbortSignal;
}): Promise<{
isDeprecated: boolean;
isEnabled: boolean;
}> =>
http.fetch<{ isDeprecated: boolean; isEnabled: boolean }>(RISK_SCORE_INDEX_STATUS_API_URL, {
version: '1',
method: 'GET',
query,
asSystemRequest: true,
signal,
});

return {
fetchRiskScorePreview,
fetchRiskEngineStatus,
Expand All @@ -109,5 +132,6 @@ export const useEntityAnalyticsRoutes = () => {
disableRiskEngine,
fetchRiskEnginePrivileges,
fetchAssetCriticalityPrivileges,
getRiskScoreIndexStatus,
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,25 @@
* 2.0.
*/
import { renderHook } from '@testing-library/react-hooks';
import { useRiskScore } from '.';
import { TestProviders } from '../../../../common/mock';
import { useRiskScore } from './use_risk_score';
import { TestProviders } from '../../../common/mock';

import { useSearchStrategy } from '../../../../common/containers/use_search_strategy';
import { useAppToasts } from '../../../../common/hooks/use_app_toasts';
import { useAppToastsMock } from '../../../../common/hooks/use_app_toasts.mock';
import { useRiskScoreFeatureStatus } from '../feature_status';
import { RiskScoreEntity } from '../../../../../common/search_strategy';
import { useSearchStrategy } from '../../../common/containers/use_search_strategy';
import { useAppToasts } from '../../../common/hooks/use_app_toasts';
import { useAppToastsMock } from '../../../common/hooks/use_app_toasts.mock';
import { useRiskScoreFeatureStatus } from './use_risk_score_feature_status';
import { RiskScoreEntity } from '../../../../common/search_strategy';

jest.mock('../../../../common/containers/use_search_strategy', () => ({
jest.mock('../../../common/containers/use_search_strategy', () => ({
useSearchStrategy: jest.fn(),
}));

jest.mock('../../../../common/hooks/use_space_id', () => ({
jest.mock('../../../common/hooks/use_space_id', () => ({
useSpaceId: jest.fn().mockReturnValue('default'),
}));

jest.mock('../../../../common/hooks/use_app_toasts');
jest.mock('../feature_status');
jest.mock('../../../common/hooks/use_app_toasts');
jest.mock('./use_risk_score_feature_status');

const mockUseRiskScoreFeatureStatus = useRiskScoreFeatureStatus as jest.Mock;
const mockUseSearchStrategy = useSearchStrategy as jest.Mock;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,25 @@

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

import { useRiskScoreFeatureStatus } from '../feature_status';
import { createFilter } from '../../../../common/containers/helpers';
import type {
RiskScoreSortField,
StrategyResponseType,
} from '../../../../../common/search_strategy';
import { i18n } from '@kbn/i18n';
import { useRiskScoreFeatureStatus } from './use_risk_score_feature_status';
import { createFilter } from '../../../common/containers/helpers';
import type { RiskScoreSortField, StrategyResponseType } from '../../../../common/search_strategy';
import {
RiskQueries,
getUserRiskIndex,
RiskScoreEntity,
getHostRiskIndex,
} from '../../../../../common/search_strategy';
import type { ESQuery } from '../../../../../common/typed_json';

import * as i18n from './translations';
import type { InspectResponse } from '../../../../types';
import { useAppToasts } from '../../../../common/hooks/use_app_toasts';
import { isIndexNotFoundError } from '../../../../common/utils/exceptions';
import type { inputsModel } from '../../../../common/store';
import { useSpaceId } from '../../../../common/hooks/use_space_id';
import { useSearchStrategy } from '../../../../common/containers/use_search_strategy';
import { useIsNewRiskScoreModuleInstalled } from '../../../../entity_analytics/api/hooks/use_risk_engine_status';
} from '../../../../common/search_strategy';
import type { ESQuery } from '../../../../common/typed_json';

import type { InspectResponse } from '../../../types';
import { useAppToasts } from '../../../common/hooks/use_app_toasts';
import { isIndexNotFoundError } from '../../../common/utils/exceptions';
import type { inputsModel } from '../../../common/store';
import { useSpaceId } from '../../../common/hooks/use_space_id';
import { useSearchStrategy } from '../../../common/containers/use_search_strategy';
import { useIsNewRiskScoreModuleInstalled } from './use_risk_engine_status';

export interface RiskScoreState<T extends RiskScoreEntity.host | RiskScoreEntity.user> {
data:
Expand Down Expand Up @@ -181,7 +178,11 @@ export const useRiskScore = <T extends RiskScoreEntity.host | RiskScoreEntity.us
useEffect(() => {
if (error) {
if (!isIndexNotFoundError(error)) {
addError(error, { title: i18n.FAIL_RISK_SCORE });
addError(error, {
title: i18n.translate('xpack.securitySolution.riskScore.failSearchDescription', {
defaultMessage: `Failed to run search on risk score`,
}),
});
}
}
}, [addError, error]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
*/

import { renderHook } from '@testing-library/react-hooks';
import { TestProviders } from '../../mock';
import { TestProviders } from '../../../common/mock';
import { ONLY_FIRST_ITEM_PAGINATION, useRiskScoreData } from './use_risk_score_data';
import { useRiskScore } from '../../../explore/containers/risk_score';
import { useBasicDataFromDetailsData } from '../../../timelines/components/side_panel/event_details/helpers';
import { RiskScoreEntity } from '../../../../common/search_strategy';
import { useRiskScore } from './use_risk_score';

jest.mock('../../../explore/containers/risk_score');
jest.mock('./use_risk_score');
jest.mock('../../../timelines/components/side_panel/event_details/helpers');
const mockUseRiskScore = useRiskScore as jest.Mock;
const mockUseBasicDataFromDetailsData = useBasicDataFromDetailsData as jest.Mock;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import {
buildUserNamesFilter,
RiskScoreEntity,
} from '../../../../common/search_strategy';
import type { HostRisk, UserRisk } from '../../../explore/containers/risk_score';
import { useRiskScore } from '../../../explore/containers/risk_score';
import { useRiskScore } from './use_risk_score';
import type { HostRisk, UserRisk } from '../types';

export const ONLY_FIRST_ITEM_PAGINATION = {
cursorStart: 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@
* 2.0.
*/
import { act, renderHook } from '@testing-library/react-hooks';
import { TestProviders } from '../../../../common/mock';
import { TestProviders } from '../../../common/mock';

import { useRiskScoreFeatureStatus } from '.';
import { RiskScoreEntity } from '../../../../../common/search_strategy';
import { useFetch } from '../../../../common/hooks/use_fetch';
import { useMlCapabilities } from '../../../../common/components/ml/hooks/use_ml_capabilities';
import { useHasSecurityCapability } from '../../../../helper_hooks';
import { useRiskScoreFeatureStatus } from './use_risk_score_feature_status';
import { RiskScoreEntity } from '../../../../common/search_strategy';
import { useFetch } from '../../../common/hooks/use_fetch';
import { useMlCapabilities } from '../../../common/components/ml/hooks/use_ml_capabilities';
import { useHasSecurityCapability } from '../../../helper_hooks';

jest.mock('../../../../common/hooks/use_fetch');
jest.mock('../../../../common/components/ml/hooks/use_ml_capabilities');
jest.mock('../../../../helper_hooks');
jest.mock('../../../common/hooks/use_fetch');
jest.mock('../../../common/components/ml/hooks/use_ml_capabilities');
jest.mock('../../../helper_hooks');

const mockFetch = jest.fn();
const mockUseMlCapabilities = useMlCapabilities as jest.Mock;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
*/

import { useCallback, useEffect, useMemo } from 'react';
import { useMlCapabilities } from '../../../../common/components/ml/hooks/use_ml_capabilities';
import { REQUEST_NAMES, useFetch } from '../../../../common/hooks/use_fetch';
import type { RiskScoreEntity } from '../../../../../common/search_strategy';
import { getRiskScoreIndexStatus } from './api';
import { useHasSecurityCapability } from '../../../../helper_hooks';
import { useMlCapabilities } from '../../../common/components/ml/hooks/use_ml_capabilities';
import { REQUEST_NAMES, useFetch } from '../../../common/hooks/use_fetch';
import type { RiskScoreEntity } from '../../../../common/search_strategy';
import { useHasSecurityCapability } from '../../../helper_hooks';
import { useEntityAnalyticsRoutes } from '../api';

interface RiskScoresFeatureStatus {
error: unknown;
Expand All @@ -31,6 +31,7 @@ export const useRiskScoreFeatureStatus = (
const { isPlatinumOrTrialLicense, capabilitiesFetched } = useMlCapabilities();
const hasEntityAnalyticsCapability = useHasSecurityCapability('entity-analytics');
const isAuthorized = isPlatinumOrTrialLicense && hasEntityAnalyticsCapability;
const { getRiskScoreIndexStatus } = useEntityAnalyticsRoutes();

const { fetch, data, isLoading, error } = useFetch(
REQUEST_NAMES.GET_RISK_SCORE_DEPRECATED,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,25 @@

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

import { i18n } from '@kbn/i18n';
import {
getHostRiskIndex,
getUserRiskIndex,
RiskQueries,
RiskSeverity,
RiskScoreEntity,
EMPTY_SEVERITY_COUNT,
} from '../../../../../common/search_strategy';
import * as i18n from './translations';
import { isIndexNotFoundError } from '../../../../common/utils/exceptions';
import type { ESQuery } from '../../../../../common/typed_json';
import type { SeverityCount } from '../../../components/risk_score/severity/types';
import { useSpaceId } from '../../../../common/hooks/use_space_id';
import { useSearchStrategy } from '../../../../common/containers/use_search_strategy';
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';
} from '../../../../common/search_strategy';
import { isIndexNotFoundError } from '../../../common/utils/exceptions';
import type { ESQuery } from '../../../../common/typed_json';
import type { SeverityCount } from '../../components/severity/types';
import { useSpaceId } from '../../../common/hooks/use_space_id';
import { useSearchStrategy } from '../../../common/containers/use_search_strategy';
import type { InspectResponse } from '../../../types';
import type { inputsModel } from '../../../common/store';
import { useAppToasts } from '../../../common/hooks/use_app_toasts';
import { useIsNewRiskScoreModuleInstalled } from './use_risk_engine_status';
import { useRiskScoreFeatureStatus } from './use_risk_score_feature_status';

interface RiskScoreKpi {
error: unknown;
Expand Down Expand Up @@ -123,7 +123,11 @@ export const useRiskScoreKpi = ({
useEffect(() => {
if (error) {
if (!isIndexNotFoundError(error)) {
addError(error, { title: i18n.FAIL_RISK_SCORE });
addError(error, {
title: i18n.translate('xpack.securitySolution.riskScore.kpi.failSearchDescription', {
defaultMessage: `Failed to run search on risk score`,
}),
});
}
}
}, [addError, error]);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* 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 type { HostRiskScore, UserRiskScore } from '../../../common/search_strategy';

export interface HostRisk {
loading: boolean;
isModuleEnabled: boolean;
result?: HostRiskScore[];
}

export interface UserRisk {
loading: boolean;
isModuleEnabled: boolean;
result?: UserRiskScore[];
}
Loading
Loading