mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[TIP] Restrict content visibility for non-enterprise users (#138097)
This commit is contained in:
parent
46a2c63ab3
commit
335d63a516
9 changed files with 134 additions and 14 deletions
|
@ -12,6 +12,7 @@ import { SpyRoute } from '../../common/utils/route/spy_routes';
|
|||
import { SecurityPageName } from '../../../common/constants';
|
||||
import { useKibana } from '../../common/lib/kibana';
|
||||
import { FiltersGlobal } from '../../common/components/filters_global';
|
||||
import { licenseService } from '../../common/hooks/use_license';
|
||||
|
||||
const ThreatIntelligence = () => {
|
||||
const services = useKibana().services;
|
||||
|
@ -20,6 +21,7 @@ const ThreatIntelligence = () => {
|
|||
|
||||
const securitySolutionContext: ThreatIntelligenceSecuritySolutionContext = {
|
||||
getFiltersGlobalComponent: () => FiltersGlobal,
|
||||
licenseService,
|
||||
};
|
||||
|
||||
return (
|
||||
|
|
|
@ -111,6 +111,11 @@ const mockSecurityContext: ThreatIntelligenceSecuritySolutionContext = {
|
|||
() =>
|
||||
({ children }) =>
|
||||
<div>{children}</div>,
|
||||
licenseService: {
|
||||
isEnterprise() {
|
||||
return true;
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const mockedServices = {
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* 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 { render, screen } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { ThreatIntelligenceSecuritySolutionContext } from '../../types';
|
||||
import { SecuritySolutionContext } from '../security_solution_context';
|
||||
import { EnterpriseGuard } from './enterprise_guard';
|
||||
|
||||
describe('<EnterpriseGuard />', () => {
|
||||
describe('when on enterprise plan', () => {
|
||||
it('should render specified children', () => {
|
||||
render(
|
||||
<SecuritySolutionContext.Provider
|
||||
value={
|
||||
{
|
||||
licenseService: { isEnterprise: jest.fn().mockReturnValue(true) },
|
||||
} as unknown as ThreatIntelligenceSecuritySolutionContext
|
||||
}
|
||||
>
|
||||
<EnterpriseGuard>
|
||||
<div>enterprise only content</div>
|
||||
</EnterpriseGuard>
|
||||
</SecuritySolutionContext.Provider>
|
||||
);
|
||||
|
||||
expect(screen.queryByText('enterprise only content')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when not on enterprise plan', () => {
|
||||
it('should render specified children', () => {
|
||||
render(
|
||||
<SecuritySolutionContext.Provider
|
||||
value={
|
||||
{
|
||||
licenseService: { isEnterprise: jest.fn().mockReturnValue(false) },
|
||||
} as unknown as ThreatIntelligenceSecuritySolutionContext
|
||||
}
|
||||
>
|
||||
<EnterpriseGuard fallback={<div>fallback for non enterprise</div>}>
|
||||
<div>enterprise only content</div>
|
||||
</EnterpriseGuard>
|
||||
</SecuritySolutionContext.Provider>
|
||||
);
|
||||
|
||||
expect(screen.queryByText('enterprise only content')).not.toBeInTheDocument();
|
||||
expect(screen.queryByText('fallback for non enterprise')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* 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 React, { ReactElement } from 'react';
|
||||
import { FC } from 'react';
|
||||
import { useSecurityContext } from '../../hooks/use_security_context';
|
||||
|
||||
interface EnterpriseGuardProps {
|
||||
fallback?: ReactElement;
|
||||
}
|
||||
|
||||
export const EnterpriseGuard: FC<EnterpriseGuardProps> = ({ children, fallback = null }) => {
|
||||
const { licenseService } = useSecurityContext();
|
||||
|
||||
if (licenseService.isEnterprise()) {
|
||||
return <>{children}</>;
|
||||
}
|
||||
|
||||
return fallback;
|
||||
};
|
|
@ -0,0 +1,8 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export * from './enterprise_guard';
|
|
@ -6,15 +6,11 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { FC, useContext } from 'react';
|
||||
import { SecuritySolutionContext } from './security_solution_context';
|
||||
import { FC } from 'react';
|
||||
import { useSecurityContext } from '../hooks/use_security_context';
|
||||
|
||||
export const FiltersGlobal: FC = ({ children }) => {
|
||||
const contextValue = useContext(SecuritySolutionContext);
|
||||
|
||||
if (!contextValue) {
|
||||
throw new Error('FiltersGlobal can only be used within Security Solution Context');
|
||||
}
|
||||
const contextValue = useSecurityContext();
|
||||
|
||||
const Component = contextValue.getFiltersGlobalComponent();
|
||||
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* 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 { useContext } from 'react';
|
||||
import { SecuritySolutionContext } from '../containers/security_solution_context';
|
||||
import { ThreatIntelligenceSecuritySolutionContext } from '../types';
|
||||
|
||||
export const useSecurityContext = (): ThreatIntelligenceSecuritySolutionContext => {
|
||||
const contextValue = useContext(SecuritySolutionContext);
|
||||
|
||||
if (!contextValue) {
|
||||
throw new Error(
|
||||
'SecuritySolutionContext can only be used within SecuritySolutionContext provider'
|
||||
);
|
||||
}
|
||||
|
||||
return contextValue;
|
||||
};
|
|
@ -18,6 +18,7 @@ import {
|
|||
ThreatIntelligenceSecuritySolutionContext,
|
||||
} from './types';
|
||||
import { SecuritySolutionContext } from './containers/security_solution_context';
|
||||
import { EnterpriseGuard } from './containers/enterprise_guard';
|
||||
|
||||
interface AppProps {
|
||||
securitySolutionContext: ThreatIntelligenceSecuritySolutionContext;
|
||||
|
@ -35,13 +36,15 @@ export const createApp =
|
|||
({ securitySolutionContext }: AppProps) =>
|
||||
(
|
||||
<IntlProvider>
|
||||
<KibanaContextProvider services={services}>
|
||||
<SecuritySolutionContext.Provider value={securitySolutionContext}>
|
||||
<Suspense fallback={<div />}>
|
||||
<LazyIndicatorsPage />
|
||||
</Suspense>
|
||||
</SecuritySolutionContext.Provider>
|
||||
</KibanaContextProvider>
|
||||
<SecuritySolutionContext.Provider value={securitySolutionContext}>
|
||||
<EnterpriseGuard>
|
||||
<KibanaContextProvider services={services}>
|
||||
<Suspense fallback={<div />}>
|
||||
<LazyIndicatorsPage />
|
||||
</Suspense>
|
||||
</KibanaContextProvider>
|
||||
</EnterpriseGuard>
|
||||
</SecuritySolutionContext.Provider>
|
||||
</IntlProvider>
|
||||
);
|
||||
|
||||
|
|
|
@ -30,6 +30,11 @@ export type Services = {
|
|||
dataViews: DataViewsPublicPluginStart;
|
||||
} & CoreStart;
|
||||
|
||||
export interface LicenseAware {
|
||||
isEnterprise(): boolean;
|
||||
}
|
||||
|
||||
export interface ThreatIntelligenceSecuritySolutionContext {
|
||||
getFiltersGlobalComponent: () => ComponentType<{ children: ReactNode }>;
|
||||
licenseService: LicenseAware;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue