Esempio n. 1
0
    def test_more_encodings(self):
        # these are unicode strings to reflect behavior after loading 'route_email' tasks from mongo
        s_msg = """Date: Sat, 25 May 2019 09:32:00 +1000
From: <*****@*****.**>
To: <*****@*****.**>
Subject: bugs
Content-Type: text/plain; charset=GBK
Content-Transfer-Encoding: base64

VGhlIFNuYXA3IGFwcGxpY2F0aW9uKGJhc2VkIG9uIHNuYXA3LWZ1bGwtMS40LjIpIGhhcyBiZWVu
IHJ1biBvdmVyIGEgd2VlayBvbiBRTlg2LjYuMCwKQnV0IHNvbWV0aW1lcyAsc3lzdGVtIHNjcmVl
biB3aWxsIHByaW50CiJsZGQ6RkFUQUw6Y291bGQgbm90IGxvYWQgbGlicmFyeSBsaWJzb2NrZXQu
c28uMyIsClRoZSBhcHBsaWNhdGlvbidzIGNvbW11bmljYXRpb24gd29yayB3ZWxsICxidXQgdGhl
IGZ0cCx0ZWxuZXQscGluZyBjYW4ndCB3b3JrICEKCgpXaHk/
"""
        msg = parse_message(s_msg)
        assert isinstance(msg['payload'], six.text_type)
        assert_in('The Snap7 application', msg['payload'])

        s_msg = """Date: Sat, 25 May 2019 09:32:00 +1000
From: <*****@*****.**>
To: <*****@*****.**>
Subject: bugs
Content-Type: text/plain; charset=utf-8
Content-Disposition: inline
Content-Transfer-Encoding: 8bit

> Status: closed
> Created: Thu May 23, 2019 09:24 PM UTC by admin1
> Attachments:
> 
>   • foo.txt (1.0 kB; text/plain)
> 
"""
        msg = parse_message(s_msg)
        assert isinstance(msg['payload'], six.text_type)
        assert_in('• foo', msg['payload'])

        s_msg = """Date: Sat, 25 May 2019 09:32:00 +1000
From: <*****@*****.**>
To: <*****@*****.**>
Subject: bugs
Content-Type: TEXT/PLAIN; format=flowed; charset=ISO-8859-15
Content-Transfer-Encoding: 8BIT

programmed or èrogrammed ?
"""
        msg = parse_message(s_msg)
        assert isinstance(msg['payload'], six.text_type)
        assert_in('èrogrammed', msg['payload'])
    def test_unicode_complex_message(self):
        charset = 'utf-8'
        p1 = MIMEText(u'''По оживлённым берегам
Громады стройные теснятся
Дворцов и башен; корабли
Толпой со всех концов земли
К богатым пристаням стремятся;'''.encode(charset),
                        'plain',
                        charset)
        p2 = MIMEText(u'''<p>По оживлённым берегам
Громады стройные теснятся
Дворцов и башен; корабли
Толпой со всех концов земли
К богатым пристаням стремятся;</p>'''.encode(charset),
                        'plain',
                        charset)
        msg1 = MIMEMultipart()
        msg1['Message-ID'] = '<*****@*****.**>'
        msg1.attach(p1)
        msg1.attach(p2)
        s_msg = msg1.as_string()
        msg2 = parse_message(s_msg)
        for part in msg2['parts']:
            if part['payload'] is None: continue
            assert isinstance(part['payload'], unicode)
Esempio n. 3
0
    def test_more_encodings_multipart(self):
        # these are unicode strings to reflect behavior after loading 'route_email' tasks from mongo
        s_msg = """Date: Sat, 25 May 2019 09:32:00 +1000
From: <*****@*****.**>
To: <*****@*****.**>
Subject: bugs
Content-Type: multipart/alternative; boundary="===============7387203749754534836=="

--===============7387203749754534836==
Content-Type: text/plain; charset="utf-8"

> Status: closed
> Created: Thu May 23, 2019 09:24 PM UTC by admin1
> Attachments:
> 
>   • foo.txt (1.0 kB; text/plain)
> 


--===============7387203749754534836==
Content-Type: text/html; charset="utf-8"

<html><head>... blah blah 
...
&gt; • foo.txt (1.0 kB; text/plain)
"""
        msg = parse_message(s_msg)
        assert isinstance(msg['parts'][1]['payload'], six.text_type)
        assert isinstance(msg['parts'][2]['payload'], six.text_type)
        assert_in('• foo', msg['parts'][1]['payload'])
        assert_in('• foo', msg['parts'][2]['payload'])
