Example #1
0
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)
Example #3
0
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'])
Example #4
0
    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)
Example #5
0
    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)
Example #9
0
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)
Example #11
0
    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')
Example #12
0
    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)
Example #13
0
    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)
Example #14
0
 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')
     ])
Example #15
0
    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)
Example #16
0
    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)
Example #17
0
    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)
Example #18
0
    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)
Example #19
0
    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)
Example #20
0
 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
Example #21
0
 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
Example #22
0
    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)
Example #23
0
    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)
Example #24
0
 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)
Example #25
0
 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))
Example #26
0
    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)
Example #27
0
 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
Example #28
0
    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)
Example #29
0
    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)
Example #30
0
    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')
        ])