mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[TIP] use cases plugin permission api (#146738)
elastic/security-team#5474
This commit is contained in:
parent
a30d225421
commit
cf2bbcd957
13 changed files with 476 additions and 48 deletions
|
@ -70,6 +70,12 @@ const defaultServices = {
|
|||
getUseCasesAddToNewCaseFlyout: () => {},
|
||||
getUseCasesAddToExistingCaseModal: () => {},
|
||||
},
|
||||
helpers: {
|
||||
canUseCases: () => ({
|
||||
create: true,
|
||||
update: true,
|
||||
}),
|
||||
},
|
||||
},
|
||||
} as unknown as CoreStart;
|
||||
|
||||
|
|
|
@ -13,20 +13,12 @@ import { IntegrationsGuard } from './integrations_guard/integrations_guard';
|
|||
import { SecuritySolutionPluginTemplateWrapper } from './security_solution_plugin_template_wrapper';
|
||||
import { useKibana } from '../hooks';
|
||||
|
||||
// export const APP_ID = 'threatIntdelligence';
|
||||
export const APP_ID = 'securitySolution';
|
||||
|
||||
export const IndicatorsPageWrapper: VFC = () => {
|
||||
const { cases } = useKibana().services;
|
||||
const CasesContext = cases.ui.getCasesContext();
|
||||
const permissions: CasesPermissions = {
|
||||
all: true,
|
||||
create: true,
|
||||
read: true,
|
||||
update: true,
|
||||
delete: true,
|
||||
push: true,
|
||||
};
|
||||
const permissions: CasesPermissions = cases.helpers.canUseCases();
|
||||
|
||||
const queryClient = new QueryClient();
|
||||
|
||||
|
|
|
@ -91,7 +91,100 @@ Object {
|
|||
}
|
||||
`;
|
||||
|
||||
exports[`AddToExistingCase should render the EuiContextMenuItem disabled 1`] = `
|
||||
exports[`AddToExistingCase should render the EuiContextMenuItem disabled if indicator is missing name 1`] = `
|
||||
Object {
|
||||
"asFragment": [Function],
|
||||
"baseElement": <body>
|
||||
<div>
|
||||
<button
|
||||
class="euiContextMenuItem euiContextMenuItem-isDisabled"
|
||||
disabled=""
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
class="euiContextMenu__itemLayout"
|
||||
>
|
||||
<span
|
||||
class="euiContextMenuItem__text"
|
||||
>
|
||||
Add to existing case
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</body>,
|
||||
"container": <div>
|
||||
<button
|
||||
class="euiContextMenuItem euiContextMenuItem-isDisabled"
|
||||
disabled=""
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
class="euiContextMenu__itemLayout"
|
||||
>
|
||||
<span
|
||||
class="euiContextMenuItem__text"
|
||||
>
|
||||
Add to existing case
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
</div>,
|
||||
"debug": [Function],
|
||||
"findAllByAltText": [Function],
|
||||
"findAllByDisplayValue": [Function],
|
||||
"findAllByLabelText": [Function],
|
||||
"findAllByPlaceholderText": [Function],
|
||||
"findAllByRole": [Function],
|
||||
"findAllByTestId": [Function],
|
||||
"findAllByText": [Function],
|
||||
"findAllByTitle": [Function],
|
||||
"findByAltText": [Function],
|
||||
"findByDisplayValue": [Function],
|
||||
"findByLabelText": [Function],
|
||||
"findByPlaceholderText": [Function],
|
||||
"findByRole": [Function],
|
||||
"findByTestId": [Function],
|
||||
"findByText": [Function],
|
||||
"findByTitle": [Function],
|
||||
"getAllByAltText": [Function],
|
||||
"getAllByDisplayValue": [Function],
|
||||
"getAllByLabelText": [Function],
|
||||
"getAllByPlaceholderText": [Function],
|
||||
"getAllByRole": [Function],
|
||||
"getAllByTestId": [Function],
|
||||
"getAllByText": [Function],
|
||||
"getAllByTitle": [Function],
|
||||
"getByAltText": [Function],
|
||||
"getByDisplayValue": [Function],
|
||||
"getByLabelText": [Function],
|
||||
"getByPlaceholderText": [Function],
|
||||
"getByRole": [Function],
|
||||
"getByTestId": [Function],
|
||||
"getByText": [Function],
|
||||
"getByTitle": [Function],
|
||||
"queryAllByAltText": [Function],
|
||||
"queryAllByDisplayValue": [Function],
|
||||
"queryAllByLabelText": [Function],
|
||||
"queryAllByPlaceholderText": [Function],
|
||||
"queryAllByRole": [Function],
|
||||
"queryAllByTestId": [Function],
|
||||
"queryAllByText": [Function],
|
||||
"queryAllByTitle": [Function],
|
||||
"queryByAltText": [Function],
|
||||
"queryByDisplayValue": [Function],
|
||||
"queryByLabelText": [Function],
|
||||
"queryByPlaceholderText": [Function],
|
||||
"queryByRole": [Function],
|
||||
"queryByTestId": [Function],
|
||||
"queryByText": [Function],
|
||||
"queryByTitle": [Function],
|
||||
"rerender": [Function],
|
||||
"unmount": [Function],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`AddToExistingCase should render the EuiContextMenuItem disabled if user has no update permission 1`] = `
|
||||
Object {
|
||||
"asFragment": [Function],
|
||||
"baseElement": <body>
|
||||
|
|
|
@ -10,31 +10,87 @@ import { render } from '@testing-library/react';
|
|||
import { AddToExistingCase } from './add_to_existing_case';
|
||||
import { TestProvidersComponent } from '../../../../common/mocks/test_providers';
|
||||
import { generateMockFileIndicator, Indicator } from '../../../../../common/types/indicator';
|
||||
import { casesPluginMock } from '@kbn/cases-plugin/public/mocks';
|
||||
import { KibanaContext } from '../../../../hooks';
|
||||
|
||||
const indicator: Indicator = generateMockFileIndicator();
|
||||
const onClick = () => window.alert('clicked');
|
||||
const casesServiceMock = casesPluginMock.createStartContract();
|
||||
|
||||
describe('AddToExistingCase', () => {
|
||||
it('should render an EuiContextMenuItem', () => {
|
||||
const indicator: Indicator = generateMockFileIndicator();
|
||||
const onClick = () => window.alert('clicked');
|
||||
const mockedServices = {
|
||||
cases: {
|
||||
...casesServiceMock,
|
||||
helpers: {
|
||||
...casesServiceMock.helpers,
|
||||
canUseCases: () => ({
|
||||
create: true,
|
||||
update: true,
|
||||
}),
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const component = render(
|
||||
<TestProvidersComponent>
|
||||
<AddToExistingCase indicator={indicator} onClick={onClick} />
|
||||
<KibanaContext.Provider value={{ services: mockedServices } as any}>
|
||||
<AddToExistingCase indicator={indicator} onClick={onClick} />
|
||||
</KibanaContext.Provider>
|
||||
</TestProvidersComponent>
|
||||
);
|
||||
expect(component).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render the EuiContextMenuItem disabled', () => {
|
||||
const indicator: Indicator = generateMockFileIndicator();
|
||||
it('should render the EuiContextMenuItem disabled if indicator is missing name', () => {
|
||||
const mockedServices = {
|
||||
cases: {
|
||||
...casesServiceMock,
|
||||
helpers: {
|
||||
...casesServiceMock.helpers,
|
||||
canUseCases: () => ({
|
||||
create: true,
|
||||
update: true,
|
||||
}),
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const fields = { ...indicator.fields };
|
||||
delete fields['threat.indicator.name'];
|
||||
const indicatorMissingName = {
|
||||
_id: indicator._id,
|
||||
fields,
|
||||
};
|
||||
const onClick = () => window.alert('clicked');
|
||||
const component = render(
|
||||
<TestProvidersComponent>
|
||||
<AddToExistingCase indicator={indicatorMissingName} onClick={onClick} />
|
||||
<KibanaContext.Provider value={{ services: mockedServices } as any}>
|
||||
<AddToExistingCase indicator={indicatorMissingName} onClick={onClick} />
|
||||
</KibanaContext.Provider>
|
||||
</TestProvidersComponent>
|
||||
);
|
||||
expect(component).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render the EuiContextMenuItem disabled if user has no update permission', () => {
|
||||
const mockedServices = {
|
||||
cases: {
|
||||
...casesServiceMock,
|
||||
helpers: {
|
||||
...casesServiceMock.helpers,
|
||||
canUseCases: () => ({
|
||||
create: false,
|
||||
update: false,
|
||||
}),
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const component = render(
|
||||
<TestProvidersComponent>
|
||||
<KibanaContext.Provider value={{ services: mockedServices } as any}>
|
||||
<AddToExistingCase indicator={indicator} onClick={onClick} />
|
||||
</KibanaContext.Provider>
|
||||
</TestProvidersComponent>
|
||||
);
|
||||
expect(component).toMatchSnapshot();
|
||||
|
|
|
@ -9,7 +9,7 @@ import React, { VFC } from 'react';
|
|||
import { EuiContextMenuItem } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { CaseAttachmentsWithoutOwner } from '@kbn/cases-plugin/public';
|
||||
import { EMPTY_VALUE } from '../../../../common/constants';
|
||||
import { useCaseDisabled } from '../../hooks/use_case_permission';
|
||||
import {
|
||||
AttachmentMetadata,
|
||||
generateAttachmentsMetadata,
|
||||
|
@ -52,20 +52,18 @@ export const AddToExistingCase: VFC<AddToExistingCaseProps> = ({
|
|||
|
||||
const id: string = indicator._id as string;
|
||||
const attachmentMetadata: AttachmentMetadata = generateAttachmentsMetadata(indicator);
|
||||
|
||||
const attachments: CaseAttachmentsWithoutOwner = generateAttachmentsWithoutOwner(
|
||||
id,
|
||||
attachmentMetadata
|
||||
);
|
||||
|
||||
// disable the item if there isn't an indicator name
|
||||
// in the case's attachment, the indicator name is the link to open the flyout
|
||||
const disabled: boolean = attachmentMetadata.indicatorName === EMPTY_VALUE;
|
||||
|
||||
const menuItemClicked = () => {
|
||||
onClick();
|
||||
selectCaseModal.open({ attachments });
|
||||
};
|
||||
|
||||
const disabled: boolean = useCaseDisabled(attachmentMetadata.indicatorName);
|
||||
|
||||
return (
|
||||
<EuiContextMenuItem
|
||||
key="attachmentsExistingCase"
|
||||
|
|
|
@ -91,7 +91,100 @@ Object {
|
|||
}
|
||||
`;
|
||||
|
||||
exports[`AddToNewCase should render the EuiContextMenuItem disabled 1`] = `
|
||||
exports[`AddToNewCase should render the EuiContextMenuItem disabled if indicator is missing name 1`] = `
|
||||
Object {
|
||||
"asFragment": [Function],
|
||||
"baseElement": <body>
|
||||
<div>
|
||||
<button
|
||||
class="euiContextMenuItem euiContextMenuItem-isDisabled"
|
||||
disabled=""
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
class="euiContextMenu__itemLayout"
|
||||
>
|
||||
<span
|
||||
class="euiContextMenuItem__text"
|
||||
>
|
||||
Add to new case
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</body>,
|
||||
"container": <div>
|
||||
<button
|
||||
class="euiContextMenuItem euiContextMenuItem-isDisabled"
|
||||
disabled=""
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
class="euiContextMenu__itemLayout"
|
||||
>
|
||||
<span
|
||||
class="euiContextMenuItem__text"
|
||||
>
|
||||
Add to new case
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
</div>,
|
||||
"debug": [Function],
|
||||
"findAllByAltText": [Function],
|
||||
"findAllByDisplayValue": [Function],
|
||||
"findAllByLabelText": [Function],
|
||||
"findAllByPlaceholderText": [Function],
|
||||
"findAllByRole": [Function],
|
||||
"findAllByTestId": [Function],
|
||||
"findAllByText": [Function],
|
||||
"findAllByTitle": [Function],
|
||||
"findByAltText": [Function],
|
||||
"findByDisplayValue": [Function],
|
||||
"findByLabelText": [Function],
|
||||
"findByPlaceholderText": [Function],
|
||||
"findByRole": [Function],
|
||||
"findByTestId": [Function],
|
||||
"findByText": [Function],
|
||||
"findByTitle": [Function],
|
||||
"getAllByAltText": [Function],
|
||||
"getAllByDisplayValue": [Function],
|
||||
"getAllByLabelText": [Function],
|
||||
"getAllByPlaceholderText": [Function],
|
||||
"getAllByRole": [Function],
|
||||
"getAllByTestId": [Function],
|
||||
"getAllByText": [Function],
|
||||
"getAllByTitle": [Function],
|
||||
"getByAltText": [Function],
|
||||
"getByDisplayValue": [Function],
|
||||
"getByLabelText": [Function],
|
||||
"getByPlaceholderText": [Function],
|
||||
"getByRole": [Function],
|
||||
"getByTestId": [Function],
|
||||
"getByText": [Function],
|
||||
"getByTitle": [Function],
|
||||
"queryAllByAltText": [Function],
|
||||
"queryAllByDisplayValue": [Function],
|
||||
"queryAllByLabelText": [Function],
|
||||
"queryAllByPlaceholderText": [Function],
|
||||
"queryAllByRole": [Function],
|
||||
"queryAllByTestId": [Function],
|
||||
"queryAllByText": [Function],
|
||||
"queryAllByTitle": [Function],
|
||||
"queryByAltText": [Function],
|
||||
"queryByDisplayValue": [Function],
|
||||
"queryByLabelText": [Function],
|
||||
"queryByPlaceholderText": [Function],
|
||||
"queryByRole": [Function],
|
||||
"queryByTestId": [Function],
|
||||
"queryByText": [Function],
|
||||
"queryByTitle": [Function],
|
||||
"rerender": [Function],
|
||||
"unmount": [Function],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`AddToNewCase should render the EuiContextMenuItem disabled if user have no create permission 1`] = `
|
||||
Object {
|
||||
"asFragment": [Function],
|
||||
"baseElement": <body>
|
||||
|
|
|
@ -5,35 +5,93 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { KibanaContext } from '../../../../hooks';
|
||||
import { render } from '@testing-library/react';
|
||||
import React from 'react';
|
||||
import { generateMockFileIndicator, Indicator } from '../../../../../common/types/indicator';
|
||||
import { TestProvidersComponent } from '../../../../common/mocks/test_providers';
|
||||
import { AddToNewCase } from './add_to_new_case';
|
||||
import { casesPluginMock } from '@kbn/cases-plugin/public/mocks';
|
||||
|
||||
const indicator: Indicator = generateMockFileIndicator();
|
||||
const onClick = () => window.alert('clicked');
|
||||
const casesServiceMock = casesPluginMock.createStartContract();
|
||||
|
||||
describe('AddToNewCase', () => {
|
||||
it('should render an EuiContextMenuItem', () => {
|
||||
const indicator: Indicator = generateMockFileIndicator();
|
||||
const onClick = () => window.alert('clicked');
|
||||
const mockedServices = {
|
||||
cases: {
|
||||
...casesServiceMock,
|
||||
helpers: {
|
||||
...casesServiceMock.helpers,
|
||||
canUseCases: () => ({
|
||||
create: true,
|
||||
update: true,
|
||||
}),
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const component = render(
|
||||
<TestProvidersComponent>
|
||||
<AddToNewCase indicator={indicator} onClick={onClick} />
|
||||
<KibanaContext.Provider value={{ services: mockedServices } as any}>
|
||||
<AddToNewCase indicator={indicator} onClick={onClick} />
|
||||
</KibanaContext.Provider>
|
||||
</TestProvidersComponent>
|
||||
);
|
||||
expect(component).toMatchSnapshot();
|
||||
});
|
||||
it('should render the EuiContextMenuItem disabled', () => {
|
||||
const indicator: Indicator = generateMockFileIndicator();
|
||||
|
||||
it('should render the EuiContextMenuItem disabled if indicator is missing name', () => {
|
||||
const mockedServices = {
|
||||
cases: {
|
||||
...casesServiceMock,
|
||||
helpers: {
|
||||
...casesServiceMock.helpers,
|
||||
canUseCases: () => ({
|
||||
create: true,
|
||||
update: true,
|
||||
}),
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const fields = { ...indicator.fields };
|
||||
delete fields['threat.indicator.name'];
|
||||
const indicatorMissingName = {
|
||||
_id: indicator._id,
|
||||
fields,
|
||||
};
|
||||
const onClick = () => window.alert('clicked');
|
||||
|
||||
const component = render(
|
||||
<TestProvidersComponent>
|
||||
<AddToNewCase indicator={indicatorMissingName} onClick={onClick} />
|
||||
<KibanaContext.Provider value={{ services: mockedServices } as any}>
|
||||
<AddToNewCase indicator={indicatorMissingName} onClick={onClick} />
|
||||
</KibanaContext.Provider>
|
||||
</TestProvidersComponent>
|
||||
);
|
||||
expect(component).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should render the EuiContextMenuItem disabled if user have no create permission', () => {
|
||||
const mockedServices = {
|
||||
cases: {
|
||||
...casesServiceMock,
|
||||
helpers: {
|
||||
...casesServiceMock.helpers,
|
||||
canUseCases: () => ({
|
||||
create: false,
|
||||
update: false,
|
||||
}),
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const component = render(
|
||||
<TestProvidersComponent>
|
||||
<KibanaContext.Provider value={{ services: mockedServices } as any}>
|
||||
<AddToNewCase indicator={indicator} onClick={onClick} />
|
||||
</KibanaContext.Provider>
|
||||
</TestProvidersComponent>
|
||||
);
|
||||
expect(component).toMatchSnapshot();
|
||||
|
|
|
@ -9,7 +9,7 @@ import React, { VFC } from 'react';
|
|||
import { EuiContextMenuItem } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { CaseAttachmentsWithoutOwner } from '@kbn/cases-plugin/public';
|
||||
import { EMPTY_VALUE } from '../../../../common/constants';
|
||||
import { useCaseDisabled } from '../../hooks/use_case_permission';
|
||||
import {
|
||||
AttachmentMetadata,
|
||||
generateAttachmentsMetadata,
|
||||
|
@ -52,20 +52,18 @@ export const AddToNewCase: VFC<AddToNewCaseProps> = ({
|
|||
|
||||
const id: string = indicator._id as string;
|
||||
const attachmentMetadata: AttachmentMetadata = generateAttachmentsMetadata(indicator);
|
||||
|
||||
const attachments: CaseAttachmentsWithoutOwner = generateAttachmentsWithoutOwner(
|
||||
id,
|
||||
attachmentMetadata
|
||||
);
|
||||
|
||||
// disable the item if there isn't an indicator name
|
||||
// in the case's attachment, the indicator name is the link to open the flyout
|
||||
const disabled: boolean = attachmentMetadata.indicatorName === EMPTY_VALUE;
|
||||
|
||||
const menuItemClicked = () => {
|
||||
onClick();
|
||||
createCaseFlyout.open({ attachments });
|
||||
};
|
||||
|
||||
const disabled: boolean = useCaseDisabled(attachmentMetadata.indicatorName);
|
||||
|
||||
return (
|
||||
<EuiContextMenuItem
|
||||
key="attachmentsNewCase"
|
||||
|
|
|
@ -24,3 +24,7 @@ export const initComponent = () => {
|
|||
return <CommentChildren id={indicatorId} metadata={metadata} />;
|
||||
};
|
||||
};
|
||||
|
||||
// Note: This is for lazy loading
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default initComponent();
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* 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, { FC, ReactNode } from 'react';
|
||||
import { Renderer, renderHook, RenderHookResult } from '@testing-library/react-hooks';
|
||||
import { casesPluginMock } from '@kbn/cases-plugin/public/mocks';
|
||||
import { KibanaContext } from '../../../hooks/use_kibana';
|
||||
import { useCaseDisabled } from './use_case_permission';
|
||||
import { TestProvidersComponent } from '../../../common/mocks/test_providers';
|
||||
import { EMPTY_VALUE } from '../../../common/constants';
|
||||
|
||||
const casesServiceMock = casesPluginMock.createStartContract();
|
||||
|
||||
const getProviderComponent =
|
||||
(mockedServices: unknown) =>
|
||||
({ children }: { children: ReactNode }) =>
|
||||
(
|
||||
<TestProvidersComponent>
|
||||
<KibanaContext.Provider value={{ services: mockedServices } as any}>
|
||||
{children}
|
||||
</KibanaContext.Provider>
|
||||
</TestProvidersComponent>
|
||||
);
|
||||
|
||||
describe('useCasePermission', () => {
|
||||
let hookResult: RenderHookResult<{}, boolean, Renderer<unknown>>;
|
||||
|
||||
it('should return false if user has correct permissions and indicator has a name', () => {
|
||||
const mockedServices = {
|
||||
cases: {
|
||||
...casesServiceMock,
|
||||
helpers: {
|
||||
...casesServiceMock.helpers,
|
||||
canUseCases: () => ({
|
||||
create: true,
|
||||
update: true,
|
||||
}),
|
||||
},
|
||||
},
|
||||
};
|
||||
// @ts-ignore
|
||||
const ProviderComponent: FC = getProviderComponent(mockedServices);
|
||||
|
||||
const indicatorName: string = 'abc';
|
||||
|
||||
hookResult = renderHook(() => useCaseDisabled(indicatorName), {
|
||||
wrapper: ProviderComponent,
|
||||
});
|
||||
expect(hookResult.result.current).toEqual(false);
|
||||
});
|
||||
|
||||
it(`should return true if user doesn't have correct permissions`, () => {
|
||||
const mockedServices = {
|
||||
cases: {
|
||||
...casesServiceMock,
|
||||
helpers: {
|
||||
...casesServiceMock.helpers,
|
||||
canUseCases: () => ({
|
||||
create: false,
|
||||
update: true,
|
||||
}),
|
||||
},
|
||||
},
|
||||
};
|
||||
// @ts-ignore
|
||||
const ProviderComponent: FC = getProviderComponent(mockedServices);
|
||||
|
||||
const indicatorName: string = 'abc';
|
||||
|
||||
hookResult = renderHook(() => useCaseDisabled(indicatorName), {
|
||||
wrapper: ProviderComponent,
|
||||
});
|
||||
expect(hookResult.result.current).toEqual(true);
|
||||
});
|
||||
|
||||
it('should return true if indicator name is missing or empty', () => {
|
||||
const mockedServices = {
|
||||
cases: {
|
||||
...casesServiceMock,
|
||||
helpers: {
|
||||
...casesServiceMock.helpers,
|
||||
canUseCases: () => ({
|
||||
create: true,
|
||||
update: true,
|
||||
}),
|
||||
},
|
||||
},
|
||||
};
|
||||
// @ts-ignore
|
||||
const ProviderComponent: FC = getProviderComponent(mockedServices);
|
||||
|
||||
const indicatorName: string = EMPTY_VALUE;
|
||||
|
||||
hookResult = renderHook(() => useCaseDisabled(indicatorName), {
|
||||
wrapper: ProviderComponent,
|
||||
});
|
||||
expect(hookResult.result.current).toEqual(true);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* 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 { CasesPermissions } from '@kbn/cases-plugin/common';
|
||||
import { EMPTY_VALUE } from '../../../common/constants';
|
||||
import { useKibana } from '../../../hooks';
|
||||
|
||||
/**
|
||||
* Decides if we enable or disable the add to existing and add to new case features.
|
||||
* If the Indicator has no name the features will be disabled.
|
||||
* If the user doesn't have the correct permissions the features will be disabled.
|
||||
*
|
||||
* @param indicatorName the name of the indicator
|
||||
* @return true if the features are enabled
|
||||
*/
|
||||
export const useCaseDisabled = (indicatorName: string): boolean => {
|
||||
const { cases } = useKibana().services;
|
||||
const permissions: CasesPermissions = cases.helpers.canUseCases();
|
||||
|
||||
// disable the item if there is no indicator name or if the user doesn't have the right permission
|
||||
// in the case's attachment, the indicator name is the link to open the flyout
|
||||
const invalidIndicatorName: boolean = indicatorName === EMPTY_VALUE;
|
||||
const hasPermission: boolean = permissions.create && permissions.update;
|
||||
|
||||
return invalidIndicatorName || !hasPermission;
|
||||
};
|
|
@ -48,9 +48,9 @@ describe('generateAttachmentsMetadata', () => {
|
|||
const result = generateAttachmentsMetadata(indicator);
|
||||
|
||||
expect(result).toEqual({
|
||||
indicatorName: '',
|
||||
indicatorType: '',
|
||||
indicatorFeedName: '',
|
||||
indicatorName: '-',
|
||||
indicatorType: '-',
|
||||
indicatorFeedName: '-',
|
||||
});
|
||||
});
|
||||
|
|
@ -28,6 +28,10 @@ export interface AttachmentMetadata {
|
|||
indicatorFeedName: string;
|
||||
}
|
||||
|
||||
const AttachmentChildrenLazy = React.lazy(
|
||||
() => import('../components/attachment_children/attachment_children')
|
||||
);
|
||||
|
||||
/**
|
||||
* Create an {@link ExternalReferenceAttachmentType} object used to register an external reference
|
||||
* to the case plugin with our Threat Intelligence plugin initializes.
|
||||
|
@ -49,14 +53,7 @@ export const generateAttachmentType = (): ExternalReferenceAttachmentType => ({
|
|||
/>
|
||||
),
|
||||
timelineAvatar: <EuiAvatar name="indicator" color="subdued" iconType="crosshairs" />,
|
||||
children: React.lazy(async () => {
|
||||
const { initComponent } = await import(
|
||||
'../components/attachment_children/attachment_children'
|
||||
);
|
||||
return {
|
||||
default: initComponent(),
|
||||
};
|
||||
}),
|
||||
children: AttachmentChildrenLazy,
|
||||
}),
|
||||
icon: 'crosshairs',
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue