Example #1
0
    def test_override_default_body_html(self):
        """SESOutput - Override body html"""
        rule_name = 'test_override_body_html'

        alert = get_random_alert(10, rule_name, omit_rule_desc=True)
        output = MagicMock(spec=SESOutput)
        alert_publication = compose_alert(alert, output, self.DESCRIPTOR)

        alert_publication['@aws-ses.body'] = {
            'html': '<head><body><p>i am a test</p></body></head>'
        }
        msg = SESOutput._build_email(alert, alert_publication, self.CREDS)

        # Tests
        payloads = msg.get_payload()
        for payload in payloads:
            if payload.is_multipart():
                # should only be one payload on this multipart
                html = payload.get_payload()[0].get_payload()
                assert_equal(html,
                             '<head><body><p>i am a test</p></body></head>')
                break
        else:
            # Raise an error if no payload of type MIMEText is found
            raise AssertionError
Example #2
0
    def test_build_email_from_email(self):
        """SESOutput - Test sender"""
        rule_name = 'test_sender'

        alert = get_random_alert(10, rule_name, omit_rule_desc=True)
        output = MagicMock(spec=SESOutput)
        alert_publication = compose_alert(alert, output, self.DESCRIPTOR)

        msg = SESOutput._build_email(alert, alert_publication, self.CREDS)

        # verify to_emails is set
        assert_equal(msg['From'], self.CREDS['from_email'])
Example #3
0
    def test_format_message_default_rule_description(self):
        """SlackOutput - Format Message, Default Rule Description"""
        rule_name = 'test_empty_rule_description'
        alert = get_random_alert(10, rule_name, True)
        output = MagicMock(spec=SlackOutput)
        alert_publication = compose_alert(alert, output, 'asdf')
        loaded_message = SlackOutput._format_message(alert, alert_publication)

        # tests
        default_rule_description = '*Rule Description:*\nNo rule description provided\n'
        assert_equal(loaded_message['attachments'][0]['pretext'],
                     default_rule_description)
Example #4
0
    def test_format_message_additional_sections(self, _, alert_section_mock,
                                                record_section_mock,
                                                add_sections_mock):
        """TeamsOutput - Format Message - Additional card sections"""
        rule_name = 'test_rule_default'
        alert = get_random_alert(25, rule_name)
        output = MagicMock(spec=TeamsOutput)
        alert_publication = compose_alert(alert, output, 'asdf')
        alert_publication['@teams.with_record'] = True

        # Setup test_card_section
        test_card_section = Mock()

        alert_section_mock.return_value = 'Alert_Section'
        record_section_mock.return_value = 'Record_Section'

        add_sections_mock.side_effect = (lambda teams_card, _: teams_card)

        # Pass card section in via Publisher
        alert_publication['@teams.additional_card_sections'] = [
            test_card_section
        ]

        loaded_message = self._dispatcher._format_message(
            alert, alert_publication, self.CREDS['url'])

        # Tests

        # Verify title
        loaded_message.title.assert_called()
        loaded_message.title.assert_called_with(
            'StreamAlert Rule Triggered: {}'.format(alert.rule_name))

        # Verify text/description
        loaded_message.text.assert_called()
        loaded_message.text.assert_called_with(alert.rule_description)

        # Verify card color
        loaded_message.color.assert_called()
        loaded_message.color.assert_called_with('E81123')

        # Verify Sections
        alert_section_mock.assert_called()
        alert_section_mock.assert_called_with(alert)
        record_section_mock.assert_called()
        record_section_mock.assert_called_with(alert.record)
        add_sections_mock.assert_called()
        assert_equal(add_sections_mock.call_count, 1)
        loaded_message.addSection.assert_called()
        loaded_message.addSection.assert_has_calls(
            [call('Alert_Section'),
             call('Record_Section')], any_order=False)