Esempio n. 4
0
    def test_unicode_simple_message(self):
        charset = 'utf-8'
        msg1 = MIMEText(
            u'''По оживлённым берегам
Громады стройные теснятся
Дворцов и башен; корабли
Толпой со всех концов земли
К богатым пристаням стремятся;'''.encode(charset), 'plain', charset)
        msg1['Message-ID'] = '<*****@*****.**>'
        s_msg = msg1.as_string()
        msg2 = parse_message(s_msg)
        assert isinstance(msg2['payload'], unicode)
Esempio n. 5
0
def test_handle_artifact_unicode(qg):
    """
    Tests that app.handle_artifact_message can accept utf strings
    """
    ticket = mock.MagicMock()
    ticket.get_discussion_thread.return_value = (mock.MagicMock(),
                                                 mock.MagicMock())
    post = mock.MagicMock()
    qg.return_value = post

    a = app.Application(c.project, c.app.config)

    msg = dict(payload='foo ƒ†©¥˙¨ˆ'.encode('utf-8'), message_id=1, headers={})
    a.handle_artifact_message(ticket, msg)
    assert_equal(post.attach.call_args[0][1].getvalue(),
                 'foo ƒ†©¥˙¨ˆ'.encode('utf-8'))

    msg = dict(payload='foo'.encode('utf-8'), message_id=1, headers={})
    a.handle_artifact_message(ticket, msg)
    assert_equal(post.attach.call_args[0][1].getvalue(), b'foo')

    msg = dict(payload="\x94my quote\x94".encode('utf-8'),
               message_id=1,
               headers={})
    a.handle_artifact_message(ticket, msg)
    assert_equal(post.attach.call_args[0][1].getvalue(),
                 '\x94my quote\x94'.encode('utf-8'))

    # assert against prod example
    msg_raw = """Message-Id: <*****@*****.**>
From: foo <*****@*****.**>
To: "[forge:site-support]" <*****@*****.**>
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Type: multipart/alternative; boundary="_----------=_150235203132168580"
Date: Thu, 10 Aug 2017 10:00:31 +0200
Subject: Re: [forge:site-support] #15391 Unable to join (my own) mailing list
This is a multi-part message in MIME format.
--_----------=_150235203132168580
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset="utf-8"
Hi
--_----------=_150235203132168580
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset="utf-8"
<!DOCTYPE html>
<html><body>Hi</body></html>
--_----------=_150235203132168580--
    """
    msg = mail_util.parse_message(msg_raw)
    for p in [p for p in msg['parts'] if p['payload'] != None]:
        # filter here mimics logic in `route_email`
        a.handle_artifact_message(ticket, p)
Esempio n. 6
0
def route_email(peer, mailfrom, rcpttos, data):
    '''
    Route messages according to their destination:

    <topic>@<mount_point>.<subproj2>.<subproj1>.<project>.projects.domain.net
    gets sent to c.app.handle_message(topic, message)
    '''
    try:
        msg = mail_util.parse_message(data)
    except Exception:  # pragma no cover
        log.exception('Parse Error: (%r,%r,%r)', peer, mailfrom, rcpttos)
        return
    if mail_util.is_autoreply(msg):
        log.info('Skipping autoreply message: %s', msg['headers'])
        return
    mail_user = mail_util.identify_sender(peer, mailfrom, msg['headers'], msg)
    with h.push_config(c, user=mail_user):
        log.info('Received email from %s', c.user.username)
        # For each of the addrs, determine the project/app and route
        # appropriately
        for addr in rcpttos:
            try:
                userpart, project, app = mail_util.parse_address(addr)
                with h.push_config(c, project=project, app=app):
                    if not app.has_access(c.user, userpart):
                        log.info('Access denied for %s to mailbox %s', c.user,
                                 userpart)
                    elif not c.app.config.options.get('AllowEmailPosting',
                                                      True):
                        log.info("Posting from email is not enabled")
                    else:
                        if msg['multipart']:
                            msg_hdrs = msg['headers']
                            for part in msg['parts']:
                                if part.get('content_type',
                                            '').startswith('multipart/'):
                                    continue
                                msg = dict(headers=dict(
                                    msg_hdrs, **part['headers']),
                                           message_id=part['message_id'],
                                           in_reply_to=part['in_reply_to'],
                                           references=part['references'],
                                           filename=part['filename'],
                                           content_type=part['content_type'],
                                           payload=part['payload'])
                                c.app.handle_message(userpart, msg)
                        else:
                            c.app.handle_message(userpart, msg)
            except exc.MailError as e:
                log.error('Error routing email to %s: %s', addr, e)
            except Exception:
                log.exception('Error routing mail to %s', addr)
