From 36515713a69f6021db8b959b95f7a8ff851b0aa7 Mon Sep 17 00:00:00 2001 From: Michael Olorunnisola Date: Tue, 7 Nov 2023 12:01:23 -0500 Subject: [PATCH] [Security Solution][Investigations] - Add check for changing alert status from bulk options (#170584) ## Summary Addresses https://github.com/elastic/kibana/issues/169684 This PR is a re-do of: https://github.com/elastic/kibana/pull/169723 (With cypress tests currently skipped until proper role is available). The alert privileges needs to be added for the alert table as it wasn't added when the migration took place. An example of the privileges elsewhere is below: https://github.com/elastic/kibana/blob/75e9d46b4b3a6ff5be4ffc324ba282cea0faea0c/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_alerts_actions.tsx#L33 Fix: https://github.com/elastic/kibana/assets/17211684/7b354906-9b96-4ba8-b30f-4080cf7e7c2f --------- Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../use_bulk_alert_tags_items.test.tsx | 6 +++ .../use_bulk_alert_tags_items.tsx | 49 ++++++++++++------- .../use_alert_actions.tsx | 10 ++-- .../detection_alerts/alert_status.cy.ts | 46 +++++++++++++++-- 4 files changed, 84 insertions(+), 27 deletions(-) diff --git a/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_bulk_alert_tags_items.test.tsx b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_bulk_alert_tags_items.test.tsx index 3cbc54cf24f12..c49e1cf133dd4 100644 --- a/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_bulk_alert_tags_items.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_bulk_alert_tags_items.test.tsx @@ -19,6 +19,12 @@ import { useUiSetting$ } from '../../../lib/kibana'; jest.mock('./use_set_alert_tags'); jest.mock('../../../lib/kibana'); +jest.mock( + '../../../../detections/containers/detection_engine/alerts/use_alerts_privileges', + () => ({ + useAlertsPrivileges: jest.fn().mockReturnValue({ hasIndexWrite: true }), + }) +); const defaultProps: UseBulkAlertTagsItemsProps = { refetch: () => {}, diff --git a/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_bulk_alert_tags_items.tsx b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_bulk_alert_tags_items.tsx index df4d5c37aeeaf..977cb0bf8b315 100644 --- a/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_bulk_alert_tags_items.tsx +++ b/x-pack/plugins/security_solution/public/common/components/toolbar/bulk_actions/use_bulk_alert_tags_items.tsx @@ -8,6 +8,7 @@ import { EuiFlexGroup, EuiIconTip, EuiFlexItem } from '@elastic/eui'; import type { RenderContentPanelProps } from '@kbn/triggers-actions-ui-plugin/public/types'; import React, { useCallback, useMemo } from 'react'; +import { useAlertsPrivileges } from '../../../../detections/containers/detection_engine/alerts/use_alerts_privileges'; import { BulkAlertTagsPanel } from './alert_bulk_tags'; import * as i18n from './translations'; import { useSetAlertTags } from './use_set_alert_tags'; @@ -24,6 +25,7 @@ export interface UseBulkAlertTagsPanel { } export const useBulkAlertTagsItems = ({ refetch }: UseBulkAlertTagsItemsProps) => { + const { hasIndexWrite } = useAlertsPrivileges(); const setAlertTags = useSetAlertTags(); const handleOnAlertTagsSubmit = useCallback( async (tags, ids, onSuccess, setIsLoading) => { @@ -34,16 +36,22 @@ export const useBulkAlertTagsItems = ({ refetch }: UseBulkAlertTagsItemsProps) = [setAlertTags] ); - const alertTagsItems = [ - { - key: 'manage-alert-tags', - 'data-test-subj': 'alert-tags-context-menu-item', - name: i18n.ALERT_TAGS_CONTEXT_MENU_ITEM_TITLE, - panel: 1, - label: i18n.ALERT_TAGS_CONTEXT_MENU_ITEM_TITLE, - disableOnQuery: true, - }, - ]; + const alertTagsItems = useMemo( + () => + hasIndexWrite + ? [ + { + key: 'manage-alert-tags', + 'data-test-subj': 'alert-tags-context-menu-item', + name: i18n.ALERT_TAGS_CONTEXT_MENU_ITEM_TITLE, + panel: 1, + label: i18n.ALERT_TAGS_CONTEXT_MENU_ITEM_TITLE, + disableOnQuery: true, + }, + ] + : [], + [hasIndexWrite] + ); const TitleContent = useMemo( () => ( @@ -79,15 +87,18 @@ export const useBulkAlertTagsItems = ({ refetch }: UseBulkAlertTagsItemsProps) = ); const alertTagsPanels: UseBulkAlertTagsPanel[] = useMemo( - () => [ - { - id: 1, - title: TitleContent, - 'data-test-subj': 'alert-tags-context-menu-panel', - renderContent, - }, - ], - [TitleContent, renderContent] + () => + hasIndexWrite + ? [ + { + id: 1, + title: TitleContent, + 'data-test-subj': 'alert-tags-context-menu-panel', + renderContent, + }, + ] + : [], + [TitleContent, hasIndexWrite, renderContent] ); return { diff --git a/x-pack/plugins/security_solution/public/detections/hooks/trigger_actions_alert_table/use_alert_actions.tsx b/x-pack/plugins/security_solution/public/detections/hooks/trigger_actions_alert_table/use_alert_actions.tsx index 5ac7628f5376f..decc2cb159b5c 100644 --- a/x-pack/plugins/security_solution/public/detections/hooks/trigger_actions_alert_table/use_alert_actions.tsx +++ b/x-pack/plugins/security_solution/public/detections/hooks/trigger_actions_alert_table/use_alert_actions.tsx @@ -19,6 +19,7 @@ import type { AlertWorkflowStatus } from '../../../common/types'; import { FILTER_CLOSED, FILTER_OPEN, FILTER_ACKNOWLEDGED } from '../../../../common/types'; import * as i18n from '../translations'; import { buildTimeRangeFilter } from '../../components/alerts_table/helpers'; +import { useAlertsPrivileges } from '../../containers/detection_engine/alerts/use_alerts_privileges'; interface UseBulkAlertActionItemsArgs { /* Table ID for which this hook is being used */ @@ -41,6 +42,7 @@ export const useBulkAlertActionItems = ({ to, refetch: refetchProp, }: UseBulkAlertActionItemsArgs) => { + const { hasIndexWrite } = useAlertsPrivileges(); const { startTransaction } = useStartTransaction(); const { addSuccess, addError, addWarning } = useAppToasts(); @@ -172,7 +174,9 @@ export const useBulkAlertActionItems = ({ [getOnAction] ); - return [FILTER_OPEN, FILTER_CLOSED, FILTER_ACKNOWLEDGED].map((status) => - getUpdateAlertStatusAction(status as AlertWorkflowStatus) - ); + return hasIndexWrite + ? [FILTER_OPEN, FILTER_CLOSED, FILTER_ACKNOWLEDGED].map((status) => + getUpdateAlertStatusAction(status as AlertWorkflowStatus) + ) + : []; }; diff --git a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/detection_alerts/alert_status.cy.ts b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/detection_alerts/alert_status.cy.ts index ca90e9b72efd1..c55c8f62dc4a9 100644 --- a/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/detection_alerts/alert_status.cy.ts +++ b/x-pack/test/security_solution_cypress/cypress/e2e/detection_response/detection_alerts/alert_status.cy.ts @@ -5,8 +5,16 @@ * 2.0. */ +import { ROLES } from '@kbn/security-solution-plugin/common/test'; import { getNewRule } from '../../../objects/rule'; -import { ALERTS_COUNT, SELECTED_ALERTS } from '../../../screens/alerts'; +import { + ALERTS_COUNT, + CLOSE_SELECTED_ALERTS_BTN, + MARK_ALERT_ACKNOWLEDGED_BTN, + SELECTED_ALERTS, + TAKE_ACTION_POPOVER_BTN, + TIMELINE_CONTEXT_MENU_BTN, +} from '../../../screens/alerts'; import { selectNumberOfAlerts, @@ -30,12 +38,12 @@ import { visit } from '../../../tasks/navigation'; import { ALERTS_URL } from '../../../urls/navigation'; // FLAKY: https://github.com/elastic/kibana/issues/169091 -describe('Changing alert status', { tags: ['@ess', '@serverless'] }, () => { +describe('Changing alert status', () => { before(() => { cy.task('esArchiverLoad', { archiveName: 'auditbeat_big' }); }); - context('Opening alerts', () => { + context('Opening alerts', { tags: ['@ess', '@serverless'] }, () => { beforeEach(() => { login(); deleteAlertsAndRules(); @@ -116,7 +124,7 @@ describe('Changing alert status', { tags: ['@ess', '@serverless'] }, () => { }); }); - context('Marking alerts as acknowledged', () => { + context('Marking alerts as acknowledged', { tags: ['@ess', '@serverless'] }, () => { beforeEach(() => { login(); deleteAlertsAndRules(); @@ -167,7 +175,7 @@ describe('Changing alert status', { tags: ['@ess', '@serverless'] }, () => { }); }); - context('Closing alerts', () => { + context('Closing alerts', { tags: ['@ess', '@serverless'] }, () => { beforeEach(() => { login(); deleteAlertsAndRules(); @@ -228,4 +236,32 @@ describe('Changing alert status', { tags: ['@ess', '@serverless'] }, () => { }); }); }); + + // This test is unable to be run in serverless as `reader` is not available and viewer is currently reserved + // https://github.com/elastic/kibana/pull/169723#issuecomment-1793191007 + // https://github.com/elastic/kibana/issues/170583 + context('User is readonly', { tags: ['@ess', '@brokenInServerless'] }, () => { + beforeEach(() => { + login(); + visit(ALERTS_URL); + deleteAlertsAndRules(); + createRule(getNewRule()); + login(ROLES.reader); + visit(ALERTS_URL, { role: ROLES.reader }); + waitForAlertsToPopulate(); + }); + it('should not allow users to change a single alert status', () => { + // This is due to the reader role which makes everything in security 'read only' + cy.get(TIMELINE_CONTEXT_MENU_BTN).should('not.exist'); + }); + + it('should not allow users to bulk change the alert status', () => { + selectNumberOfAlerts(2); + cy.get(TAKE_ACTION_POPOVER_BTN).first().click(); + cy.get(TAKE_ACTION_POPOVER_BTN).should('be.visible'); + + cy.get(CLOSE_SELECTED_ALERTS_BTN).should('not.exist'); + cy.get(MARK_ALERT_ACKNOWLEDGED_BTN).should('not.exist'); + }); + }); });