From affbed7a161ae5b41d4dde8264b597b7c21f453e Mon Sep 17 00:00:00 2001 From: Davis Plumlee <56367316+dplumlee@users.noreply.github.com> Date: Thu, 10 Mar 2022 18:57:09 -0500 Subject: [PATCH] [Security Solution] Fixes manage alerts permissions on Detections alerts page (#126537) Co-authored-by: Garrett Spong --- .../detection_alerts/acknowledged.spec.ts | 39 +++++++++++++++++ .../detection_alerts/closing.spec.ts | 42 +++++++++++++++++++ .../timeline_actions/use_alerts_actions.tsx | 4 +- .../detection_engine/detection_engine.tsx | 5 +-- 4 files changed, 85 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/security_solution/cypress/integration/detection_alerts/acknowledged.spec.ts b/x-pack/plugins/security_solution/cypress/integration/detection_alerts/acknowledged.spec.ts index e75832aa968dd..b71396f116a9e 100644 --- a/x-pack/plugins/security_solution/cypress/integration/detection_alerts/acknowledged.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/detection_alerts/acknowledged.spec.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { ROLES } from '../../../common/test'; import { getNewRule } from '../../objects/rule'; import { ALERTS_COUNT, @@ -63,3 +64,41 @@ describe('Marking alerts as acknowledged', () => { }); }); }); + +describe('Marking alerts as acknowledged with read only role', () => { + beforeEach(() => { + cleanKibana(); + loginAndWaitForPage(ALERTS_URL, ROLES.t2_analyst); + createCustomRuleEnabled(getNewRule()); + refreshPage(); + waitForAlertsToPopulate(100); + }); + + it('Mark one alert as acknowledged when more than one open alerts are selected', () => { + cy.get(ALERTS_COUNT) + .invoke('text') + .then((alertNumberString) => { + const numberOfAlerts = alertNumberString.split(' ')[0]; + const numberOfAlertsToBeMarkedAcknowledged = 1; + const numberOfAlertsToBeSelected = 3; + + cy.get(TAKE_ACTION_POPOVER_BTN).should('not.exist'); + selectNumberOfAlerts(numberOfAlertsToBeSelected); + cy.get(TAKE_ACTION_POPOVER_BTN).should('exist'); + + markAcknowledgedFirstAlert(); + const expectedNumberOfAlerts = +numberOfAlerts - numberOfAlertsToBeMarkedAcknowledged; + cy.get(ALERTS_COUNT).should('have.text', `${expectedNumberOfAlerts} alerts`); + cy.get(ALERT_COUNT_TABLE_FIRST_ROW_COUNT).should('have.text', `${expectedNumberOfAlerts}`); + + goToAcknowledgedAlerts(); + waitForAlerts(); + + cy.get(ALERTS_COUNT).should('have.text', `${numberOfAlertsToBeMarkedAcknowledged} alert`); + cy.get(ALERT_COUNT_TABLE_FIRST_ROW_COUNT).should( + 'have.text', + `${numberOfAlertsToBeMarkedAcknowledged}` + ); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/cypress/integration/detection_alerts/closing.spec.ts b/x-pack/plugins/security_solution/cypress/integration/detection_alerts/closing.spec.ts index d6235d47d31ee..0275e35b1e43b 100644 --- a/x-pack/plugins/security_solution/cypress/integration/detection_alerts/closing.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/detection_alerts/closing.spec.ts @@ -6,6 +6,7 @@ */ import { getNewRule } from '../../objects/rule'; +import { ROLES } from '../../../common/test'; import { ALERTS_COUNT, SELECTED_ALERTS, @@ -174,3 +175,44 @@ describe('Closing alerts', () => { }); }); }); + +describe('Closing alerts with read only role', () => { + beforeEach(() => { + cleanKibana(); + loginAndWaitForPage(ALERTS_URL, ROLES.t2_analyst); + createCustomRuleEnabled(getNewRule(), '1', '100m', 100); + refreshPage(); + waitForAlertsToPopulate(100); + deleteCustomRule(); + }); + + it('Closes alerts', () => { + const numberOfAlertsToBeClosed = 3; + cy.get(ALERTS_COUNT) + .invoke('text') + .then((alertNumberString) => { + const numberOfAlerts = alertNumberString.split(' ')[0]; + cy.get(ALERTS_COUNT).should('have.text', `${numberOfAlerts} alerts`); + cy.get(ALERT_COUNT_TABLE_FIRST_ROW_COUNT).should('have.text', `${numberOfAlerts}`); + + selectNumberOfAlerts(numberOfAlertsToBeClosed); + + cy.get(SELECTED_ALERTS).should('have.text', `Selected ${numberOfAlertsToBeClosed} alerts`); + + closeAlerts(); + waitForAlerts(); + + const expectedNumberOfAlertsAfterClosing = +numberOfAlerts - numberOfAlertsToBeClosed; + cy.get(ALERTS_COUNT).should('have.text', `${expectedNumberOfAlertsAfterClosing} alerts`); + cy.get(ALERT_COUNT_TABLE_FIRST_ROW_COUNT).should( + 'have.text', + `${expectedNumberOfAlertsAfterClosing}` + ); + + goToClosedAlerts(); + waitForAlerts(); + + cy.get(ALERTS_COUNT).should('have.text', `${numberOfAlertsToBeClosed} alerts`); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_alerts_actions.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_alerts_actions.tsx index 8da4ce1c3ed7f..b87cea7008442 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_alerts_actions.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_alerts_actions.tsx @@ -31,7 +31,7 @@ export const useAlertsActions = ({ refetch, }: Props) => { const dispatch = useDispatch(); - const { hasIndexWrite, hasKibanaCRUD } = useAlertsPrivileges(); + const { hasIndexWrite } = useAlertsPrivileges(); const onStatusUpdate = useCallback(() => { closePopover(); @@ -66,6 +66,6 @@ export const useAlertsActions = ({ }); return { - actionItems: hasIndexWrite && hasKibanaCRUD ? actionItems : [], + actionItems: hasIndexWrite ? actionItems : [], }; }; diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx index eccb2e081cd9d..5bd6875032e03 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/detection_engine.tsx @@ -123,7 +123,6 @@ const DetectionEnginePageComponent: React.FC = ({ signalIndexName, hasIndexWrite = false, hasIndexMaintenance = false, - canUserCRUD = false, canUserREAD, hasIndexRead, }, @@ -376,8 +375,8 @@ const DetectionEnginePageComponent: React.FC = ({