diff --git a/x-pack/solutions/security/plugins/security_solution/common/constants.ts b/x-pack/solutions/security/plugins/security_solution/common/constants.ts
index eda49eae164d0..c4bb9290ddb64 100644
--- a/x-pack/solutions/security/plugins/security_solution/common/constants.ts
+++ b/x-pack/solutions/security/plugins/security_solution/common/constants.ts
@@ -101,7 +101,6 @@ export const RULES_LANDING_PATH = `${RULES_PATH}/landing` as const;
export const RULES_ADD_PATH = `${RULES_PATH}/add_rules` as const;
export const RULES_UPDATES = `${RULES_PATH}/updates` as const;
export const RULES_CREATE_PATH = `${RULES_PATH}/create` as const;
-export const RULES_MANAGEMENT_PATH = `${RULES_PATH}/management` as const;
export const EXCEPTIONS_PATH = '/exceptions' as const;
export const EXCEPTION_LIST_DETAIL_PATH = `${EXCEPTIONS_PATH}/details/:detailName` as const;
export const HOSTS_PATH = '/hosts' as const;
diff --git a/x-pack/solutions/security/plugins/security_solution/public/asset_inventory/links.ts b/x-pack/solutions/security/plugins/security_solution/public/asset_inventory/links.ts
index 27970e81abe64..5b9c3afed1124 100644
--- a/x-pack/solutions/security/plugins/security_solution/public/asset_inventory/links.ts
+++ b/x-pack/solutions/security/plugins/security_solution/public/asset_inventory/links.ts
@@ -17,7 +17,7 @@ import {
import type { LinkItem } from '../common/links/types';
export const links: LinkItem = {
- capabilities: [`${SECURITY_FEATURE_ID}.show`],
+ capabilities: [[`${SECURITY_FEATURE_ID}.show`, `${SECURITY_FEATURE_ID}.detections`]],
globalNavPosition: 11,
globalSearchKeywords: [
i18n.translate('xpack.securitySolution.appLinks.inventory', {
diff --git a/x-pack/solutions/security/plugins/security_solution/public/asset_inventory/routes.tsx b/x-pack/solutions/security/plugins/security_solution/public/asset_inventory/routes.tsx
index a3775a516ab81..02ed4e6631da8 100644
--- a/x-pack/solutions/security/plugins/security_solution/public/asset_inventory/routes.tsx
+++ b/x-pack/solutions/security/plugins/security_solution/public/asset_inventory/routes.tsx
@@ -12,7 +12,7 @@ import { SecurityPageName } from '../app/types';
import { ASSET_INVENTORY_PATH } from '../../common/constants';
import { SecuritySolutionPageWrapper } from '../common/components/page_wrapper';
import { PluginTemplateWrapper } from '../common/components/plugin_template_wrapper';
-import { SecurityRoutePageWrapper } from '../common/components/security_route_page_wrapper';
+import { withSecurityRoutePageWrapper } from '../common/components/security_route_page_wrapper';
import { AssetInventoryLoading } from './components/asset_inventory_loading';
const AssetsPageLazy = lazy(() => import('./pages'));
@@ -32,13 +32,11 @@ export const AssetInventoryRoutes = () => {
return (
-
-
- }>
-
-
-
-
+
+ }>
+
+
+
);
@@ -47,6 +45,8 @@ export const AssetInventoryRoutes = () => {
export const routes: SecuritySubPluginRoutes = [
{
path: ASSET_INVENTORY_PATH,
- component: AssetInventoryRoutes,
+ component: withSecurityRoutePageWrapper(AssetInventoryRoutes, SecurityPageName.assetInventory, {
+ redirectOnMissing: true,
+ }),
},
];
diff --git a/x-pack/solutions/security/plugins/security_solution/public/cloud_security_posture/routes.tsx b/x-pack/solutions/security/plugins/security_solution/public/cloud_security_posture/routes.tsx
index ffa266d938087..ed4c712e18801 100644
--- a/x-pack/solutions/security/plugins/security_solution/public/cloud_security_posture/routes.tsx
+++ b/x-pack/solutions/security/plugins/security_solution/public/cloud_security_posture/routes.tsx
@@ -9,15 +9,15 @@ import React from 'react';
import { CLOUD_SECURITY_POSTURE_BASE_PATH } from '@kbn/cloud-security-posture-common';
import type { CloudSecurityPosturePageId } from '@kbn/cloud-security-posture-plugin/public';
import { type CspSecuritySolutionContext } from '@kbn/cloud-security-posture-plugin/public';
-import { TrackApplicationView } from '@kbn/usage-collection-plugin/public';
import { useExpandableFlyoutApi } from '@kbn/expandable-flyout';
-import type { SecurityPageName, SecuritySubPluginRoutes } from '../app/types';
+import { SecurityPageName } from '../app/types';
+import type { SecuritySubPluginRoutes } from '../app/types';
import { useKibana } from '../common/lib/kibana';
-import { SecuritySolutionPageWrapper } from '../common/components/page_wrapper';
import { SpyRoute } from '../common/utils/route/spy_routes';
import { FiltersGlobal } from '../common/components/filters_global';
import { PluginTemplateWrapper } from '../common/components/plugin_template_wrapper';
import { useOnExpandableFlyoutClose } from '../flyout/shared/hooks/use_on_expandable_flyout_close';
+import { withSecurityRoutePageWrapper } from '../common/components/security_route_page_wrapper';
// This exists only for the type signature cast
const CloudPostureSpyRoute = ({ pageName, ...rest }: { pageName?: CloudSecurityPosturePageId }) => (
@@ -37,11 +37,7 @@ const CloudSecurityPosture = () => {
return (
-
-
-
-
-
+
);
};
@@ -51,6 +47,13 @@ CloudSecurityPosture.displayName = 'CloudSecurityPosture';
export const routes: SecuritySubPluginRoutes = [
{
path: CLOUD_SECURITY_POSTURE_BASE_PATH,
- component: CloudSecurityPosture,
+ component: withSecurityRoutePageWrapper(
+ CloudSecurityPosture,
+ SecurityPageName.cloudSecurityPostureDashboard,
+ {
+ redirectOnMissing: true,
+ omitSpyRoute: true,
+ }
+ ),
},
];
diff --git a/x-pack/solutions/security/plugins/security_solution/public/dashboards/links.ts b/x-pack/solutions/security/plugins/security_solution/public/dashboards/links.ts
index 7feecbd1742c9..7ffb6463f42e5 100644
--- a/x-pack/solutions/security/plugins/security_solution/public/dashboards/links.ts
+++ b/x-pack/solutions/security/plugins/security_solution/public/dashboards/links.ts
@@ -31,7 +31,7 @@ export const dashboardsLinks: LinkItem = {
title: DASHBOARDS,
path: DASHBOARDS_PATH,
globalNavPosition: 1,
- capabilities: [`${SECURITY_FEATURE_ID}.show`],
+ capabilities: [[`${SECURITY_FEATURE_ID}.show`, `${SECURITY_FEATURE_ID}.detections`]],
globalSearchKeywords: [
i18n.translate('xpack.securitySolution.appLinks.dashboards', {
defaultMessage: 'Dashboards',
diff --git a/x-pack/solutions/security/plugins/security_solution/public/dashboards/routes.tsx b/x-pack/solutions/security/plugins/security_solution/public/dashboards/routes.tsx
index b9e854dfdbbdf..96de49d4a693b 100644
--- a/x-pack/solutions/security/plugins/security_solution/public/dashboards/routes.tsx
+++ b/x-pack/solutions/security/plugins/security_solution/public/dashboards/routes.tsx
@@ -5,24 +5,24 @@
* 2.0.
*/
import React from 'react';
-import { TrackApplicationView } from '@kbn/usage-collection-plugin/public';
import { DASHBOARDS_PATH, SecurityPageName } from '../../common/constants';
import type { SecuritySubPluginRoutes } from '../app/types';
import { PluginTemplateWrapper } from '../common/components/plugin_template_wrapper';
import { DashboardsContainer } from './pages';
+import { withSecurityRoutePageWrapper } from '../common/components/security_route_page_wrapper';
export const DashboardRoutes = () => (
-
-
-
+
);
export const routes: SecuritySubPluginRoutes = [
{
path: DASHBOARDS_PATH,
- component: DashboardRoutes,
+ component: withSecurityRoutePageWrapper(DashboardRoutes, SecurityPageName.dashboards, {
+ redirectOnMissing: true,
+ }),
},
];
diff --git a/x-pack/solutions/security/plugins/security_solution/public/exceptions/routes.tsx b/x-pack/solutions/security/plugins/security_solution/public/exceptions/routes.tsx
index e6faf794dcdbf..2fdcfb578821b 100644
--- a/x-pack/solutions/security/plugins/security_solution/public/exceptions/routes.tsx
+++ b/x-pack/solutions/security/plugins/security_solution/public/exceptions/routes.tsx
@@ -20,7 +20,10 @@ import { SpyRoute } from '../common/utils/route/spy_routes';
import { NotFoundPage } from '../app/404';
import { useReadonlyHeader } from '../use_readonly_header';
import { PluginTemplateWrapper } from '../common/components/plugin_template_wrapper';
-import { SecurityRoutePageWrapper } from '../common/components/security_route_page_wrapper';
+import {
+ SecurityRoutePageWrapper,
+ withSecurityRoutePageWrapper,
+} from '../common/components/security_route_page_wrapper';
const ExceptionsRoutes = () => (
@@ -53,11 +56,11 @@ const ExceptionsContainerComponent: React.FC = () => {
const Exceptions = React.memo(ExceptionsContainerComponent);
-const renderExceptionsRoutes = () => ;
-
export const routes = [
{
path: EXCEPTIONS_PATH,
- render: renderExceptionsRoutes,
+ component: withSecurityRoutePageWrapper(Exceptions, SecurityPageName.exceptions, {
+ redirectOnMissing: true,
+ }),
},
];
diff --git a/x-pack/solutions/security/plugins/security_solution/public/explore/links.ts b/x-pack/solutions/security/plugins/security_solution/public/explore/links.ts
index 18f176494fffe..920b9a4ba2614 100644
--- a/x-pack/solutions/security/plugins/security_solution/public/explore/links.ts
+++ b/x-pack/solutions/security/plugins/security_solution/public/explore/links.ts
@@ -209,7 +209,7 @@ export const exploreLinks: LinkItem = {
title: EXPLORE,
path: EXPLORE_PATH,
globalNavPosition: 9,
- capabilities: [`${SECURITY_FEATURE_ID}.show`],
+ capabilities: [[`${SECURITY_FEATURE_ID}.show`, `${SECURITY_FEATURE_ID}.detections`]],
globalSearchKeywords: [
i18n.translate('xpack.securitySolution.appLinks.explore', {
defaultMessage: 'Explore',
diff --git a/x-pack/solutions/security/plugins/security_solution/public/explore/routes.tsx b/x-pack/solutions/security/plugins/security_solution/public/explore/routes.tsx
index 3da94b7dc82f9..fedb7b91c83e6 100644
--- a/x-pack/solutions/security/plugins/security_solution/public/explore/routes.tsx
+++ b/x-pack/solutions/security/plugins/security_solution/public/explore/routes.tsx
@@ -6,7 +6,6 @@
*/
import React from 'react';
-import { TrackApplicationView } from '@kbn/usage-collection-plugin/public';
import { UsersContainer } from './users/pages';
import { HostsContainer } from './hosts/pages';
import { NetworkContainer } from './network/pages';
@@ -16,37 +15,29 @@ import { SecurityPageName } from '../app/types';
import { EXPLORE_PATH, HOSTS_PATH, NETWORK_PATH, USERS_PATH } from '../../common/constants';
import { PluginTemplateWrapper } from '../common/components/plugin_template_wrapper';
import { ExploreLandingPage } from './landing';
-import { SecurityRoutePageWrapper } from '../common/components/security_route_page_wrapper';
+import { withSecurityRoutePageWrapper } from '../common/components/security_route_page_wrapper';
const ExploreLanding = () => (
-
-
-
+
);
const NetworkRoutes = () => (
-
-
-
+
);
const UsersRoutes = () => (
-
-
-
+
);
const HostsRoutes = () => (
-
-
-
+
);
@@ -54,18 +45,30 @@ export const routes: SecuritySubPluginRoutes = [
{
path: EXPLORE_PATH,
exact: true,
- component: ExploreLanding,
+ component: withSecurityRoutePageWrapper(ExploreLanding, SecurityPageName.exploreLanding, {
+ redirectOnMissing: true,
+ omitSpyRoute: true,
+ }),
},
{
path: NETWORK_PATH,
- component: NetworkRoutes,
+ component: withSecurityRoutePageWrapper(NetworkRoutes, SecurityPageName.network, {
+ redirectOnMissing: true,
+ omitSpyRoute: true,
+ }),
},
{
path: USERS_PATH,
- component: UsersRoutes,
+ component: withSecurityRoutePageWrapper(UsersRoutes, SecurityPageName.users, {
+ redirectOnMissing: true,
+ omitSpyRoute: true,
+ }),
},
{
path: HOSTS_PATH,
- component: HostsRoutes,
+ component: withSecurityRoutePageWrapper(HostsRoutes, SecurityPageName.hosts, {
+ redirectOnMissing: true,
+ omitSpyRoute: true,
+ }),
},
];
diff --git a/x-pack/solutions/security/plugins/security_solution/public/management/pages/index.tsx b/x-pack/solutions/security/plugins/security_solution/public/management/pages/index.tsx
index d558b1271dc6b..613447bd44431 100644
--- a/x-pack/solutions/security/plugins/security_solution/public/management/pages/index.tsx
+++ b/x-pack/solutions/security/plugins/security_solution/public/management/pages/index.tsx
@@ -37,6 +37,7 @@ import { HostIsolationExceptionsContainer } from './host_isolation_exceptions';
import { BlocklistContainer } from './blocklist';
import { ResponseActionsContainer } from './response_actions';
import { PrivilegedRoute } from '../components/privileged_route';
+import { SecurityRoutePageWrapper } from '../../common/components/security_route_page_wrapper';
const EndpointTelemetry = () => (
@@ -80,11 +81,10 @@ const ResponseActionsTelemetry = () => (
);
-const NotesTelemetry = () => (
-
+const Notes = () => (
+
-
-
+
);
export const ManagementContainer = memo(() => {
@@ -163,7 +163,7 @@ export const ManagementContainer = memo(() => {
/>
{!securitySolutionNotesDisabled && (
-
+
)}
{canReadEndpointList && (
diff --git a/x-pack/solutions/security/plugins/security_solution/public/notes/routes.tsx b/x-pack/solutions/security/plugins/security_solution/public/notes/routes.tsx
index c49f54f9c9a93..43c6be374c94e 100644
--- a/x-pack/solutions/security/plugins/security_solution/public/notes/routes.tsx
+++ b/x-pack/solutions/security/plugins/security_solution/public/notes/routes.tsx
@@ -7,26 +7,22 @@
import React from 'react';
import { Route, Routes } from '@kbn/shared-ux-router';
-import { TrackApplicationView } from '@kbn/usage-collection-plugin/public';
import { NoteManagementPage } from './pages/note_management_page';
-import { SpyRoute } from '../common/utils/route/spy_routes';
import { NotFoundPage } from '../app/404';
import { NOTES_PATH, SecurityPageName } from '../../common/constants';
import { PluginTemplateWrapper } from '../common/components/plugin_template_wrapper';
+import { withSecurityRoutePageWrapper } from '../common/components/security_route_page_wrapper';
-const NotesManagementTelemetry = () => (
+const NotesManagementWrapper = () => (
-
-
-
-
+
);
const NotesManagementContainer: React.FC = React.memo(() => {
return (
-
+
);
@@ -36,6 +32,8 @@ NotesManagementContainer.displayName = 'NotesManagementContainer';
export const routes = [
{
path: NOTES_PATH,
- component: NotesManagementContainer,
+ component: withSecurityRoutePageWrapper(NotesManagementContainer, SecurityPageName.notes, {
+ redirectOnMissing: true,
+ }),
},
];
diff --git a/x-pack/solutions/security/plugins/security_solution/public/overview/routes.tsx b/x-pack/solutions/security/plugins/security_solution/public/overview/routes.tsx
index 3b1e9ca0e8046..5964adca240e6 100644
--- a/x-pack/solutions/security/plugins/security_solution/public/overview/routes.tsx
+++ b/x-pack/solutions/security/plugins/security_solution/public/overview/routes.tsx
@@ -6,7 +6,6 @@
*/
import React from 'react';
-import { TrackApplicationView } from '@kbn/usage-collection-plugin/public';
import {
OVERVIEW_PATH,
DATA_QUALITY_PATH,
@@ -21,55 +20,63 @@ import { DataQuality } from './pages/data_quality';
import { DetectionResponse } from './pages/detection_response';
import { PluginTemplateWrapper } from '../common/components/plugin_template_wrapper';
import { EntityAnalyticsPage } from '../entity_analytics/pages/entity_analytics_dashboard';
-import { SecurityRoutePageWrapper } from '../common/components/security_route_page_wrapper';
+import { withSecurityRoutePageWrapper } from '../common/components/security_route_page_wrapper';
const OverviewRoutes = () => (
-
-
-
+
);
const DetectionResponseRoutes = () => (
-
-
-
+
);
const EntityAnalyticsRoutes = () => (
-
-
-
+
);
const DataQualityRoutes = () => (
-
-
-
+
);
export const routes: SecuritySubPluginRoutes = [
{
path: OVERVIEW_PATH,
- component: OverviewRoutes,
+ component: withSecurityRoutePageWrapper(OverviewRoutes, SecurityPageName.overview, {
+ redirectOnMissing: true,
+ }),
},
{
path: DETECTION_RESPONSE_PATH,
- component: DetectionResponseRoutes,
+ component: withSecurityRoutePageWrapper(
+ DetectionResponseRoutes,
+ SecurityPageName.detectionAndResponse,
+ {
+ redirectOnMissing: true,
+ }
+ ),
},
{
path: ENTITY_ANALYTICS_PATH,
- render: EntityAnalyticsRoutes,
+ component: withSecurityRoutePageWrapper(
+ EntityAnalyticsRoutes,
+ SecurityPageName.entityAnalytics,
+ {
+ redirectOnMissing: true,
+ }
+ ),
},
{
path: DATA_QUALITY_PATH,
- component: DataQualityRoutes,
+ component: withSecurityRoutePageWrapper(DataQualityRoutes, SecurityPageName.dataQuality, {
+ redirectOnMissing: true,
+ }),
},
];
diff --git a/x-pack/solutions/security/plugins/security_solution/public/rules/links.ts b/x-pack/solutions/security/plugins/security_solution/public/rules/links.ts
index 43b9842aca6cb..9b687e89da655 100644
--- a/x-pack/solutions/security/plugins/security_solution/public/rules/links.ts
+++ b/x-pack/solutions/security/plugins/security_solution/public/rules/links.ts
@@ -12,7 +12,6 @@ import {
RULES_ADD_PATH,
RULES_CREATE_PATH,
RULES_LANDING_PATH,
- RULES_MANAGEMENT_PATH,
RULES_PATH,
SECURITY_FEATURE_ID,
} from '../../common/constants';
@@ -56,15 +55,6 @@ export const links: LinkItem = {
],
capabilities: `${SECURITY_FEATURE_ID}.show`,
links: [
- {
- id: SecurityPageName.rulesManagement,
- title: SIEM_RULES,
- path: RULES_MANAGEMENT_PATH,
- globalSearchDisabled: true,
- skipUrlState: true,
- hideTimeline: true,
- capabilities: `${SECURITY_FEATURE_ID}.detections`,
- },
{
id: SecurityPageName.rulesAdd,
title: ADD_RULES,
diff --git a/x-pack/solutions/security/plugins/security_solution/public/rules/routes.tsx b/x-pack/solutions/security/plugins/security_solution/public/rules/routes.tsx
index 557d4d58e31ed..6aa039b2a16a4 100644
--- a/x-pack/solutions/security/plugins/security_solution/public/rules/routes.tsx
+++ b/x-pack/solutions/security/plugins/security_solution/public/rules/routes.tsx
@@ -43,6 +43,11 @@ const getRulesSubRoutes = (capabilities: Capabilities) => [
main: EditRulePage,
exact: true,
},
+ {
+ path: `/rules/:tabName(${AllRulesTabs.management}|${AllRulesTabs.monitoring}|${AllRulesTabs.updates})`,
+ main: RulesPage,
+ exact: true,
+ },
]
: []),
...(hasCapabilities(capabilities, [
@@ -65,14 +70,6 @@ const getRulesSubRoutes = (capabilities: Capabilities) => [
}),
exact: true,
},
- {
- path: `/rules/:tabName(${AllRulesTabs.management}|${AllRulesTabs.monitoring}|${AllRulesTabs.updates})`,
- main: withSecurityRoutePageWrapper(RulesPage, SecurityPageName.rulesManagement, {
- redirectOnMissing: true,
- omitSpyRoute: true,
- }),
- exact: true,
- },
{
path: '/rules/add_rules',
main: withSecurityRoutePageWrapper(AddRulesPage, SecurityPageName.rulesAdd, {
diff --git a/x-pack/solutions/security/plugins/security_solution/public/timelines/routes.tsx b/x-pack/solutions/security/plugins/security_solution/public/timelines/routes.tsx
index e7f28eb9d71e3..e321507799df1 100644
--- a/x-pack/solutions/security/plugins/security_solution/public/timelines/routes.tsx
+++ b/x-pack/solutions/security/plugins/security_solution/public/timelines/routes.tsx
@@ -6,8 +6,8 @@
*/
import React from 'react';
-import { TrackApplicationView } from '@kbn/usage-collection-plugin/public';
+import { withSecurityRoutePageWrapper } from '../common/components/security_route_page_wrapper';
import { PluginTemplateWrapper } from '../common/components/plugin_template_wrapper';
import { SecurityPageName } from '../app/types';
import type { SecuritySubPluginRoutes } from '../app/types';
@@ -16,15 +16,15 @@ import { Timelines } from './pages';
const TimelinesRoutes = () => (
-
-
-
+
);
export const routes: SecuritySubPluginRoutes = [
{
path: TIMELINES_PATH,
- component: TimelinesRoutes,
+ component: withSecurityRoutePageWrapper(TimelinesRoutes, SecurityPageName.timelines, {
+ redirectOnMissing: true,
+ }),
},
];
diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/ai4dsoc/navigation/navigation.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/ai4dsoc/navigation/navigation.cy.ts
index ee0795aa2a003..c86b0da2fc061 100644
--- a/x-pack/test/security_solution_cypress/cypress/e2e/ai4dsoc/navigation/navigation.cy.ts
+++ b/x-pack/test/security_solution_cypress/cypress/e2e/ai4dsoc/navigation/navigation.cy.ts
@@ -7,18 +7,125 @@
import { login } from '../../../tasks/login';
import { visit } from '../../../tasks/navigation';
-import { GET_STARTED_URL } from '../../../urls/navigation';
+import {
+ ASSETS_URL,
+ ALERTS_URL,
+ ASSET_INVENTORY_URL,
+ BLOCKLIST_URL,
+ CREATE_RULE_URL,
+ CSP_DASHBOARD_URL,
+ CSP_BENCHMARKS_URL,
+ CSP_FINDINGS_URL,
+ CSP_VULNERABILITIES_URL,
+ DASHBOARDS_URL,
+ ENDPOINTS_URL,
+ ENTITY_ANALYTICS_MANAGEMENT_URL,
+ ENTITY_ANALYTICS_ENTITY_STORE_URL,
+ EVENT_FILTERS_URL,
+ EXCEPTIONS_URL,
+ EXPLORE_URL,
+ GET_STARTED_URL,
+ HOST_ISOLATION_EXCEPTIONS_URL,
+ INVESTIGATIONS_URL,
+ HOSTS_URL,
+ MACHINE_LEARNING_EXPLORER,
+ MACHINE_LEARNING_TIME_SERIES_EXPLORER,
+ MACHINE_LEARNING_DATA_FRAME_ANALYTICS_EXPLORATION,
+ MACHINE_LEARNING_DATA_FRAME_ANALYTICS_MAP,
+ NETWORK_URL,
+ NOTES_URL,
+ OVERVIEW_URL,
+ POLICIES_URL,
+ RESPONSE_ACTIONS_HISTORY,
+ THREAT_INTELLIGENCE_URL,
+ TIMELINES_URL,
+ TRUSTED_APPS_URL,
+ USERS_URL,
+} from '../../../urls/navigation';
import { AI_SOC_NAVIGATION } from '../../../screens/ai_soc';
-const visibleLinks = ['discover', 'attack_discovery', 'case', 'alert_summary', 'configurations'];
+const visibleLinks = ['alert_summary', 'attack_discovery', 'cases', 'configurations', 'discover'];
+const notVisibleLinks = [
+ 'securityGroup:rules',
+ 'alerts',
+ 'cloud_security_posture-findings',
+ 'threat_intelligence',
+ 'securityGroup:explore',
+ 'securityGroup:assets',
+ 'securityGroup:machine_learning',
+ 'alerts',
+ 'rules',
+];
-const notVisibleLinks = ['machine_learning-landing', 'alerts', 'rules'];
+const redirectedLinks = [
+ ALERTS_URL,
+ ASSETS_URL,
+ ASSET_INVENTORY_URL,
+ CREATE_RULE_URL,
+ CSP_DASHBOARD_URL,
+ CSP_FINDINGS_URL,
+ CSP_VULNERABILITIES_URL,
+ CSP_BENCHMARKS_URL,
+ DASHBOARDS_URL,
+ ENTITY_ANALYTICS_MANAGEMENT_URL,
+ ENTITY_ANALYTICS_ENTITY_STORE_URL,
+ EXPLORE_URL,
+ HOSTS_URL,
+ INVESTIGATIONS_URL,
+ NETWORK_URL,
+ NOTES_URL,
+ OVERVIEW_URL,
+ TIMELINES_URL,
+ USERS_URL,
+];
+const upSellLinks = [EXCEPTIONS_URL, THREAT_INTELLIGENCE_URL];
+const privilegeRequiredLinks = [
+ ENDPOINTS_URL,
+ POLICIES_URL,
+ TRUSTED_APPS_URL,
+ EVENT_FILTERS_URL,
+ BLOCKLIST_URL,
+ HOST_ISOLATION_EXCEPTIONS_URL,
+ RESPONSE_ACTIONS_HISTORY,
+];
+const mlLinks = [
+ MACHINE_LEARNING_EXPLORER,
+ MACHINE_LEARNING_TIME_SERIES_EXPLORER,
+ MACHINE_LEARNING_DATA_FRAME_ANALYTICS_EXPLORATION,
+ MACHINE_LEARNING_DATA_FRAME_ANALYTICS_MAP,
+];
-describe('AI$DSOC Navigation', { tags: '@serverless' }, () => {
+const linkedPagesAssertions: Record void> = {
+ alert_summary: () => {
+ cy.getByTestSubjContains('alert-summary-landing-page-prompt').should('exist');
+ },
+ attack_discovery: () => {
+ cy.getByTestSubjContains('attackDiscoveryPageTitle').should('contain', 'Attack discovery');
+ },
+ cases: () => {
+ cy.getByTestSubjContains('header-page-title').should('contain', 'Cases');
+ },
+ configurations: () => {
+ cy.url().should('include', `/configurations/integrations`);
+ cy.get('.euiTab').then((tabs) => {
+ const tabNames = Array.from(tabs).map((tab) => tab.innerText);
+ expect(tabNames).to.deep.equal(['Integrations', 'Rules', 'AI settings']);
+ });
+ },
+ discover: () => {
+ cy.getByTestSubjContains('discoverSavedSearchTitle').should(
+ 'contain',
+ 'Discover - Search not yet saved'
+ );
+ },
+};
+
+describe('AI4dSoC Navigation', { tags: '@serverless' }, () => {
beforeEach(() => {
login('admin');
visit(GET_STARTED_URL);
});
+
describe('renders links correctly', () => {
it('should contain the specified links', () => {
cy.get(AI_SOC_NAVIGATION)
@@ -34,4 +141,55 @@ describe('AI$DSOC Navigation', { tags: '@serverless' }, () => {
});
});
});
+
+ describe('renders pages within links correctly', () => {
+ it('should show the correct page for visible links when navigating', () => {
+ cy.get(AI_SOC_NAVIGATION).should('exist');
+
+ visibleLinks.forEach((link) => {
+ cy.getByTestSubjContains(`nav-item-id-${link}`).click();
+ cy.url().should('include', `/${link}`);
+ cy.getByTestSubjContains(`nav-item-id-${link}`).click();
+
+ // Assert that the page contains the expected content
+ linkedPagesAssertions[link]();
+ });
+ });
+ });
+
+ describe('Redirected pages', () => {
+ it('should redirect to the "get started page"', () => {
+ redirectedLinks.forEach((link) => {
+ cy.visit(link);
+ cy.url().should('include', GET_STARTED_URL);
+ });
+ });
+ });
+
+ // TODO: Undecided if these pages should be redirected as well.
+ describe('Non-redirected pages ', () => {
+ it('shows `up-sell callout` for a set of pages', () => {
+ upSellLinks.forEach((link) => {
+ cy.visit(link);
+ cy.url().should('include', link);
+ cy.get('.euiTitle').should('contain', 'Do more with Security');
+ });
+ });
+
+ it('shows `privilege required` callout for `endpoint` related pages', () => {
+ privilegeRequiredLinks.forEach((link) => {
+ cy.visit(link);
+ cy.url().should('include', link);
+ cy.getByTestSubjContains('noPrivilegesPage').should('exist');
+ });
+ });
+
+ it('shows access denied callout for a set of `ml` links', () => {
+ mlLinks.forEach((link) => {
+ cy.visit(link);
+ cy.url().should('include', link);
+ cy.getByTestSubjContains('mlAccessDenied').should('exist');
+ });
+ });
+ });
});
diff --git a/x-pack/test/security_solution_cypress/cypress/urls/navigation.ts b/x-pack/test/security_solution_cypress/cypress/urls/navigation.ts
index 3025d7de7e325..bf47b7613acab 100644
--- a/x-pack/test/security_solution_cypress/cypress/urls/navigation.ts
+++ b/x-pack/test/security_solution_cypress/cypress/urls/navigation.ts
@@ -19,9 +19,14 @@ export const POLICIES_URL = '/app/security/administration/policy';
export const TRUSTED_APPS_URL = '/app/security/administration/trusted_apps';
export const EVENT_FILTERS_URL = '/app/security/administration/event_filters';
export const BLOCKLIST_URL = '/app/security/administration/blocklist';
+export const HOST_ISOLATION_EXCEPTIONS_URL = `app/security/administration/host_isolation_exceptions`;
+export const RESPONSE_ACTIONS_HISTORY = `app/security/administration/response_actions_history`;
+
export const CSP_BENCHMARKS_URL = '/app/security/cloud_security_posture/benchmarks';
export const CSP_DASHBOARD_URL = '/app/security/cloud_security_posture/dashboard';
export const CSP_FINDINGS_URL = '/app/security/cloud_security_posture/findings/configurations';
+export const CSP_VULNERABILITIES_URL =
+ '/app/security/cloud_security_posture/findings/vulnerabilities';
export const RULES_URL = '/app/security/rules';
export const RULES_COVERAGE_URL = '/app/security/rules_coverage_overview';
@@ -34,6 +39,7 @@ export const OVERVIEW_URL = '/app/security/overview';
export const ENTITY_ANALYTICS_URL = '/app/security/entity_analytics';
export const KUBERNETES_URL = '/app/security/kubernetes';
+export const THREAT_INTELLIGENCE_URL = '/app/security/threat_intelligence';
export const INDICATORS_URL = '/app/security/threat_intelligence/indicators';
export const EXPLORE_URL = '/app/security/explore';
export const userDetailsUrl = (userName: string) =>
@@ -43,6 +49,7 @@ export const INVESTIGATIONS_URL = '/app/security/investigations';
export const TIMELINES_URL = '/app/security/timelines/default';
export const TIMELINE_TEMPLATES_URL = '/app/security/timelines/template';
export const CASES_URL = '/app/security/cases';
+export const NOTES_URL = '/app/security/administration/notes';
export const hostsUrl = (tab: 'allHosts' | 'anomalies' | 'events' | 'uncommonProcesses'): string =>
`/app/security/hosts/${tab}`;
@@ -60,7 +67,11 @@ export const DISCOVER_WITH_PINNED_FILTER_URL =
export const hostDetailsUrl = (hostName: string) =>
`/app/security/hosts/${hostName}/authentications`;
-export const MACHINE_LEARNING_LANDING_URL = '/app/security/ml';
+export const MACHINE_LEARNING_EXPLORER = '/app/ml/explorer';
+export const MACHINE_LEARNING_TIME_SERIES_EXPLORER = '/app/ml/timeseriesexplorer';
+export const MACHINE_LEARNING_DATA_FRAME_ANALYTICS_EXPLORATION =
+ 'app/ml/data_frame_analytics/exploration';
+export const MACHINE_LEARNING_DATA_FRAME_ANALYTICS_MAP = 'app/ml/data_frame_analytics/map';
// Detection and Response
export const DETECTION_AND_RESPONSE_URL = '/app/security/detection_response';
@@ -69,6 +80,7 @@ export const ALERT_SUMMARY_URL = '/app/security/alert_summary';
export const EXCEPTIONS_URL = '/app/security/exceptions';
export const CREATE_RULE_URL = '/app/security/rules/create';
export const ENTITY_ANALYTICS_MANAGEMENT_URL = '/app/security/entity_analytics_management';
+export const ENTITY_ANALYTICS_ENTITY_STORE_URL = '/app/security/entity_analytics_entity_store';
export const ENTITY_ANALYTICS_ASSET_CRITICALITY_URL =
'/app/security/entity_analytics_asset_criticality';