import { RulesClient , ConstructorOptions } from '../rules_client' ; import { savedObjectsClientMock , loggingSystemMock } from '../../../../../../src/core/server/mocks' ; import { taskManagerMock } from '../../../../task_manager/server/mocks' ; import { ruleTypeRegistryMock } from '../../rule_type_registry.mock' ; import { alertingAuthorizationMock } from '../../authorization/alerting_authorization.mock' ; import { encryptedSavedObjectsMock } from '../../../../encrypted_saved_objects/server/mocks' ; import { actionsAuthorizationMock } from '../../../../actions/server/mocks' ; import { AlertingAuthorization } from '../../authorization/alerting_authorization' ; import { ActionsAuthorization } from '../../../../actions/server' ; import { httpServerMock } from '../../../../../../src/core/server/mocks' ; import { auditServiceMock } from '../../../../security/server/audit/index.mock' ; import { getBeforeSetup , setGlobalDate } from './lib' ; const taskManager = taskManagerMock . createStart ( ) ; const ruleTypeRegistry = ruleTypeRegistryMock . create ( ) ; const unsecuredSavedObjectsClient = savedObjectsClientMock . create ( ) ; const encryptedSavedObjects = encryptedSavedObjectsMock . createClient ( ) ; const authorization = alertingAuthorizationMock . create ( ) ; const actionsAuthorization = actionsAuthorizationMock . create ( ) ; const auditLogger = auditServiceMock . create ( ) . asScoped ( httpServerMock . createKibanaRequest ( ) ) ; const kibanaVersion = 'v7.10.0' ; const rulesClientParams = { taskManager , ruleTypeRegistry , unsecuredSavedObjectsClient , authorization : authorization as unknown as AlertingAuthorization , actionsAuthorization : actionsAuthorization as unknown as ActionsAuthorization , spaceId : 'default' , namespace : 'default' , getUserName : jest . fn ( ) , createAPIKey : jest . fn ( ) , logger : loggingSystemMock . create ( ) . get ( ) , encryptedSavedObjectsClient : encryptedSavedObjects , getActionsClient : jest . fn ( ) , getEventLogClient : jest . fn ( ) , kibanaVersion , } ; beforeEach ( ( ) => { getBeforeSetup ( rulesClientParams , taskManager , ruleTypeRegistry ) ; ( auditLogger . log as jest . Mock ) . mockClear ( ) ; } ) ; setGlobalDate ( ) ; describe ( 'unmuteInstance()' , ( ) => { test ( 'unmutes an alert instance' , async ( ) => { const rulesClient = new RulesClient ( rulesClientParams ) ; unsecuredSavedObjectsClient . get . mockResolvedValueOnce ( { id : '1' , type : 'alert' , attributes : { actions : [ ] , schedule : { interval : '10s' } , alertTypeId : '2' , enabled : true , scheduledTaskId : 'task-123' , mutedInstanceIds : [ '2' ] , } , version : '123' , references : [ ] , } ) ; await rulesClient . unmuteInstance ( { alertId : '1' , alertInstanceId : '2' } ) ; expect ( unsecuredSavedObjectsClient . update ) . toHaveBeenCalledWith ( 'alert' , '1' , { mutedInstanceIds : [ ] , updatedBy : 'elastic' , updatedAt : '2019-02-12T21:01:22.479Z' , } , { version : '123' } ) ; } ) ; test ( 'skips unmuting when alert instance not muted' , async ( ) => { const rulesClient = new RulesClient ( rulesClientParams ) ; unsecuredSavedObjectsClient . get . mockResolvedValueOnce ( { id : '1' , type : 'alert' , attributes : { actions : [ ] , schedule : { interval : '10s' } , alertTypeId : '2' , enabled : true , scheduledTaskId : 'task-123' , mutedInstanceIds : [ ] , } , references : [ ] , } ) ; await rulesClient . unmuteInstance ( { alertId : '1' , alertInstanceId : '2' } ) ; expect ( unsecuredSavedObjectsClient . create ) . not . toHaveBeenCalled ( ) ; } ) ; test ( 'skips unmuting when alert is muted' , async ( ) => { const rulesClient = new RulesClient ( rulesClientParams ) ; unsecuredSavedObjectsClient . get . mockResolvedValueOnce ( { id : '1' , type : 'alert' , attributes : { actions : [ ] , schedule : { interval : '10s' } , alertTypeId : '2' , enabled : true , scheduledTaskId : 'task-123' , mutedInstanceIds : [ ] , muteAll : true , } , references : [ ] , } ) ; await rulesClient . unmuteInstance ( { alertId : '1' , alertInstanceId : '2' } ) ; expect ( unsecuredSavedObjectsClient . create ) . not . toHaveBeenCalled ( ) ; } ) ; describe ( 'authorization' , ( ) => { beforeEach ( ( ) => { unsecuredSavedObjectsClient . get . mockResolvedValueOnce ( { id : '1' , type : 'alert' , attributes : { actions : [ { group : 'default' , id : '1' , actionTypeId : '1' , actionRef : '1' , params : { foo : true , } , } , ] , alertTypeId : 'myType' , consumer : 'myApp' , schedule : { interval : '10s' } , enabled : true , scheduledTaskId : 'task-123' , mutedInstanceIds : [ '2' ] , } , version : '123' , references : [ ] , } ) ; } ) ; test ( 'ensures user is authorised to unmuteInstance this type of alert under the consumer' , async ( ) => { const rulesClient = new RulesClient ( rulesClientParams ) ; await rulesClient . unmuteInstance ( { alertId : '1' , alertInstanceId : '2' } ) ; expect ( actionsAuthorization . ensureAuthorized ) . toHaveBeenCalledWith ( 'execute' ) ; expect ( authorization . ensureAuthorized ) . toHaveBeenCalledWith ( { entity : 'rule' , consumer : 'myApp' , operation : 'unmuteAlert' , ruleTypeId : 'myType' , } ) ; } ) ; test ( 'throws when user is not authorised to unmuteInstance this type of alert' , async ( ) => { const rulesClient = new RulesClient ( rulesClientParams ) ; authorization . ensureAuthorized . mockRejectedValue ( new Error ( `Unauthorized to unmuteAlert a "myType" alert for "myApp"` ) ) ; await expect ( rulesClient . unmuteInstance ( { alertId : '1' , alertInstanceId : '2' } ) ) . rejects . toMatchInlineSnapshot ( `[Error: Unauthorized to unmuteAlert a "myType" alert for "myApp"]` ) ; expect ( authorization . ensureAuthorized ) . toHaveBeenCalledWith ( { entity : 'rule' , consumer : 'myApp' , operation : 'unmuteAlert' , ruleTypeId : 'myType' , } ) ; } ) ; } ) ; describe ( 'auditLogger' , ( ) => { test ( 'logs audit event when unmuting an alert' , async ( ) => { const rulesClient = new RulesClient ( { ... rulesClientParams , auditLogger } ) ; unsecuredSavedObjectsClient . get . mockResolvedValueOnce ( { id : '1' , type : 'alert' , attributes : { actions : [ ] , schedule : { interval : '10s' } , alertTypeId : '2' , enabled : true , scheduledTaskId : 'task-123' , mutedInstanceIds : [ ] , } , version : '123' , references : [ ] , } ) ; await rulesClient . unmuteInstance ( { alertId : '1' , alertInstanceId : '2' } ) ; expect ( auditLogger . log ) . toHaveBeenCalledWith ( expect . objectContaining ( { event : expect . objectContaining ( { action : 'rule_alert_unmute' , outcome : 'unknown' , } ) , kibana : { saved_object : { id : '1' , type : 'alert' } } , } ) ) ; } ) ; test ( 'logs audit event when not authorised to unmute an alert' , async ( ) => { const rulesClient = new RulesClient ( { ... rulesClientParams , auditLogger } ) ; unsecuredSavedObjectsClient . get . mockResolvedValueOnce ( { id : '1' , type : 'alert' , attributes : { actions : [ ] , schedule : { interval : '10s' } , alertTypeId : '2' , enabled : true , scheduledTaskId : 'task-123' , mutedInstanceIds : [ ] , } , version : '123' , references : [ ] , } ) ; authorization . ensureAuthorized . mockRejectedValue ( new Error ( 'Unauthorized' ) ) ; await expect ( rulesClient . unmuteInstance ( { alertId : '1' , alertInstanceId : '2' } ) ) . rejects . toThrow ( ) ; expect ( auditLogger . log ) . toHaveBeenCalledWith ( expect . objectContaining ( { event : expect . objectContaining ( { action : 'rule_alert_unmute' , outcome : 'failure' , } ) , kibana : { saved_object : { id : '1' , type : 'alert' , } , } , error : { code : 'Error' , message : 'Unauthorized' , } , } ) ) ; } ) ; } ) ; } ) ;