Skip to content

Commit

Permalink
[Logs Explorer] Fix Privileges Accessibility (elastic#193894)
Browse files Browse the repository at this point in the history
closes elastic#192062

This PR adds privileges checks for `Logs Explorerer` it checks for
`Discover & Fleet` privileges before allowing the user access to `Logs
Explorer`.
Clicking on the `Logs` tab from the side nav defaults to `Stream`, as
long as its not depricated, in case the user doesn't have access to
`Logs Explorer`

https://github.com/user-attachments/assets/a4105ec0-7681-40ee-b2fd-e39b9c178dcf
(cherry picked from commit dbfd4f0)
  • Loading branch information
mohamedhamed-ahmed committed Oct 30, 2024
1 parent d4b1e28 commit d965c7f
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 78 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,17 @@ import { EuiCallOut } from '@elastic/eui';
import React from 'react';
import { i18n } from '@kbn/i18n';
import { EuiButton } from '@elastic/eui';
import { AllDatasetsLocatorParams, ALL_DATASETS_LOCATOR_ID } from '@kbn/deeplinks-observability';
import {
AllDatasetsLocatorParams,
ALL_DATASETS_LOCATOR_ID,
DatasetLocatorParams,
} from '@kbn/deeplinks-observability';
import { getRouterLinkProps } from '@kbn/router-utils';
import useLocalStorage from 'react-use/lib/useLocalStorage';

import { euiThemeVars } from '@kbn/ui-theme';
import { css } from '@emotion/css';
import { SharePublicStart } from '@kbn/share-plugin/public/plugin';
import { LocatorPublic } from '@kbn/share-plugin/common';
import { useKibanaContextForPlugin } from '../hooks/use_kibana';

const pageConfigurations = {
Expand Down Expand Up @@ -44,14 +48,22 @@ interface LogsDeprecationCalloutProps {

export const LogsDeprecationCallout = ({ page }: LogsDeprecationCalloutProps) => {
const {
services: { share },
services: {
share,
application: {
capabilities: { discover, fleet },
},
},
} = useKibanaContextForPlugin();

const { dismissalStorageKey, message } = pageConfigurations[page];

const [isDismissed, setDismissed] = useLocalStorage(dismissalStorageKey, false);

if (isDismissed) {
const allDatasetLocator =
share.url.locators.get<AllDatasetsLocatorParams>(ALL_DATASETS_LOCATOR_ID);

if (isDismissed || !(allDatasetLocator && discover?.show && fleet?.read)) {
return null;
}

Expand All @@ -71,7 +83,7 @@ export const LogsDeprecationCallout = ({ page }: LogsDeprecationCalloutProps) =>
fill
data-test-subj="infraLogsDeprecationCalloutTryLogsExplorerButton"
color="warning"
{...getLogsExplorerLinkProps(share)}
{...getLogsExplorerLinkProps(allDatasetLocator)}
>
{i18n.translate('xpack.infra.logsDeprecationCallout.tryLogsExplorerButtonLabel', {
defaultMessage: 'Try Logs Explorer',
Expand All @@ -81,9 +93,7 @@ export const LogsDeprecationCallout = ({ page }: LogsDeprecationCalloutProps) =>
);
};

const getLogsExplorerLinkProps = (share: SharePublicStart) => {
const locator = share.url.locators.get<AllDatasetsLocatorParams>(ALL_DATASETS_LOCATOR_ID)!;

const getLogsExplorerLinkProps = (locator: LocatorPublic<DatasetLocatorParams>) => {
return getRouterLinkProps({
href: locator.getRedirectUrl({}),
onClick: () => locator.navigate({}),
Expand Down
144 changes: 74 additions & 70 deletions x-pack/plugins/observability_solution/infra/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
DEFAULT_APP_CATEGORIES,
PluginInitializerContext,
AppDeepLinkLocations,
AppStatus,
} from '@kbn/core/public';
import { i18n } from '@kbn/i18n';
import { enableInfrastructureHostsView } from '@kbn/observability-plugin/public';
Expand All @@ -35,6 +36,7 @@ import {
} from '@kbn/observability-shared-plugin/common';
import { OBSERVABILITY_ENABLE_LOGS_STREAM } from '@kbn/management-settings-ids';
import { NavigationEntry } from '@kbn/observability-shared-plugin/public';
import { OBSERVABILITY_LOGS_EXPLORER_APP_ID } from '@kbn/deeplinks-observability/constants';
import type { InfraPublicConfig } from '../common/plugin_config_types';
import { createInventoryMetricRuleType } from './alerting/inventory';
import { createLogThresholdRuleType } from './alerting/log_threshold';
Expand Down Expand Up @@ -141,66 +143,53 @@ export class Plugin implements InfraClientPluginClass {
/** !! 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: { capabilities },
},
],
isInfrastructureHostsViewEnabled,
]) => {
const { infrastructure, logs } = capabilities;
return [
...(logs.show
? [
{
label: logsTitle,
sortKey: 200,
entries: getLogsNavigationEntries({
capabilities,
config: this.config,
routes: logRoutes,
}),
},
]
: []),
...(infrastructure.show
? [
{
label: metricsTitle,
sortKey: 300,
entries: [
{
label: inventoryTitle,
app: 'metrics',
path: '/inventory',
},
...(this.config.featureFlags.metricsExplorerEnabled
? [
{
label: metricsExplorerTitle,
app: 'metrics',
path: '/explorer',
},
]
: []),
...(isInfrastructureHostsViewEnabled
? [
{
label: hostsTitle,
app: 'metrics',
path: '/hosts',
},
]
: []),
],
},
]
: []),
];
}
)
map(([[{ application }]]) => {
const { infrastructure, logs } = application.capabilities;
return [
...(logs.show
? [
{
label: logsTitle,
sortKey: 200,
entries: getLogsNavigationEntries({
application,
config: this.config,
routes: logRoutes,
}),
},
]
: []),
...(infrastructure.show
? [
{
label: metricsTitle,
sortKey: 300,
entries: [
{
label: inventoryTitle,
app: 'metrics',
path: '/inventory',
},
...(this.config.featureFlags.metricsExplorerEnabled
? [
{
label: metricsExplorerTitle,
app: 'metrics',
path: '/explorer',
},
]
: []),
{
label: hostsTitle,
app: 'metrics',
path: '/hosts',
},
],
},
]
: []),
];
})
)
);

Expand Down Expand Up @@ -408,26 +397,28 @@ export class Plugin implements InfraClientPluginClass {
}

const getLogsNavigationEntries = ({
capabilities,
application,
config,
routes,
}: {
capabilities: CoreStart['application']['capabilities'];
application: CoreStart['application'];
config: InfraPublicConfig;
routes: LogsAppRoutes;
}) => {
const entries: NavigationEntry[] = [];

if (!config.featureFlags.logsUIEnabled) return entries;

if (capabilities.discover?.show && capabilities.fleet?.read) {
entries.push({
label: 'Explorer',
app: 'observability-logs-explorer',
path: '/',
isBetaFeature: true,
});
}
getLogsExplorerAccessibility$(application).subscribe((isAccessible) => {
if (isAccessible) {
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));
Expand All @@ -440,6 +431,19 @@ const getLogsNavigationEntries = ({
return entries;
};

const getLogsExplorerAccessibility$ = (application: CoreStart['application']) => {
const { capabilities, 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
)
);
};

const createNavEntryFromRoute = ({ path, title }: LogsRoute): NavigationEntry => ({
app: 'logs',
label: title,
Expand Down

0 comments on commit d965c7f

Please sign in to comment.