Example #5
0
    def test_build_email_to_emails_single(self):
        """SESOutput - Single recipient"""
        rule_name = 'test_single_recipient'

        alert = get_random_alert(10, rule_name, omit_rule_desc=True)

        output = MagicMock(spec=SESOutput)
        alert_publication = compose_alert(alert, output, self.DESCRIPTOR)

        msg = SESOutput._build_email(alert, alert_publication, self.CREDS)

        # verify to_emails is set
        assert_equal(msg['To'], '*****@*****.**')
Example #6
0
    def test_subject_override(self):
        """SESOutput - Change default Subject"""
        rule_name = 'test_subject_override'

        alert = get_random_alert(10, rule_name, omit_rule_desc=True)
        output = MagicMock(spec=SESOutput)
        alert_publication = compose_alert(alert, output, 'asdf')
        alert_publication['@aws-ses.subject'] = 'this is a test'

        msg = SESOutput._build_email(alert, alert_publication, self.CREDS)

        # check subject override worked
        assert_equal(msg['Subject'], 'this is a test')
Example #7
0
    def test_format_message_custom_attachment(self):
        """SlackOutput - Format Message, Custom Attachment"""
        rule_name = 'test_empty_rule_description'
        alert = get_random_alert(10, rule_name, True)
        output = MagicMock(spec=SlackOutput)
        alert_publication = compose_alert(alert, output, 'asdf')
        alert_publication['@slack.attachments'] = [{'text': 'aasdfkjadfj'}]

        loaded_message = SlackOutput._format_message(alert, alert_publication)

        # tests
        assert_equal(len(loaded_message['attachments']), 1)
        assert_equal(loaded_message['attachments'][0]['text'], 'aasdfkjadfj')
Example #8
0
    def test_format_message_single(self):
        """SlackOutput - Format Single Message - Slack"""
        rule_name = 'test_rule_single'
        alert = get_random_alert(25, rule_name)
        output = MagicMock(spec=SlackOutput)
        alert_publication = compose_alert(alert, output, 'asdf')
        loaded_message = SlackOutput._format_message(alert, alert_publication)

        # tests
        assert_set_equal(set(loaded_message.keys()),
                         {'text', 'mrkdwn', 'attachments'})
        assert_equal(loaded_message['text'],
                     '*StreamAlert Rule Triggered: test_rule_single*')
        assert_equal(len(loaded_message['attachments']), 1)
Example #9
0
    def test_format_message_custom_text(self):
        """SlackOutput - Format Single Message - Custom Text"""
        rule_name = 'test_rule_single'
        alert = get_random_alert(25, rule_name)
        output = MagicMock(spec=SlackOutput)
        alert_publication = compose_alert(alert, output, 'asdf')
        alert_publication['@slack.text'] = 'Lorem ipsum foobar'

        loaded_message = SlackOutput._format_message(alert, alert_publication)

        # tests
        assert_set_equal(set(loaded_message.keys()),
                         {'text', 'mrkdwn', 'attachments'})
        assert_equal(loaded_message['text'], 'Lorem ipsum foobar')
        assert_equal(len(loaded_message['attachments']), 1)
Example #10
0
    def test_build_email_to_emails_multiple(self):
        """SESOutput - Multiple recipients"""
        rule_name = 'test_multiple_recipients'

        alert = get_random_alert(10, rule_name, omit_rule_desc=True)
        output = MagicMock(spec=SESOutput)
        alert_publication = compose_alert(alert, output, self.DESCRIPTOR)

        creds = {
            'to_emails': '[email protected],[email protected]',
            'from_email': '*****@*****.**'
        }
        msg = SESOutput._build_email(alert, alert_publication, creds)

        # verify to_emails is set
        assert_equal(msg["To"], creds["to_emails"])
Example #11
0
    def test_format_message_multiple(self):
        """SlackOutput - Format Multi-Message"""
        rule_name = 'test_rule_multi-part'
        alert = get_random_alert(30, rule_name)
        output = MagicMock(spec=SlackOutput)
        alert_publication = compose_alert(alert, output, 'asdf')
        loaded_message = SlackOutput._format_message(alert, alert_publication)

        # tests
        assert_set_equal(set(loaded_message.keys()),
                         {'text', 'mrkdwn', 'attachments'})
        assert_equal(loaded_message['text'],
                     '*StreamAlert Rule Triggered: test_rule_multi-part*')
        assert_equal(len(loaded_message['attachments']), 2)
        assert_equal(
            loaded_message['attachments'][1]['text'].split('\n')[3][1:7],
            '000028')