Esempio n. 7
0
    def test_unicode_simple_message(self):
        charset = 'utf-8'
        msg1 = MIMEText(u'''По оживлённым берегам
Громады стройные теснятся
Дворцов и башен; корабли
Толпой со всех концов земли
К богатым пристаням стремятся;'''.encode(charset),
                        'plain',
                        charset)
        msg1['Message-ID'] = '<*****@*****.**>'
        s_msg = msg1.as_string()
        msg2 = parse_message(s_msg)
        assert isinstance(msg2['payload'], unicode)
Esempio n. 8
0
def route_email(
        peer, mailfrom, rcpttos, data):
    '''
    Route messages according to their destination:

    <topic>@<mount_point>.<subproj2>.<subproj1>.<project>.projects.domain.net
    gets sent to c.app.handle_message(topic, message)
    '''
    try:
        msg = mail_util.parse_message(data)
    except:  # pragma no cover
        log.exception('Parse Error: (%r,%r,%r)', peer, mailfrom, rcpttos)
        return
    if mail_util.is_autoreply(msg):
        log.info('Skipping autoreply message: %s', msg['headers'])
        return
    mail_user = mail_util.identify_sender(peer, mailfrom, msg['headers'], msg)
    with h.push_config(c, user=mail_user):
        log.info('Received email from %s', c.user.username)
        # For each of the addrs, determine the project/app and route
        # appropriately
        for addr in rcpttos:
            try:
                userpart, project, app = mail_util.parse_address(addr)
                with h.push_config(c, project=project, app=app):
                    if not app.has_access(c.user, userpart):
                        log.info('Access denied for %s to mailbox %s',
                                 c.user, userpart)
                    elif not c.app.config.options.get('AllowEmailPosting', True):
                        log.info("Posting from email is not enabled")
                    else:
                        if msg['multipart']:
                            msg_hdrs = msg['headers']
                            for part in msg['parts']:
                                if part.get('content_type', '').startswith('multipart/'):
                                    continue
                                msg = dict(
                                    headers=dict(msg_hdrs, **part['headers']),
                                    message_id=part['message_id'],
                                    in_reply_to=part['in_reply_to'],
                                    references=part['references'],
                                    filename=part['filename'],
                                    content_type=part['content_type'],
                                    payload=part['payload'])
                                c.app.handle_message(userpart, msg)
                        else:
                            c.app.handle_message(userpart, msg)
            except exc.MailError, e:
                log.error('Error routing email to %s: %s', addr, e)
            except:
Esempio n. 9
0
def test_handle_artifact_unicode(qg):
    """
    Tests that app.handle_artifact_message can accept utf strings
    """
    ticket = mock.MagicMock()
    ticket.get_discussion_thread.return_value = (mock.MagicMock(), mock.MagicMock())
    post = mock.MagicMock()
    qg.return_value = post

    a = app.Application(c.project, c.app.config)

    msg = dict(payload=u'foo ƒ†©¥˙¨ˆ', message_id=1, headers={})
    a.handle_artifact_message(ticket, msg)
    assert_equal(post.attach.call_args[0][1].getvalue(), 'foo ƒ†©¥˙¨ˆ')

    msg = dict(payload='foo', message_id=1, headers={})
    a.handle_artifact_message(ticket, msg)
    assert_equal(post.attach.call_args[0][1].getvalue(), 'foo')

    msg = dict(payload="\x94my quote\x94", message_id=1, headers={})
    a.handle_artifact_message(ticket, msg)
    assert_equal(post.attach.call_args[0][1].getvalue(), '\x94my quote\x94')

    # assert against prod example
    msg_raw = """Message-Id: <*****@*****.**>
From: foo <*****@*****.**>
To: "[forge:site-support]" <*****@*****.**>
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Type: multipart/alternative; boundary="_----------=_150235203132168580"
Date: Thu, 10 Aug 2017 10:00:31 +0200
Subject: Re: [forge:site-support] #15391 Unable to join (my own) mailing list
This is a multi-part message in MIME format.
--_----------=_150235203132168580
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset="utf-8"
Hi
--_----------=_150235203132168580
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset="utf-8"
<!DOCTYPE html>
<html><body>Hi</body></html>
--_----------=_150235203132168580--
    """
    msg = mail_util.parse_message(msg_raw)
    for p in filter(lambda p: p['payload'] != None, msg['parts']):
        # filter here mimics logic in `route_email`
        a.handle_artifact_message(ticket, p)