mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[Security Solution] Use useEndpointPrivileges instead of checking the license directly (#116142) (#116886)
* Use useEndpointPrivileges instead of checking the license directly * Use the correct privilege key * rename variable * Skips flaky test * Remove skip * Remove extra dependency * Add back entries check Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
8ab0d9df04
commit
050da3efbb
4 changed files with 38 additions and 32 deletions
|
@ -4,33 +4,35 @@
|
|||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
import { useLicense } from '../../../../common/hooks/use_license';
|
||||
import { useCanSeeHostIsolationExceptionsMenu } from './hooks';
|
||||
import { renderHook } from '@testing-library/react-hooks';
|
||||
import { TestProviders } from '../../../../common/mock';
|
||||
import { getHostIsolationExceptionSummary } from '../service';
|
||||
import { useEndpointPrivileges } from '../../../../common/components/user_privileges/endpoint';
|
||||
|
||||
jest.mock('../../../../common/hooks/use_license');
|
||||
jest.mock('../service');
|
||||
jest.mock('../../../../common/components/user_privileges/endpoint/use_endpoint_privileges');
|
||||
|
||||
const getHostIsolationExceptionSummaryMock = getHostIsolationExceptionSummary as jest.Mock;
|
||||
|
||||
describe('host isolation exceptions hooks', () => {
|
||||
const isPlatinumPlusMock = useLicense().isPlatinumPlus as jest.Mock;
|
||||
const useEndpointPrivilegesMock = useEndpointPrivileges as jest.Mock;
|
||||
describe('useCanSeeHostIsolationExceptionsMenu', () => {
|
||||
beforeEach(() => {
|
||||
isPlatinumPlusMock.mockReset();
|
||||
useEndpointPrivilegesMock.mockReset();
|
||||
});
|
||||
it('should return true if the license is platinum plus', () => {
|
||||
isPlatinumPlusMock.mockReturnValue(true);
|
||||
|
||||
it('should return true if has the correct privileges', () => {
|
||||
useEndpointPrivilegesMock.mockReturnValue({ canIsolateHost: true });
|
||||
const { result } = renderHook(() => useCanSeeHostIsolationExceptionsMenu(), {
|
||||
wrapper: TestProviders,
|
||||
});
|
||||
expect(result.current).toBe(true);
|
||||
});
|
||||
|
||||
it('should return false if the license is lower platinum plus and there are not existing host isolation items', () => {
|
||||
isPlatinumPlusMock.mockReturnValue(false);
|
||||
it('should return false if does not have privileges and there are not existing host isolation items', () => {
|
||||
useEndpointPrivilegesMock.mockReturnValue({ canIsolateHost: false });
|
||||
getHostIsolationExceptionSummaryMock.mockReturnValueOnce({ total: 0 });
|
||||
const { result } = renderHook(() => useCanSeeHostIsolationExceptionsMenu(), {
|
||||
wrapper: TestProviders,
|
||||
|
@ -38,8 +40,8 @@ describe('host isolation exceptions hooks', () => {
|
|||
expect(result.current).toBe(false);
|
||||
});
|
||||
|
||||
it('should return true if the license is lower platinum plus and there are existing host isolation items', async () => {
|
||||
isPlatinumPlusMock.mockReturnValue(false);
|
||||
it('should return true if does not have privileges and there are existing host isolation items', async () => {
|
||||
useEndpointPrivilegesMock.mockReturnValue({ canIsolateHost: false });
|
||||
getHostIsolationExceptionSummaryMock.mockReturnValueOnce({ total: 11 });
|
||||
const { result, waitForNextUpdate } = renderHook(
|
||||
() => useCanSeeHostIsolationExceptionsMenu(),
|
||||
|
|
|
@ -8,7 +8,7 @@ import { useCallback, useEffect, useState } from 'react';
|
|||
import { useSelector } from 'react-redux';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { useHttp } from '../../../../common/lib/kibana/hooks';
|
||||
import { useLicense } from '../../../../common/hooks/use_license';
|
||||
import { useEndpointPrivileges } from '../../../../common/components/user_privileges/endpoint';
|
||||
import { State } from '../../../../common/store';
|
||||
import {
|
||||
MANAGEMENT_STORE_GLOBAL_NAMESPACE,
|
||||
|
@ -42,30 +42,30 @@ export function useHostIsolationExceptionsNavigateCallback() {
|
|||
|
||||
/**
|
||||
* Checks if the current user should be able to see the host isolation exceptions
|
||||
* menu item based on their current license level and existing excepted items.
|
||||
* menu item based on their current privileges
|
||||
*/
|
||||
export function useCanSeeHostIsolationExceptionsMenu() {
|
||||
const license = useLicense();
|
||||
const http = useHttp();
|
||||
const privileges = useEndpointPrivileges();
|
||||
|
||||
const [hasExceptions, setHasExceptions] = useState(license.isPlatinumPlus());
|
||||
const [canSeeMenu, setCanSeeMenu] = useState(privileges.canIsolateHost);
|
||||
|
||||
useEffect(() => {
|
||||
async function checkIfHasExceptions() {
|
||||
try {
|
||||
const summary = await getHostIsolationExceptionSummary(http);
|
||||
if (summary?.total > 0) {
|
||||
setHasExceptions(true);
|
||||
setCanSeeMenu(true);
|
||||
}
|
||||
} catch (error) {
|
||||
// an error will ocurr if the exception list does not exist
|
||||
setHasExceptions(false);
|
||||
setCanSeeMenu(false);
|
||||
}
|
||||
}
|
||||
if (!license.isPlatinumPlus()) {
|
||||
if (!privileges.canIsolateHost) {
|
||||
checkIfHasExceptions();
|
||||
}
|
||||
}, [http, license]);
|
||||
}, [http, privileges.canIsolateHost]);
|
||||
|
||||
return hasExceptions;
|
||||
return canSeeMenu;
|
||||
}
|
||||
|
|
|
@ -14,11 +14,11 @@ import { AppContextTestRender, createAppRootMockRenderer } from '../../../../com
|
|||
import { isFailedResourceState, isLoadedResourceState } from '../../../state';
|
||||
import { getHostIsolationExceptionItems } from '../service';
|
||||
import { HostIsolationExceptionsList } from './host_isolation_exceptions_list';
|
||||
import { useLicense } from '../../../../common/hooks/use_license';
|
||||
import { useEndpointPrivileges } from '../../../../common/components/user_privileges/endpoint';
|
||||
|
||||
jest.mock('../../../../common/components/user_privileges/endpoint/use_endpoint_privileges');
|
||||
jest.mock('../service');
|
||||
jest.mock('../../../../common/hooks/use_license');
|
||||
jest.mock('../../../../common/components/user_privileges/endpoint/use_endpoint_privileges');
|
||||
|
||||
const getHostIsolationExceptionItemsMock = getHostIsolationExceptionItems as jest.Mock;
|
||||
|
||||
|
@ -29,7 +29,7 @@ describe('When on the host isolation exceptions page', () => {
|
|||
let waitForAction: AppContextTestRender['middlewareSpy']['waitForAction'];
|
||||
let mockedContext: AppContextTestRender;
|
||||
|
||||
const isPlatinumPlusMock = useLicense().isPlatinumPlus as jest.Mock;
|
||||
const useEndpointPrivilegesMock = useEndpointPrivileges as jest.Mock;
|
||||
|
||||
beforeEach(() => {
|
||||
getHostIsolationExceptionItemsMock.mockReset();
|
||||
|
@ -129,11 +129,12 @@ describe('When on the host isolation exceptions page', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('is license platinum plus', () => {
|
||||
describe('has canIsolateHost privileges', () => {
|
||||
beforeEach(async () => {
|
||||
isPlatinumPlusMock.mockReturnValue(true);
|
||||
useEndpointPrivilegesMock.mockReturnValue({ canIsolateHost: true });
|
||||
getHostIsolationExceptionItemsMock.mockImplementation(getFoundExceptionListItemSchemaMock);
|
||||
});
|
||||
|
||||
it('should show the create flyout when the add button is pressed', async () => {
|
||||
render();
|
||||
await dataReceived();
|
||||
|
@ -142,6 +143,7 @@ describe('When on the host isolation exceptions page', () => {
|
|||
});
|
||||
expect(renderResult.getByTestId('hostIsolationExceptionsCreateEditFlyout')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should show the create flyout when the show location is create', async () => {
|
||||
history.push(`${HOST_ISOLATION_EXCEPTIONS_PATH}?show=create`);
|
||||
render();
|
||||
|
@ -151,15 +153,17 @@ describe('When on the host isolation exceptions page', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('is not license platinum plus', () => {
|
||||
describe('does not have canIsolateHost privileges', () => {
|
||||
beforeEach(() => {
|
||||
isPlatinumPlusMock.mockReturnValue(false);
|
||||
useEndpointPrivilegesMock.mockReturnValue({ canIsolateHost: false });
|
||||
});
|
||||
|
||||
it('should not show the create flyout if the user navigates to the create url', () => {
|
||||
history.push(`${HOST_ISOLATION_EXCEPTIONS_PATH}?show=create`);
|
||||
render();
|
||||
expect(renderResult.queryByTestId('hostIsolationExceptionsCreateEditFlyout')).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should not show the create flyout if the user navigates to the edit url', () => {
|
||||
history.push(`${HOST_ISOLATION_EXCEPTIONS_PATH}?show=edit`);
|
||||
render();
|
||||
|
|
|
@ -13,7 +13,6 @@ import { FormattedMessage } from '@kbn/i18n/react';
|
|||
import { useDispatch } from 'react-redux';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { ExceptionItem } from '../../../../common/components/exceptions/viewer/exception_item';
|
||||
import { useLicense } from '../../../../common/hooks/use_license';
|
||||
import {
|
||||
getCurrentLocation,
|
||||
getItemToDelete,
|
||||
|
@ -41,6 +40,7 @@ import {
|
|||
EDIT_HOST_ISOLATION_EXCEPTION_LABEL,
|
||||
} from './components/translations';
|
||||
import { getEndpointListPath } from '../../../common/routing';
|
||||
import { useEndpointPrivileges } from '../../../../common/components/user_privileges/endpoint';
|
||||
|
||||
type HostIsolationExceptionPaginatedContent = PaginatedContentProps<
|
||||
Immutable<ExceptionListItemSchema>,
|
||||
|
@ -58,14 +58,14 @@ export const HostIsolationExceptionsList = () => {
|
|||
const itemToDelete = useHostIsolationExceptionsSelector(getItemToDelete);
|
||||
const navigateCallback = useHostIsolationExceptionsNavigateCallback();
|
||||
const history = useHistory();
|
||||
const license = useLicense();
|
||||
const showFlyout = license.isPlatinumPlus() && !!location.show;
|
||||
const privileges = useEndpointPrivileges();
|
||||
const showFlyout = privileges.canIsolateHost && !!location.show;
|
||||
|
||||
useEffect(() => {
|
||||
if (!isLoading && listItems.length === 0 && !license.isPlatinumPlus()) {
|
||||
if (!isLoading && listItems.length === 0 && !privileges.canIsolateHost) {
|
||||
history.replace(getEndpointListPath({ name: 'endpointList' }));
|
||||
}
|
||||
}, [history, isLoading, license, listItems.length]);
|
||||
}, [history, isLoading, listItems.length, privileges.canIsolateHost]);
|
||||
|
||||
const handleOnSearch = useCallback(
|
||||
(query: string) => {
|
||||
|
@ -100,7 +100,7 @@ export const HostIsolationExceptionsList = () => {
|
|||
return {
|
||||
item: element,
|
||||
'data-test-subj': `hostIsolationExceptionsCard`,
|
||||
actions: license.isPlatinumPlus() ? [editAction, deleteAction] : [deleteAction],
|
||||
actions: privileges.canIsolateHost ? [editAction, deleteAction] : [deleteAction],
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -139,7 +139,7 @@ export const HostIsolationExceptionsList = () => {
|
|||
/>
|
||||
}
|
||||
actions={
|
||||
license.isPlatinumPlus() && listItems.length > 0 ? (
|
||||
privileges.canIsolateHost && listItems.length > 0 ? (
|
||||
<EuiButton
|
||||
fill
|
||||
iconType="plusInCircle"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue