Skip to content

Commit

Permalink
[TIP] disable add to blocklist feature if user doesn't have write pri…
Browse files Browse the repository at this point in the history
…vilege (elastic#149710)
  • Loading branch information
PhilippeOberti authored and kqualters-elastic committed Feb 6, 2023
1 parent 8a4b445 commit 75fc86f
Show file tree
Hide file tree
Showing 7 changed files with 155 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { THREAT_INTELLIGENCE_BASE_PATH } from '@kbn/threat-intelligence-plugin/p
import type { SourcererDataView } from '@kbn/threat-intelligence-plugin/public/types';
import type { Store } from 'redux';
import { useSelector } from 'react-redux';
import { useUserPrivileges } from '../common/components/user_privileges';
import { useSetUrlParams } from '../management/components/artifact_list_page/hooks/use_set_url_params';
import { BlockListForm } from '../management/pages/blocklist/view/components/blocklist_form';
import { BlocklistsApiClient } from '../management/pages/blocklist/services';
Expand Down Expand Up @@ -49,6 +50,7 @@ const ThreatIntelligence = memo(() => {
getUseInvestigateInTimeline: useInvestigateInTimeline,

blockList: {
canWriteBlocklist: useUserPrivileges().endpointPrivileges.canWriteBlocklist,
exceptionListApiClient: BlocklistsApiClient.getInstance(http),
useSetUrlParams,
// @ts-ignore
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export const getSecuritySolutionContextMock = (): SecuritySolutionPluginContext
deregisterQuery: () => {},

blockList: {
canWriteBlocklist: true,
exceptionListApiClient: {},
useSetUrlParams: () => (params, replace) => {},
getFlyoutComponent: () => (<div />) as unknown as NamedExoticComponent<BlockListFlyoutProps>,
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,22 @@ export const ContextMenu: Story<void> = () => {
</SecuritySolutionContext.Provider>
);
};

export const Disabled: Story<void> = () => {
const mockSecurityContext: SecuritySolutionPluginContext = getSecuritySolutionContextMock();
mockSecurityContext.blockList.canWriteBlocklist = false;

const mockIndicatorFileHashValue: string = 'abc';
const mockOnClick: () => void = () => window.alert('clicked!');
const items = [
<AddToBlockListContextMenu data={mockIndicatorFileHashValue} onClick={mockOnClick} />,
];

return (
<SecuritySolutionContext.Provider value={mockSecurityContext}>
<BlockListProvider>
<EuiContextMenuPanel items={items} />
</BlockListProvider>
</SecuritySolutionContext.Provider>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ describe('<AddToBlockListContextMenu />', () => {
expect(component).toMatchSnapshot();
});

it('should render a disabled EuiContextMenuItem', () => {
it('should render a disabled EuiContextMenuItem if data is null', () => {
const mockSecurityContext: SecuritySolutionPluginContext = getSecuritySolutionContextMock();

const mockIndicatorFileHashValue = null;
Expand All @@ -47,4 +47,22 @@ describe('<AddToBlockListContextMenu />', () => {

expect(component).toMatchSnapshot();
});

it('should render a disabled EuiContextMenuItem if no write blocklist privilege', () => {
const mockSecurityContext: SecuritySolutionPluginContext = getSecuritySolutionContextMock();
mockSecurityContext.blockList.canWriteBlocklist = false;

const mockIndicatorFileHashValue: string = 'abc';
const mockOnClick: () => void = () => window.alert('clicked!');

const component = render(
<SecuritySolutionContext.Provider value={mockSecurityContext}>
<BlockListProvider>
<AddToBlockListContextMenu data={mockIndicatorFileHashValue} onClick={mockOnClick} />
</BlockListProvider>
</SecuritySolutionContext.Provider>
);

expect(component).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import React, { VFC } from 'react';
import { EuiContextMenuItem } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
import { useSecurityContext } from '../../../../hooks';
import { useBlockListContext } from '../../../indicators/hooks/use_block_list_context';
import { useSetUrlParams } from '../../hooks/use_set_url_params';

Expand Down Expand Up @@ -37,6 +38,9 @@ export const AddToBlockListContextMenu: VFC<AddToBlockListProps> = ({
'data-test-subj': dataTestSub,
onClick,
}) => {
const {
blockList: { canWriteBlocklist },
} = useSecurityContext();
const { setBlockListIndicatorValue } = useBlockListContext();
const { setUrlParams } = useSetUrlParams();

Expand All @@ -46,12 +50,14 @@ export const AddToBlockListContextMenu: VFC<AddToBlockListProps> = ({
setUrlParams({ show: 'create' });
};

const disabled = !canWriteBlocklist || data === null;

return (
<EuiContextMenuItem
key="addToBlocklist"
onClick={() => menuItemClicked()}
data-test-subj={dataTestSub}
disabled={data == null}
disabled={disabled}
>
<FormattedMessage
defaultMessage="Add blocklist entry"
Expand Down
9 changes: 9 additions & 0 deletions x-pack/plugins/threat_intelligence/public/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,14 +106,17 @@ export interface SecuritySolutionPluginContext {
* Get the user's license to drive the Threat Intelligence plugin's visibility.
*/
licenseService: LicenseAware;

/**
* Gets Security Solution shared information like browerFields, indexPattern and selectedPatterns in DataView.
*/
sourcererDataView: SourcererDataView;

/**
* Security Solution store
*/
securitySolutionStore: Store;

/**
* Pass UseInvestigateInTimeline functionality to TI plugin
*/
Expand All @@ -124,7 +127,9 @@ export interface SecuritySolutionPluginContext {
}: UseInvestigateInTimelineProps) => () => Promise<void>;

useQuery: () => Query;

useFilters: () => Filter[];

useGlobalTime: () => TimeRange;

SiemSearchBar: VFC<any>;
Expand All @@ -139,7 +144,11 @@ export interface SecuritySolutionPluginContext {
*/
deregisterQuery: (query: { id: string }) => void;

/**
* Add to blocklist feature
*/
blockList: {
canWriteBlocklist: boolean;
exceptionListApiClient: unknown;
useSetUrlParams: () => (
params: Record<string, string | number | null | undefined>,
Expand Down

0 comments on commit 75fc86f

Please sign in to comment.