diff --git a/x-pack/plugins/security_solution/cypress/integration/exceptions/all_exception_lists_read_only.spec.ts b/x-pack/plugins/security_solution/cypress/integration/exceptions/all_exception_lists_read_only.spec.ts new file mode 100644 index 0000000000000..e332019f2754e --- /dev/null +++ b/x-pack/plugins/security_solution/cypress/integration/exceptions/all_exception_lists_read_only.spec.ts @@ -0,0 +1,50 @@ +/* + * 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 { ROLES } from '../../../common/test'; +import { getExceptionList } from '../../objects/exception'; +import { EXCEPTIONS_TABLE_SHOWING_LISTS } from '../../screens/exceptions'; +import { createExceptionList } from '../../tasks/api_calls/exceptions'; +import { cleanKibana } from '../../tasks/common'; +import { dismissCallOut, getCallOut, waitForCallOutToBeShown } from '../../tasks/common/callouts'; +import { loginAndWaitForPageWithoutDateRange } from '../../tasks/login'; +import { EXCEPTIONS_URL } from '../../urls/navigation'; + +const MISSING_PRIVILEGES_CALLOUT = 'missing-user-privileges'; + +describe('All exception lists - read only', () => { + before(() => { + cleanKibana(); + + // Create exception list not used by any rules + createExceptionList(getExceptionList(), getExceptionList().list_id); + + loginAndWaitForPageWithoutDateRange(EXCEPTIONS_URL, ROLES.reader); + + cy.reload(); + + // Using cy.contains because we do not care about the exact text, + // just checking number of lists shown + cy.contains(EXCEPTIONS_TABLE_SHOWING_LISTS, '1'); + }); + + it('Displays missing privileges primary callout', () => { + waitForCallOutToBeShown(MISSING_PRIVILEGES_CALLOUT, 'primary'); + }); + + context('When a user clicks Dismiss on the callouts', () => { + it('We hide them and persist the dismissal', () => { + waitForCallOutToBeShown(MISSING_PRIVILEGES_CALLOUT, 'primary'); + + dismissCallOut(MISSING_PRIVILEGES_CALLOUT); + cy.reload(); + cy.contains(EXCEPTIONS_TABLE_SHOWING_LISTS, '1'); + + getCallOut(MISSING_PRIVILEGES_CALLOUT).should('not.exist'); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table.tsx index c40b6b9571724..65684a7c7d9de 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/exceptions/exceptions_table.tsx @@ -39,6 +39,7 @@ import { useUserData } from '../../../../../components/user_info'; import { userHasPermissions } from '../../helpers'; import { useListsConfig } from '../../../../../containers/detection_engine/lists/use_lists_config'; import { ExceptionsTableItem } from './types'; +import { MissingPrivilegesCallOut } from '../../../../../components/callouts/missing_privileges_callout'; export type Func = () => Promise; @@ -349,6 +350,7 @@ export const ExceptionListsTable = React.memo(() => { return ( <> +