Skip to content

Commit

Permalink
[Security Solution] Co-locate Frontend Entity Analytics Code (#173499)
Browse files Browse the repository at this point in the history
## Summary

Move all files owned by the Entity Analytics team to
`x-pack/plugins/security_solution/public/entity_analytics`

Initially, files inside `public/entity_analytics/components` look
disorganised because many of them have similar names and do not follow
the same conventions.

I minimized the PR scope to avoid putting too much of a burden on
reviewers.
### Changes
* Moves files to the `entity_analytics` folder
* Updates imports
* Moves the content of some files to a new file inside the
`entity_analytics` folder
* Inlines copies that were previously inside `translation.ts`. 
* No changes to the user experience are expected. 

### Checklist

- [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

---------

Co-authored-by: kibanamachine <[email protected]>
  • Loading branch information
machadoum and kibanamachine authored Dec 21, 2023
1 parent 87d5d6b commit 306debf
Show file tree
Hide file tree
Showing 186 changed files with 731 additions and 790 deletions.
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

0 comments on commit 306debf

Please sign in to comment.