Skip to content

Commit

Permalink
[Security Solution][Exceptions] - Update exceptions tab privileges ch…
Browse files Browse the repository at this point in the history
…ecks (#122902) (#123305)

### Summary

Addresses #122227.

(cherry picked from commit fc64d17)

Co-authored-by: Yara Tercero <[email protected]>
  • Loading branch information
kibanamachine and yctercero authored Jan 18, 2022
1 parent 8f656e9 commit d47fe31
Show file tree
Hide file tree
Showing 17 changed files with 196 additions and 82 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ export const getReadPrivilegeMock = (
manage_index_templates: booleanValues,
manage_ingest_pipelines: booleanValues,
manage_ml: booleanValues,
manage_own_api_key: false,
manage_own_api_key: booleanValues,
manage_pipeline: booleanValues,
manage_rollup: booleanValues,
manage_saml: booleanValues,
Expand All @@ -105,7 +105,7 @@ export const getReadPrivilegeMock = (
read_ilm: booleanValues,
transport_client: booleanValues,
},
has_all_requested: false,
has_all_requested: booleanValues,
index: {
[listItemsIndex]: {
all: booleanValues,
Expand Down Expand Up @@ -141,7 +141,7 @@ export const getReadPrivilegeMock = (
manage_index_templates: booleanValues,
manage_ingest_pipelines: booleanValues,
manage_ml: booleanValues,
manage_own_api_key: false,
manage_own_api_key: booleanValues,
manage_pipeline: booleanValues,
manage_rollup: booleanValues,
manage_saml: booleanValues,
Expand All @@ -158,7 +158,7 @@ export const getReadPrivilegeMock = (
read_ilm: booleanValues,
transport_client: booleanValues,
},
has_all_requested: false,
has_all_requested: booleanValues,
index: {
[listIndex]: {
all: booleanValues,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { login, loginAndWaitForPage, waitForPageWithoutDateRange } from '../../t
import { refreshPage } from '../../tasks/security_header';

import { ALERTS_URL } from '../../urls/navigation';
import { ATTACH_ALERT_TO_CASE_BUTTON } from '../../screens/alerts';
import { ATTACH_ALERT_TO_CASE_BUTTON, TIMELINE_CONTEXT_MENU_BTN } from '../../screens/alerts';

const loadDetectionsPage = (role: ROLES) => {
waitForPageWithoutDateRange(ALERTS_URL, role);
Expand Down Expand Up @@ -48,8 +48,8 @@ describe('Alerts timeline', () => {
});

it('should not allow user with read only privileges to attach alerts to cases', () => {
expandFirstAlertActions();
cy.get(ATTACH_ALERT_TO_CASE_BUTTON).should('not.exist');
// Disabled actions for read only users are hidden, so actions button should not show
cy.get(TIMELINE_CONTEXT_MENU_BTN).should('not.exist');
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ describe('ExceptionEntries', () => {
const wrapper = mount(
<ThemeProvider theme={mockTheme}>
<ExceptionEntries
disableDelete={false}
disableActions={false}
entries={[getFormattedEntryMock()]}
onDelete={jest.fn()}
onEdit={jest.fn()}
Expand All @@ -38,7 +38,7 @@ describe('ExceptionEntries', () => {
const wrapper = mount(
<ThemeProvider theme={mockTheme}>
<ExceptionEntries
disableDelete={false}
disableActions={false}
entries={[getFormattedEntryMock(), getFormattedEntryMock()]}
onDelete={jest.fn()}
onEdit={jest.fn()}
Expand All @@ -54,7 +54,7 @@ describe('ExceptionEntries', () => {
const wrapper = mount(
<ThemeProvider theme={mockTheme}>
<ExceptionEntries
disableDelete={false}
disableActions={false}
entries={[getFormattedEntryMock()]}
onDelete={jest.fn()}
onEdit={mockOnEdit}
Expand All @@ -72,7 +72,7 @@ describe('ExceptionEntries', () => {
const wrapper = mount(
<ThemeProvider theme={mockTheme}>
<ExceptionEntries
disableDelete={false}
disableActions={false}
entries={[getFormattedEntryMock()]}
onDelete={mockOnDelete}
onEdit={jest.fn()}
Expand All @@ -85,37 +85,36 @@ describe('ExceptionEntries', () => {
expect(mockOnDelete).toHaveBeenCalledTimes(1);
});

test('it renders edit button disabled if "disableDelete" is "true"', () => {
test('it does not render edit button if "disableActions" is "true"', () => {
const wrapper = mount(
<ThemeProvider theme={mockTheme}>
<ExceptionEntries
disableDelete={true}
disableActions={true}
entries={[getFormattedEntryMock()]}
onDelete={jest.fn()}
onEdit={jest.fn()}
/>
</ThemeProvider>
);
const editBtn = wrapper.find('[data-test-subj="exceptionsViewerEditBtn"] button').at(0);
const editBtns = wrapper.find('[data-test-subj="exceptionsViewerEditBtn"] button');

expect(editBtn.prop('disabled')).toBeTruthy();
expect(editBtns).toHaveLength(0);
});

test('it renders delete button in loading state if "disableDelete" is "true"', () => {
test('it does not render delete button if "disableActions" is "true"', () => {
const wrapper = mount(
<ThemeProvider theme={mockTheme}>
<ExceptionEntries
disableDelete={true}
disableActions={true}
entries={[getFormattedEntryMock()]}
onDelete={jest.fn()}
onEdit={jest.fn()}
/>
</ThemeProvider>
);
const deleteBtn = wrapper.find('[data-test-subj="exceptionsViewerDeleteBtn"] button').at(0);
const deleteBtns = wrapper.find('[data-test-subj="exceptionsViewerDeleteBtn"] button').at(0);

expect(deleteBtn.prop('disabled')).toBeTruthy();
expect(deleteBtn.find('.euiLoadingSpinner')).toBeTruthy();
expect(deleteBtns).toHaveLength(0);
});

test('it renders nested entry', () => {
Expand All @@ -126,7 +125,7 @@ describe('ExceptionEntries', () => {
const wrapper = mount(
<ThemeProvider theme={mockTheme}>
<ExceptionEntries
disableDelete={false}
disableActions={false}
entries={[parentEntry, getFormattedEntryMock(true)]}
onDelete={jest.fn()}
onEdit={jest.fn()}
Expand Down Expand Up @@ -168,7 +167,7 @@ describe('ExceptionEntries', () => {
const wrapper = mount(
<ThemeProvider theme={mockTheme}>
<ExceptionEntries
disableDelete={false}
disableActions={false}
entries={[getFormattedEntryMock()]}
onDelete={jest.fn()}
onEdit={jest.fn()}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,14 @@ const ValueBadgeGroup = styled(EuiBadgeGroup)`

interface ExceptionEntriesComponentProps {
entries: FormattedEntry[];
disableDelete: boolean;
disableActions: boolean;
onDelete: () => void;
onEdit: () => void;
}

const ExceptionEntriesComponent = ({
entries,
disableDelete,
disableActions,
onDelete,
onEdit,
}: ExceptionEntriesComponentProps): JSX.Element => {
Expand Down Expand Up @@ -181,32 +181,32 @@ const ExceptionEntriesComponent = ({
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
<EuiFlexItem grow={1}>
<EuiFlexGroup gutterSize="s" justifyContent="flexEnd">
<MyActionButton grow={false}>
<MyEditButton
size="s"
color="primary"
onClick={onEdit}
isDisabled={disableDelete}
data-test-subj="exceptionsViewerEditBtn"
>
{i18n.EDIT}
</MyEditButton>
</MyActionButton>
<MyActionButton grow={false}>
<MyRemoveButton
size="s"
color="danger"
onClick={onDelete}
isLoading={disableDelete}
data-test-subj="exceptionsViewerDeleteBtn"
>
{i18n.REMOVE}
</MyRemoveButton>
</MyActionButton>
</EuiFlexGroup>
</EuiFlexItem>
{!disableActions && (
<EuiFlexItem grow={1}>
<EuiFlexGroup gutterSize="s" justifyContent="flexEnd">
<MyActionButton grow={false}>
<MyEditButton
size="s"
color="primary"
onClick={onEdit}
data-test-subj="exceptionsViewerEditBtn"
>
{i18n.EDIT}
</MyEditButton>
</MyActionButton>
<MyActionButton grow={false}>
<MyRemoveButton
size="s"
color="danger"
onClick={onDelete}
data-test-subj="exceptionsViewerDeleteBtn"
>
{i18n.REMOVE}
</MyRemoveButton>
</MyActionButton>
</EuiFlexGroup>
</EuiFlexItem>
)}
</EuiFlexGroup>
</MyEntriesDetails>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ storiesOf('Components/ExceptionItem', module)

return (
<ExceptionItem
disableActions={false}
loadingItemIds={[]}
commentsAccordionId={'accordion--comments'}
exceptionItem={payload}
Expand All @@ -57,6 +58,7 @@ storiesOf('Components/ExceptionItem', module)

return (
<ExceptionItem
disableActions={false}
loadingItemIds={[]}
commentsAccordionId={'accordion--comments'}
exceptionItem={payload}
Expand All @@ -80,6 +82,7 @@ storiesOf('Components/ExceptionItem', module)

return (
<ExceptionItem
disableActions={false}
loadingItemIds={[]}
commentsAccordionId={'accordion--comments'}
exceptionItem={payload}
Expand All @@ -95,6 +98,7 @@ storiesOf('Components/ExceptionItem', module)

return (
<ExceptionItem
disableActions={false}
loadingItemIds={[]}
commentsAccordionId={'accordion--comments'}
exceptionItem={payload}
Expand All @@ -108,6 +112,7 @@ storiesOf('Components/ExceptionItem', module)
payload.comments = getCommentsArrayMock();
return (
<ExceptionItem
disableActions={false}
loadingItemIds={[]}
commentsAccordionId={'accordion--comments'}
exceptionItem={payload}
Expand All @@ -122,11 +127,36 @@ storiesOf('Components/ExceptionItem', module)

return (
<ExceptionItem
disableActions={false}
loadingItemIds={[{ id, namespaceType: namespace_type }]}
commentsAccordionId={'accordion--comments'}
exceptionItem={{ id, namespace_type, ...rest }}
onDeleteException={action('onClick')}
onEditException={action('onClick')}
/>
);
})
.add('with actions disabled', () => {
const payload = getExceptionListItemSchemaMock();
payload.description = '';
payload.comments = getCommentsArrayMock();
payload.entries = [
{
field: 'actingProcess.file.signer',
type: 'match',
operator: 'included',
value: 'Elastic, N.V.',
},
];

return (
<ExceptionItem
disableActions
loadingItemIds={[]}
commentsAccordionId={'accordion--comments'}
exceptionItem={payload}
onDeleteException={action('onClick')}
onEditException={action('onClick')}
/>
);
});
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ describe('ExceptionItem', () => {
const wrapper = mount(
<ThemeProvider theme={mockTheme}>
<ExceptionItem
disableActions={false}
loadingItemIds={[]}
commentsAccordionId={'accordion--comments'}
onDeleteException={jest.fn()}
Expand All @@ -51,6 +52,7 @@ describe('ExceptionItem', () => {
const wrapper = mount(
<ThemeProvider theme={mockTheme}>
<ExceptionItem
disableActions={false}
loadingItemIds={[]}
commentsAccordionId={'accordion--comments'}
onDeleteException={jest.fn()}
Expand All @@ -70,13 +72,38 @@ describe('ExceptionItem', () => {
);
});

it('it does not render edit or delete action buttons when "disableActions" is "true"', () => {
const mockOnEditException = jest.fn();
const exceptionItem = getExceptionListItemSchemaMock();

const wrapper = mount(
<ThemeProvider theme={mockTheme}>
<ExceptionItem
disableActions
loadingItemIds={[]}
commentsAccordionId={'accordion--comments'}
onDeleteException={jest.fn()}
onEditException={mockOnEditException}
exceptionItem={exceptionItem}
/>
</ThemeProvider>
);

const editBtn = wrapper.find('[data-test-subj="exceptionsViewerEditBtn"] button');
const deleteBtn = wrapper.find('[data-test-subj="exceptionsViewerDeleteBtn"] button');

expect(editBtn).toHaveLength(0);
expect(deleteBtn).toHaveLength(0);
});

it('it invokes "onEditException" when edit button clicked', () => {
const mockOnEditException = jest.fn();
const exceptionItem = getExceptionListItemSchemaMock();

const wrapper = mount(
<ThemeProvider theme={mockTheme}>
<ExceptionItem
disableActions={false}
loadingItemIds={[]}
commentsAccordionId={'accordion--comments'}
onDeleteException={jest.fn()}
Expand All @@ -99,6 +126,7 @@ describe('ExceptionItem', () => {
const wrapper = mount(
<ThemeProvider theme={mockTheme}>
<ExceptionItem
disableActions={false}
loadingItemIds={[]}
commentsAccordionId={'accordion--comments'}
onDeleteException={mockOnDeleteException}
Expand All @@ -108,8 +136,8 @@ describe('ExceptionItem', () => {
</ThemeProvider>
);

const editBtn = wrapper.find('[data-test-subj="exceptionsViewerDeleteBtn"] button').at(0);
editBtn.simulate('click');
const deleteBtn = wrapper.find('[data-test-subj="exceptionsViewerDeleteBtn"] button').at(0);
deleteBtn.simulate('click');

expect(mockOnDeleteException).toHaveBeenCalledWith({
id: '1',
Expand All @@ -124,6 +152,7 @@ describe('ExceptionItem', () => {
const wrapper = mount(
<ThemeProvider theme={mockTheme}>
<ExceptionItem
disableActions={false}
loadingItemIds={[]}
commentsAccordionId={'accordion--comments'}
onDeleteException={mockOnDeleteException}
Expand All @@ -143,6 +172,7 @@ describe('ExceptionItem', () => {
const wrapper = mount(
<ThemeProvider theme={mockTheme}>
<ExceptionItem
disableActions={false}
loadingItemIds={[]}
commentsAccordionId={'accordion--comments'}
onDeleteException={mockOnDeleteException}
Expand Down
Loading

0 comments on commit d47fe31

Please sign in to comment.