From 76ccc9c562e06fd176fd673264c5661e08dd700a Mon Sep 17 00:00:00 2001 From: mohamedhamed-ahmed Date: Thu, 31 Oct 2024 14:36:23 +0000 Subject: [PATCH] [Logs Explorer] Fix privilege checks bug (#198368) ## Summary This PR enhances the privilege checks for Logs Explorer side nav visibility. --- .../infra/public/apps/logs_app.tsx | 31 ++++++-- .../infra/public/plugin.ts | 73 ++++++++++--------- 2 files changed, 65 insertions(+), 39 deletions(-) diff --git a/x-pack/plugins/observability_solution/infra/public/apps/logs_app.tsx b/x-pack/plugins/observability_solution/infra/public/apps/logs_app.tsx index 329e059288e3e..9d5583b0ecf4c 100644 --- a/x-pack/plugins/observability_solution/infra/public/apps/logs_app.tsx +++ b/x-pack/plugins/observability_solution/infra/public/apps/logs_app.tsx @@ -6,13 +6,19 @@ */ import { History } from 'history'; -import { CoreStart } from '@kbn/core/public'; -import React from 'react'; +import { AppStatus, CoreStart } from '@kbn/core/public'; +import React, { useMemo } from 'react'; import ReactDOM from 'react-dom'; import { Router, Routes, Route } from '@kbn/shared-ux-router'; import { AppMountParameters } from '@kbn/core/public'; import { Storage } from '@kbn/kibana-utils-plugin/public'; -import { AllDatasetsLocatorParams, ALL_DATASETS_LOCATOR_ID } from '@kbn/deeplinks-observability'; +import { + AllDatasetsLocatorParams, + ALL_DATASETS_LOCATOR_ID, + OBSERVABILITY_LOGS_EXPLORER_APP_ID, +} from '@kbn/deeplinks-observability'; +import useObservable from 'react-use/lib/useObservable'; +import { map } from 'rxjs'; import { LinkToLogsPage } from '../pages/link_to/link_to_logs'; import { LogsPage } from '../pages/logs'; import { InfraClientStartDeps, InfraClientStartExports } from '../types'; @@ -57,7 +63,22 @@ const LogsApp: React.FC<{ storage: Storage; theme$: AppMountParameters['theme$']; }> = ({ core, history, pluginStart, plugins, setHeaderActionMenu, storage, theme$ }) => { - const { logs, discover, fleet } = core.application.capabilities; + const { logs } = core.application.capabilities; + + const isLogsExplorerAppAccessible = useObservable( + useMemo( + () => + core.application.applications$.pipe( + map( + (apps) => + (apps.get(OBSERVABILITY_LOGS_EXPLORER_APP_ID)?.status ?? AppStatus.inaccessible) === + AppStatus.accessible + ) + ), + [core.application.applications$] + ), + false + ); return ( @@ -74,7 +95,7 @@ const LogsApp: React.FC<{ toastsService={core.notifications.toasts} > - {Boolean(discover?.show && fleet?.read) && ( + {isLogsExplorerAppAccessible && ( + combineLatest([of(application), getLogsExplorerAccessible$(application)]) + ) + ); const logRoutes = getLogsAppRoutes({ isLogsStreamEnabled }); /** !! Need to be kept in sync with the deepLinks in x-pack/plugins/observability_solution/infra/public/plugin.ts */ pluginsSetup.observabilityShared.navigation.registerSections( - startDep$AndHostViewFlag$.pipe( - map(([[{ application }]]) => { + startDep$AndAccessibleFlag$.pipe( + map(([application, isLogsExplorerAccessible]) => { const { infrastructure, logs } = application.capabilities; return [ ...(logs.show @@ -148,7 +159,7 @@ export class Plugin implements InfraClientPluginClass { label: logsTitle, sortKey: 200, entries: getLogsNavigationEntries({ - application, + isLogsExplorerAccessible, config: this.config, routes: logRoutes, }), @@ -310,16 +321,13 @@ export class Plugin implements InfraClientPluginClass { ); }, }); - - startDep$AndHostViewFlag$.subscribe( - ([_startServices]: [[CoreStart, InfraClientStartDeps, InfraClientStartExports]]) => { - this.appUpdater$.next(() => ({ - deepLinks: getInfraDeepLinks({ - metricsExplorerEnabled: this.config.featureFlags.metricsExplorerEnabled, - }), - })); - } - ); + startDep$AndAccessibleFlag$.subscribe(([_applicationStart, _isLogsExplorerAccessible]) => { + this.appUpdater$.next(() => ({ + deepLinks: getInfraDeepLinks({ + metricsExplorerEnabled: this.config.featureFlags.metricsExplorerEnabled, + }), + })); + }); // Setup telemetry events this.telemetry.setup({ analytics: core.analytics }); @@ -382,11 +390,11 @@ export class Plugin implements InfraClientPluginClass { } const getLogsNavigationEntries = ({ - application, + isLogsExplorerAccessible, config, routes, }: { - application: CoreStart['application']; + isLogsExplorerAccessible: boolean; config: InfraPublicConfig; routes: LogsAppRoutes; }) => { @@ -394,16 +402,14 @@ const getLogsNavigationEntries = ({ if (!config.featureFlags.logsUIEnabled) return entries; - getLogsExplorerAccessibility$(application).subscribe((isAccessible) => { - if (isAccessible) { - entries.push({ - label: 'Explorer', - app: 'observability-logs-explorer', - path: '/', - isBetaFeature: true, - }); - } - }); + if (isLogsExplorerAccessible) { + entries.push({ + label: 'Explorer', + app: 'observability-logs-explorer', + path: '/', + isBetaFeature: true, + }); + } // Display Stream nav entry when Logs Stream is enabled if (routes.stream) entries.push(createNavEntryFromRoute(routes.stream)); @@ -416,16 +422,15 @@ const getLogsNavigationEntries = ({ return entries; }; -const getLogsExplorerAccessibility$ = (application: CoreStart['application']) => { - const { capabilities, applications$ } = application; +const getLogsExplorerAccessible$ = (application: CoreStart['application']) => { + const { applications$ } = application; return applications$.pipe( map( (apps) => (apps.get(OBSERVABILITY_LOGS_EXPLORER_APP_ID)?.status ?? AppStatus.inaccessible) === - AppStatus.accessible && - capabilities.discover?.show && - capabilities.fleet?.read - ) + AppStatus.accessible + ), + distinctUntilChanged() ); };