Example #12
0
    def test_generate_record_section(self, section_mock):
        """TeamsOutput - _generate_record_section - Teams"""
        section_mock.return_value = Mock(activityTitle=Mock(), addFact=Mock())

        rule_name = 'test_rule_default'
        alert = get_random_alert(25, rule_name)

        section = self._dispatcher._generate_record_section(alert.record)

        # Tests
        section_mock.assert_called()
        section.activityTitle.assert_called()
        section.activityTitle.assert_called_with('StreamAlert Alert Record')
        section.addFact.assert_called()
        section.addFact.assert_has_calls(
            [call(key, value) for key, value in alert.record.items()],
            any_order=True)
Example #13
0
    def test_no_attachment(self):
        """SESOutput - No attachment"""
        rule_name = 'test_no_attachment'

        alert = get_random_alert(10, rule_name, omit_rule_desc=True)
        output = MagicMock(spec=SESOutput)
        alert_publication = compose_alert(alert, output, self.DESCRIPTOR)

        # remove the default record
        alert_publication['@aws-ses.attach_record'] = False

        msg = SESOutput._build_email(alert, alert_publication, self.CREDS)
        payloads = msg.get_payload()

        # Verify no attachment
        assert_equal(len(payloads), 1)
        assert_equal(payloads[0].get_payload(),
                     'Please review the attached record.json')
Example #14
0
    def test_format_message_custom_attachment_limit(self, log_warning):
        """SlackOutput - Format Message, Custom Attachment is Truncated"""
        rule_name = 'test_empty_rule_description'
        alert = get_random_alert(10, rule_name, True)
        output = MagicMock(spec=SlackOutput)
        alert_publication = compose_alert(alert, output, 'asdf')

        long_message = 'a' * (SlackOutput.MAX_MESSAGE_SIZE + 1)
        alert_publication['@slack.attachments'] = [{'text': long_message}]

        loaded_message = SlackOutput._format_message(alert, alert_publication)

        # tests
        assert_equal(len(loaded_message['attachments'][0]['text']),
                     3999)  # bug in elide
        log_warning.assert_called_with(
            'Custom attachment was truncated to length %d. Full message: %s',
            SlackOutput.MAX_MESSAGE_SIZE, long_message)
Example #15
0
    def test_add_single_attachment(self):
        """SESOutput - Test single attachment"""
        rule_name = 'test_single_attachment'

        alert = get_random_alert(10, rule_name, omit_rule_desc=True)
        output = MagicMock(spec=SESOutput)
        alert_publication = compose_alert(alert, output, self.DESCRIPTOR)

        msg = SESOutput._build_email(alert, alert_publication, self.CREDS)

        # Verify attachment
        payloads = msg.get_payload()
        for payload in payloads:
            if isinstance(payload, MIMEApplication):
                assert_equal(payload.get_filename(), 'record.json')
                break
        else:
            # Raise an error if no payload of type MIMEApplication is found
            raise AssertionError
Example #16
0
    def test_generate_alert_section(self, section_mock):
        """TeamsOutput - _generate_alert_section - Teams"""
        section_mock.return_value = Mock(activityTitle=Mock(), addFact=Mock())

        rule_name = 'test_rule_default'
        alert = get_random_alert(25, rule_name)

        section = self._dispatcher._generate_alert_section(alert)

        # Tests
        section_mock.assert_called()
        section.activityTitle.assert_called()
        section.activityTitle.assert_called_with('Alert Info')
        section.addFact.assert_called()
        section.addFact.assert_has_calls([
            call('rule_name', alert.rule_name),
            call('alert_id', alert.alert_id)
        ],
                                         any_order=False)
