From ffda8c0e444ab51036ef070df4a3c6fc2a9bcc9e Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Tue, 9 Aug 2022 05:13:31 -0400 Subject: [PATCH] [TIP] Restrict content visibility for non-enterprise users (#138097) (#138358) (cherry picked from commit 335d63a516ec16f1c2edf87a4c79b1e5c33e65c2) Co-authored-by: Luke Gmys --- .../pages/threat_intelligence.tsx | 2 + .../public/common/mocks/test_providers.tsx | 5 ++ .../enterprise_guard.test.tsx | 55 +++++++++++++++++++ .../enterprise_guard/enterprise_guard.tsx | 24 ++++++++ .../containers/enterprise_guard/index.ts | 8 +++ .../public/containers/filters_global.tsx | 10 +--- .../public/hooks/use_security_context.ts | 22 ++++++++ .../threat_intelligence/public/plugin.tsx | 17 +++--- .../threat_intelligence/public/types.ts | 5 ++ 9 files changed, 134 insertions(+), 14 deletions(-) create mode 100644 x-pack/plugins/threat_intelligence/public/containers/enterprise_guard/enterprise_guard.test.tsx create mode 100644 x-pack/plugins/threat_intelligence/public/containers/enterprise_guard/enterprise_guard.tsx create mode 100644 x-pack/plugins/threat_intelligence/public/containers/enterprise_guard/index.ts create mode 100644 x-pack/plugins/threat_intelligence/public/hooks/use_security_context.ts diff --git a/x-pack/plugins/security_solution/public/threat_intelligence/pages/threat_intelligence.tsx b/x-pack/plugins/security_solution/public/threat_intelligence/pages/threat_intelligence.tsx index 468fe58b7be0b..9801d4cb15cb5 100644 --- a/x-pack/plugins/security_solution/public/threat_intelligence/pages/threat_intelligence.tsx +++ b/x-pack/plugins/security_solution/public/threat_intelligence/pages/threat_intelligence.tsx @@ -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 ( diff --git a/x-pack/plugins/threat_intelligence/public/common/mocks/test_providers.tsx b/x-pack/plugins/threat_intelligence/public/common/mocks/test_providers.tsx index b9f5e3d5cae42..f10faded12c3b 100644 --- a/x-pack/plugins/threat_intelligence/public/common/mocks/test_providers.tsx +++ b/x-pack/plugins/threat_intelligence/public/common/mocks/test_providers.tsx @@ -97,6 +97,11 @@ const mockSecurityContext: ThreatIntelligenceSecuritySolutionContext = { () => ({ children }) =>
{children}
, + licenseService: { + isEnterprise() { + return true; + }, + }, }; mockCoreStart.uiSettings.get.mockImplementation(mockUiSetting); diff --git a/x-pack/plugins/threat_intelligence/public/containers/enterprise_guard/enterprise_guard.test.tsx b/x-pack/plugins/threat_intelligence/public/containers/enterprise_guard/enterprise_guard.test.tsx new file mode 100644 index 0000000000000..bb4739bb6251f --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/containers/enterprise_guard/enterprise_guard.test.tsx @@ -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('', () => { + describe('when on enterprise plan', () => { + it('should render specified children', () => { + render( + + +
enterprise only content
+
+
+ ); + + expect(screen.queryByText('enterprise only content')).toBeInTheDocument(); + }); + }); + + describe('when not on enterprise plan', () => { + it('should render specified children', () => { + render( + + fallback for non enterprise}> +
enterprise only content
+
+
+ ); + + expect(screen.queryByText('enterprise only content')).not.toBeInTheDocument(); + expect(screen.queryByText('fallback for non enterprise')).toBeInTheDocument(); + }); + }); +}); diff --git a/x-pack/plugins/threat_intelligence/public/containers/enterprise_guard/enterprise_guard.tsx b/x-pack/plugins/threat_intelligence/public/containers/enterprise_guard/enterprise_guard.tsx new file mode 100644 index 0000000000000..67351c1e3d149 --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/containers/enterprise_guard/enterprise_guard.tsx @@ -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 = ({ children, fallback = null }) => { + const { licenseService } = useSecurityContext(); + + if (licenseService.isEnterprise()) { + return <>{children}; + } + + return fallback; +}; diff --git a/x-pack/plugins/threat_intelligence/public/containers/enterprise_guard/index.ts b/x-pack/plugins/threat_intelligence/public/containers/enterprise_guard/index.ts new file mode 100644 index 0000000000000..72cc0cbce39e0 --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/containers/enterprise_guard/index.ts @@ -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'; diff --git a/x-pack/plugins/threat_intelligence/public/containers/filters_global.tsx b/x-pack/plugins/threat_intelligence/public/containers/filters_global.tsx index 96eec40008a25..dde9ae1db0d73 100644 --- a/x-pack/plugins/threat_intelligence/public/containers/filters_global.tsx +++ b/x-pack/plugins/threat_intelligence/public/containers/filters_global.tsx @@ -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(); diff --git a/x-pack/plugins/threat_intelligence/public/hooks/use_security_context.ts b/x-pack/plugins/threat_intelligence/public/hooks/use_security_context.ts new file mode 100644 index 0000000000000..433f12bf548c0 --- /dev/null +++ b/x-pack/plugins/threat_intelligence/public/hooks/use_security_context.ts @@ -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; +}; diff --git a/x-pack/plugins/threat_intelligence/public/plugin.tsx b/x-pack/plugins/threat_intelligence/public/plugin.tsx index fb93ae824556a..de097dda6cfff 100755 --- a/x-pack/plugins/threat_intelligence/public/plugin.tsx +++ b/x-pack/plugins/threat_intelligence/public/plugin.tsx @@ -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) => ( - - - }> - - - - + + + + }> + + + + + ); diff --git a/x-pack/plugins/threat_intelligence/public/types.ts b/x-pack/plugins/threat_intelligence/public/types.ts index 6620f31120667..1a12517739325 100644 --- a/x-pack/plugins/threat_intelligence/public/types.ts +++ b/x-pack/plugins/threat_intelligence/public/types.ts @@ -30,6 +30,11 @@ export type Services = { dataViews: DataViewsPublicPluginStart; } & CoreStart; +export interface LicenseAware { + isEnterprise(): boolean; +} + export interface ThreatIntelligenceSecuritySolutionContext { getFiltersGlobalComponent: () => ComponentType<{ children: ReactNode }>; + licenseService: LicenseAware; }