def test_attach_image(): """Publishers - PagerDuty - AttachImage""" alert = get_alert() alert.created = datetime(2019, 1, 1) alert.publishers = { 'pagerduty': ['publishers.community.pagerduty.pagerduty_layout.AttachImage'] } output = MagicMock(spec=OutputDispatcher) output.__service__ = 'pagerduty' descriptor = 'unit_test_channel' publication = compose_alert(alert, output, descriptor) expectation = { '@pagerduty-v2.images': [{ 'src': 'https://streamalert.io/en/stable/_images/sa-banner.png', 'alt': 'StreamAlert Docs', 'href': 'https://streamalert.io/en/stable/' }], '@pagerduty.contexts': [{ 'src': 'https://streamalert.io/en/stable/_images/sa-banner.png', 'type': 'image' }] } assert_equal(publication, expectation)
def test_from_previous_publication(self): """Publishers - Slack - AttachStringTemplate - from previous publication""" alert = get_alert( context={'slack_message_template': 'Foo {bar} baz {buzz}'}) alert.created = datetime(2019, 1, 1) publication = self._publisher.publish( alert, { '@slack._previous_publication': { 'bar': 'BAR?', 'buzz': 'BUZZ?', }, 'bar': 'wrong', 'buzz': 'wrong', }) expectation = { '@slack._previous_publication': { 'bar': 'BAR?', 'buzz': 'BUZZ?' }, '@slack.attachments': [{ 'color': '#ffb400', 'text': 'Foo BAR? baz BUZZ?' }], 'bar': 'wrong', 'buzz': 'wrong', } assert_equal(publication, expectation)
def test_as_custom_details_ignores_custom_fields(): """Publishers - PagerDuty - as_custom_details - Ignore Magic Keys""" alert = get_alert(context={'context': 'value'}) alert.created = datetime(2019, 1, 1) alert.publishers = { 'pagerduty': [ 'streamalert.shared.publisher.DefaultPublisher', 'publishers.community.pagerduty.pagerduty_layout.ShortenTitle', 'publishers.community.pagerduty.pagerduty_layout.as_custom_details', ] } output = MagicMock(spec=OutputDispatcher) output.__service__ = 'pagerduty' descriptor = 'unit_test_channel' publication = compose_alert(alert, output, descriptor) # We don't care about the entire payload; let's check a few top-level keys we know # are supposed to be here.. assert_true(publication['source_entity']) assert_true(publication['outputs']) assert_true(publication['log_source']) # Check that the title keys exists assert_true(publication['@pagerduty.description']) # now check that the details key exists assert_true(publication['@pagerduty.details']) # And check that it has no magic keys assert_false('@pagerduty.description' in publication['@pagerduty.details']) assert_false('@pagerduty-v2.summary' in publication['@pagerduty.details'])
def test_dispatch_issue_existing(self, post_mock, get_mock, log_mock): """JiraOutput - Dispatch Success, Existing Issue""" # setup the request to find an existing issue get_mock.return_value.status_code = 200 existing_issues = { 'issues': [{ 'fields': { 'summary': 'Bogus' }, 'id': '5000' }] } get_mock.return_value.json.return_value = existing_issues auth_resp = { 'session': { 'name': 'cookie_name', 'value': 'cookie_value' } } # setup the auth and successful creation responses post_mock.return_value.status_code = 200 post_mock.return_value.json.side_effect = [auth_resp, {'id': 5000}] assert_true(self._dispatcher.dispatch(get_alert(), self.OUTPUT)) log_mock.assert_called_with('Successfully sent alert to %s:%s', self.SERVICE, self.DESCRIPTOR)
def test_comment_creation_failure(self, post_mock, get_mock, log_mock): """JiraOutput - Comment Creation, Failure""" # setup successful search response get_mock.return_value.status_code = 200 existing_issues = { 'issues': [{ 'fields': { 'summary': 'Bogus' }, 'id': '5000' }] } get_mock.return_value.json.return_value = existing_issues # setup successful auth, failed comment creation, and successful issue creation type(post_mock.return_value).status_code = PropertyMock( side_effect=[200, 400, 200]) auth_resp = { 'session': { 'name': 'cookie_name', 'value': 'cookie_value' } } post_mock.return_value.json.side_effect = [auth_resp, {'id': 6000}] assert_true(self._dispatcher.dispatch(get_alert(), self.OUTPUT)) log_mock.assert_called_with( 'Encountered an error when adding alert to existing Jira ' 'issue %s. Attempting to create new Jira issue.', 5000)
def test_simple(self): """Publishers - Slack - AttachRuleInfo""" alert = get_alert() alert.created = datetime(2019, 1, 1) alert.rule_description = ''' Author: unit_test Reference: somewhere_over_the_rainbow Description: ? Att&ck vector: Assuming direct control ''' publication = self._publisher.publish(alert, {}) expectation = { '@slack.attachments': [{ 'color': '#8ce071', 'fields': [{ 'title': 'Reference', 'value': 'somewhere_over_the_rainbow', }, { 'title': 'Att&ck vector', 'value': 'Assuming direct control', }] }] } assert_dict_equal(publication, expectation)
def test_record_splitting(self): """Publishers - Slack - AttachFullRecord - Split Record""" alert = get_alert() alert.created = datetime(2019, 1, 1) alert.record = {'massive_record': []} for index in range(0, 999): alert.record['massive_record'].append({ 'index': index, 'value': 'foo' }) publication = self._publisher.publish(alert, {}) attachments = publication['@slack.attachments'] assert_equal(len(attachments), 14) for attachment in attachments: assert_less_equal(len(attachment['text']), 4000) assert_equal(attachments[0]['title'], 'Record') assert_equal(len(attachments[0]['fields']), 0) assert_equal(attachments[0]['footer'], '') assert_equal(attachments[1]['title'], '') assert_equal(len(attachments[1]['fields']), 0) assert_equal(attachments[1]['footer'], '') assert_equal(attachments[13]['title'], '') assert_equal(len(attachments[13]['fields']), 1) assert_equal(attachments[13]['footer'], 'via <https://console.aws.amazon.com/s3/home|s3>')
def test_simple(self): """Publishers - Slack - AttachFullRecord""" alert = get_alert() alert.created = datetime(2019, 1, 1) publication = self._publisher.publish(alert, {}) expectation = { '@slack.attachments': [{ 'footer': 'via <https://console.aws.amazon.com/s3/home|s3>', 'fields': [{ 'value': '79192344-4a6d-4850-8d06-9c3fef1060a4', 'title': 'Alert Id' }], 'mrkdwn_in': ['text'], 'author': 'corp-prefix.prod.cb.region', 'color': '#7b0051', 'text': ('```\n\n{\n "cb_server": "cbserver",\n "compressed_size": "9982",' '\n "file_path": "/tmp/5DA/AD8/0F9AA55DA3BDE84B35656AD8911A22E1.zip",' '\n "md5": "0F9AA55DA3BDE84B35656AD8911A22E1",\n "node_id": "1",' '\n "size": "21504",\n "timestamp": "1496947381.18",' '\n "type": "binarystore.file.added"\n}\n```'), 'title': 'Record', 'footer_icon': '' }] } assert_equal(publication, expectation)
def test_pretty_print_arrays(): """Publishers - PagerDuty - PrettyPrintArrays""" alert = get_alert( context={'populate_fields': ['publishers', 'cb_server', 'staged']}) alert.created = datetime(2019, 1, 1) alert.publishers = { 'pagerduty': [ 'streamalert.shared.publisher.DefaultPublisher', 'publishers.community.generic.populate_fields', 'publishers.community.pagerduty.pagerduty_layout.PrettyPrintArrays' ] } output = MagicMock(spec=OutputDispatcher) output.__service__ = 'pagerduty' descriptor = 'unit_test_channel' publication = compose_alert(alert, output, descriptor) expectation = { 'publishers': [{ 'pagerduty': ('streamalert.shared.publisher.DefaultPublisher\n\n----------\n\n' 'publishers.community.generic.populate_fields\n\n----------\n\n' 'publishers.community.pagerduty.pagerduty_layout.PrettyPrintArrays' ) }], 'staged': 'False', 'cb_server': 'cbserver' } assert_equal(publication, expectation)
def test_simple(self): """Publishers - Slack - AttachPublication""" alert = get_alert() alert.created = datetime(2019, 1, 1) previous = { '@slack._previous_publication': { 'foo': 'bar' }, '@slack.attachments': [ { 'text': 'attachment1', }, ] } publication = self._publisher.publish(alert, previous) expectation = { '@slack._previous_publication': { 'foo': 'bar' }, '@slack.attachments': [{ 'text': 'attachment1' }, { 'color': '#00d1c1', 'text': '```\n{\n "foo": "bar"\n}\n```', 'mrkdwn_in': ['text'], 'title': 'Alert Data:' }] } assert_equal(publication, expectation)
def test_dispatch_bad_descriptor(self, log_error_mock): """KomandOutput - Dispatch Failure, Bad Descriptor""" assert_false( self._dispatcher.dispatch( get_alert(), ':'.join([self.SERVICE, 'bad_descriptor']))) log_error_mock.assert_called_with('Failed to send alert to %s:%s', self.SERVICE, 'bad_descriptor')
def test_dispatch_existing_container(self, post_mock, log_mock): """KomandOutput - Dispatch Success""" post_mock.return_value.status_code = 200 assert_true(self._dispatcher.dispatch(get_alert(), self.OUTPUT)) log_mock.assert_called_with('Successfully sent alert to %s:%s', self.SERVICE, self.DESCRIPTOR)
def test_dispatch(self, log_mock): """Cloudwatch - Dispatch""" alert = get_alert() assert_true(self._dispatcher.dispatch(alert, self.OUTPUT)) assert_equal(log_mock.call_count, 3) log_mock.assert_called_with('Successfully sent alert to %s:%s', self.SERVICE, self.DESCRIPTOR)
def test_dispatch_no_context(self, mock_logger): """CarbonBlackOutput - Dispatch No Context""" assert_false(self._dispatcher.dispatch(get_alert(), self.OUTPUT)) mock_logger.assert_has_calls([ call('[%s] Alert must contain context to run actions', 'carbonblack'), call('Failed to send alert to %s:%s', 'carbonblack', 'unit_test_carbonblack') ])
def test_wrapped_function_publisher(): """WrappedFunctionPublisher - Ensure function is executed properly""" publisher = WrappedFunctionPublisher(sample_publisher_5) alert = get_alert() publication = publisher.publish(alert, {}) expectation = {'test4': True} assert_equal(publication, expectation)
def test_dispatch_success(self, url_mock, log_mock): """SlackOutput - Dispatch Success""" url_mock.return_value.status_code = 200 url_mock.return_value.json.return_value = dict() assert_true(self._dispatcher.dispatch(get_alert(), self.OUTPUT)) log_mock.assert_called_with('Successfully sent alert to %s:%s', self.SERVICE, self.DESCRIPTOR)
def test_auth_empty_response(self, post_mock, log_mock): """JiraOutput - Auth, Failure Empty Response""" # setup unsuccesful auth response post_mock.return_value.status_code = 200 post_mock.return_value.json.return_value = {} assert_false(self._dispatcher.dispatch(get_alert(), self.OUTPUT)) log_mock.assert_called_with('Failed to send alert to %s:%s', self.SERVICE, self.DESCRIPTOR)
def test_dispatch_failure(self, url_mock, log_mock): """SlackOutput - Dispatch Failure, Bad Request""" json_error = {'message': 'error message', 'errors': ['error1']} url_mock.return_value.json.return_value = json_error url_mock.return_value.status_code = 400 assert_false(self._dispatcher.dispatch(get_alert(), self.OUTPUT)) log_mock.assert_called_with('Failed to send alert to %s:%s', self.SERVICE, self.DESCRIPTOR)
def test_dispatch_container_failure(self, post_mock, log_mock): """KomandOutput - Dispatch Failure""" post_mock.return_value.status_code = 400 json_error = {'message': 'error message', 'errors': ['error1']} post_mock.return_value.json.return_value = json_error assert_false(self._dispatcher.dispatch(get_alert(), self.OUTPUT)) log_mock.assert_called_with('Failed to send alert to %s:%s', self.SERVICE, self.DESCRIPTOR)
def setup(self): self._alert = get_alert(context={ 'remove_fields': [ 'streamalert', '^publishers', 'type$', '^outputs$', '^cluster$', '^context$' ] }) self._alert.created = datetime(2019, 1, 1) self._alert.publishers = [TestDefaultPublisher.PUBLISHER_NAME, self.PUBLISHER_NAME] self._output = MagicMock(spec=SlackOutput) # Just use some random output
def setup(self): self._alert = get_alert(context={ 'array': ['a', 'b', 'c'], 'not_array': ['a', {'b': 'c'}, 'd'], 'nest': { 'deep_array': ['a', 'b', 'c'], } }) self._alert.created = datetime(2019, 1, 1) self._alert.publishers = [TestDefaultPublisher.PUBLISHER_NAME, self.PUBLISHER_NAME] self._output = MagicMock(spec=SlackOutput) # Just use some random output
def test_dispatch_success_with_labels(self, url_mock, log_mock): """GithubOutput - Dispatch Success with Labels""" url_mock.return_value.status_code = 200 url_mock.return_value.json.return_value = dict() assert_true(self._dispatcher.dispatch(get_alert(), self.OUTPUT)) assert_equal(url_mock.call_args[1]['json']['labels'], ['label1', 'label2']) log_mock.assert_called_with('Successfully sent alert to %s:%s', self.SERVICE, self.DESCRIPTOR)
def test_dispatch_success(self, message_mock, log_mock): """TeamsOutput - Dispatch Success""" message_mock.return_value = Mock(send=Mock(return_value='Worked')) assert_true(self._dispatcher.dispatch(get_alert(), self.OUTPUT)) # Tests log_mock.assert_called() log_mock.assert_called_with('Successfully sent alert to %s:%s', self.SERVICE, self.DESCRIPTOR)
def test_max_attachments(self, log_mock): """SlackOutput - Max Attachment Reached""" alert = get_alert() alert.record = {'info': 'test' * 20000} output = MagicMock(spec=SlackOutput) alert_publication = compose_alert(alert, output, 'asdf') SlackOutput._format_default_attachments(alert, alert_publication, 'foo') log_mock.assert_called_with( '%s: %d-part message truncated to %d parts', alert_publication, 21, 20)
def test_dispatch_not_banned(self, mock_cb): """CarbonBlackOutput - Dispatch Not Banned""" alert_context = { 'carbonblack': { 'action': 'ban', 'value': 'NOT_BANNED_HASH' } } assert_true( self._dispatcher.dispatch(get_alert(context=alert_context), self.OUTPUT))
def test_dispatch_with_qualifier(self, log_mock): """LambdaOutput - Dispatch Success, With Qualifier""" alt_descriptor = '{}_qual'.format(self.DESCRIPTOR) assert_true( self._dispatcher.dispatch(get_alert(), ':'.join([self.SERVICE, alt_descriptor]))) log_mock.assert_called_with('Successfully sent alert to %s:%s', self.SERVICE, alt_descriptor)
def setup(self): self._alert = get_alert(context={ 'context1': 'value', 'attribs': [ {'type': 'Name', 'value': 'Bob'}, {'type': 'Age', 'value': '42'}, {'type': 'Profession', 'value': 'Software engineer'}, ] }) self._alert.created = datetime(2019, 1, 1) self._alert.publishers = [TestDefaultPublisher.PUBLISHER_NAME, self.PUBLISHER_NAME] self._output = MagicMock(spec=SlackOutput) # Just use some random output
def test_dispatch_new_container(self, post_mock, get_mock, log_mock): """PhantomOutput - Dispatch Success, New Container""" # _check_container_exists get_mock.return_value.status_code = 200 get_mock.return_value.json.return_value = {'count': 0, 'data': []} # _setup_container, dispatch post_mock.return_value.status_code = 200 post_mock.return_value.json.return_value = {'id': 1948} assert_true(self._dispatcher.dispatch(get_alert(), self.OUTPUT)) log_mock.assert_called_with('Successfully sent alert to %s:%s', self.SERVICE, self.DESCRIPTOR)
def test_composite_publisher_ordering(): """CompositePublisher - Ensure publishers executed in correct order""" publisher = CompositePublisher([ SamplePublisher1(), WrappedFunctionPublisher(sample_publisher_blank), SamplePublisher2(), ]) alert = get_alert() publication = publisher.publish(alert, {}) expectation = {'test2': True} assert_equal(publication, expectation)
def test_dispatch_failure(self, message_mock, log_mock): """TeamsOutput - Dispatch Failure, Bad Request""" exception = TeamsWebhookException('BOOM!') message_mock.return_value = Mock(send=Mock(side_effect=exception)) assert_false(self._dispatcher.dispatch(get_alert(), self.OUTPUT)) # Tests log_mock.assert_called() log_mock.assert_has_calls([ call('Error Sending Alert to Teams: %s', exception), call('Failed to send alert to %s:%s', 'teams', 'unit_test_channel') ])