Example #17
0
    def test_format_message_custom_attachment_multi_limit(self, log_warning):
        """SlackOutput - Format Message, Too many Custom Attachments is truncated"""
        rule_name = 'test_empty_rule_description'
        alert = get_random_alert(10, rule_name, True)
        output = MagicMock(spec=SlackOutput)
        alert_publication = compose_alert(alert, output, 'asdf')
        alert_publication['@slack.attachments'] = []
        for _ in range(SlackOutput.MAX_ATTACHMENTS + 1):
            alert_publication['@slack.attachments'].append({'text': 'yay'})

        loaded_message = SlackOutput._format_message(alert, alert_publication)

        # tests
        assert_equal(len(loaded_message['attachments']),
                     SlackOutput.MAX_ATTACHMENTS)
        assert_equal(loaded_message['attachments'][19]['text'], 'yay')
        log_warning.assert_called_with(
            'Message with %d custom attachments was truncated to %d attachments',
            SlackOutput.MAX_ATTACHMENTS + 1, SlackOutput.MAX_ATTACHMENTS)
Example #18
0
    def test_override_default_body_string(self):
        """SESOutput - Override body string"""
        rule_name = 'test_override_body_string'

        alert = get_random_alert(10, rule_name, omit_rule_desc=True)
        output = MagicMock(spec=SESOutput)
        alert_publication = compose_alert(alert, output, self.DESCRIPTOR)

        alert_publication['@aws-ses.body'] = 'i am a test'

        msg = SESOutput._build_email(alert, alert_publication, self.CREDS)

        # Tests
        payloads = msg.get_payload()
        for payload in payloads:
            if isinstance(payload, MIMEText):
                assert_equal(payload.get_payload(), 'i am a test')
                break
        else:
            # Raise an error if no payload of type MIMEText is found
            raise AssertionError
Example #19
0
    def test_format_message_custom_color(self, _, alert_section_mock,
                                         record_section_mock):
        """TeamsOutput - Format Message - Custom color"""
        rule_name = 'test_rule_default'
        alert = get_random_alert(25, rule_name)
        output = MagicMock(spec=TeamsOutput)
        alert_publication = compose_alert(alert, output, 'asdf')
        alert_publication['@teams.card_color'] = '46eb34'

        alert_section_mock.return_value = 'Alert_Section'
        record_section_mock.return_value = 'Record_Section'

        loaded_message = self._dispatcher._format_message(
            alert, alert_publication, self.CREDS['url'])

        # Tests

        # Verify title
        loaded_message.title.assert_called()
        loaded_message.title.assert_called_with(
            'StreamAlert Rule Triggered: {}'.format(alert.rule_name))

        # Verify text/description
        loaded_message.text.assert_called()
        loaded_message.text.assert_called_with(alert.rule_description)

        # Verify card color
        loaded_message.color.assert_called()
        loaded_message.color.assert_called_with('46eb34')

        # Verify Sections
        alert_section_mock.assert_called()
        alert_section_mock.assert_called_with(alert)
        record_section_mock.assert_called()
        record_section_mock.assert_called_with(alert.record)
        loaded_message.addSection.assert_called()
        loaded_message.addSection.assert_has_calls(
            [call('Alert_Section'),
             call('Record_Section')], any_order=False)
Example #20
0
    def test_add_multiple_attachments(self):
        """SESOutput - Multiple attachments"""
        rule_name = 'test_multiple_attachments'

        alert = get_random_alert(10, rule_name, omit_rule_desc=True)
        output = MagicMock(spec=SESOutput)
        alert_publication = compose_alert(alert, output, self.DESCRIPTOR)

        # remove the default record
        alert_publication['@aws-ses.attach_record'] = False
        attachments = {
            'file_one.json': '{"test": true, "foo": "bar"}',
            'file_two.json': '{"test": true, "bar": "foo"}'
        }
        alert_publication['@aws-ses.attachments'] = attachments

        msg = SESOutput._build_email(alert, alert_publication, self.CREDS)

        # Tests
        payloads = msg.get_payload()
        for payload in payloads:
            if isinstance(payload, MIMEApplication):
                assert_true(payload.get_filename() in attachments.keys())