automatically attach mails addressed to ticket+<uuid>@domain.tld to ticket with matching uuid
This commit is contained in:
parent
5a1cfedd56
commit
9269f2ec48
2 changed files with 56 additions and 2 deletions
|
@ -82,7 +82,13 @@ async def send_smtp(message, log):
|
||||||
await aiosmtplib.send(message, hostname="127.0.0.1", port=25, use_tls=False, start_tls=False)
|
await aiosmtplib.send(message, hostname="127.0.0.1", port=25, use_tls=False, start_tls=False)
|
||||||
|
|
||||||
|
|
||||||
def find_active_issue_thread(in_reply_to, subject=None):
|
def find_active_issue_thread(in_reply_to, address, subject):
|
||||||
|
from re import match
|
||||||
|
uuid_match = match(r'^ticket\+([a-f0-9-]{36})@', address)
|
||||||
|
if uuid_match:
|
||||||
|
issue = IssueThread.objects.filter(uuid=uuid_match.group(1))
|
||||||
|
if issue.exists():
|
||||||
|
return issue.first(), False
|
||||||
reply_to = Email.objects.filter(reference=in_reply_to)
|
reply_to = Email.objects.filter(reference=in_reply_to)
|
||||||
if reply_to.exists():
|
if reply_to.exists():
|
||||||
return reply_to.first().issue_thread, False
|
return reply_to.first().issue_thread, False
|
||||||
|
@ -172,7 +178,7 @@ def receive_email(envelope, log=None):
|
||||||
subject = unescape_and_decode_base64(subject)
|
subject = unescape_and_decode_base64(subject)
|
||||||
target_event = find_target_event(recipient)
|
target_event = find_target_event(recipient)
|
||||||
|
|
||||||
active_issue_thread, new = find_active_issue_thread(header_in_reply_to, subject)
|
active_issue_thread, new = find_active_issue_thread(header_in_reply_to, recipient, subject)
|
||||||
|
|
||||||
email = Email.objects.create(
|
email = Email.objects.create(
|
||||||
sender=sender, recipient=recipient, body=body, subject=subject, reference=header_message_id,
|
sender=sender, recipient=recipient, body=body, subject=subject, reference=header_message_id,
|
||||||
|
|
|
@ -630,3 +630,51 @@ dGVzdGltYWdl
|
||||||
states = StateChange.objects.filter(issue_thread=IssueThread.objects.all()[0])
|
states = StateChange.objects.filter(issue_thread=IssueThread.objects.all()[0])
|
||||||
self.assertEqual(1, len(states))
|
self.assertEqual(1, len(states))
|
||||||
self.assertEqual('pending_new', states[0].state)
|
self.assertEqual('pending_new', states[0].state)
|
||||||
|
|
||||||
|
def test_mail_plus_issue_thread(self):
|
||||||
|
issue_thread = IssueThread.objects.create(
|
||||||
|
name="test",
|
||||||
|
)
|
||||||
|
mail1 = Email.objects.create(
|
||||||
|
subject='test subject',
|
||||||
|
body='test',
|
||||||
|
sender='test1@test',
|
||||||
|
recipient='test2@test',
|
||||||
|
issue_thread=issue_thread,
|
||||||
|
)
|
||||||
|
mail1_reply = Email.objects.create(
|
||||||
|
subject='Message received',
|
||||||
|
body='Thank you for your message.',
|
||||||
|
sender='test2@test',
|
||||||
|
recipient='test1@test',
|
||||||
|
in_reply_to=mail1.reference,
|
||||||
|
issue_thread=issue_thread,
|
||||||
|
)
|
||||||
|
from aiosmtpd.smtp import Envelope
|
||||||
|
from asgiref.sync import async_to_sync
|
||||||
|
import aiosmtplib
|
||||||
|
import logging
|
||||||
|
logging.disable(logging.CRITICAL)
|
||||||
|
aiosmtplib.send = make_mocked_coro()
|
||||||
|
handler = LMTPHandler()
|
||||||
|
server = mock.Mock()
|
||||||
|
session = mock.Mock()
|
||||||
|
envelope = Envelope()
|
||||||
|
envelope.mail_from = '<test1@test>'
|
||||||
|
envelope.rcpt_tos = ['ticket+{}@test'.format(issue_thread.uuid)]
|
||||||
|
envelope.content = (f'Subject: foo\nFrom: <test3@test>\nTo: ticket+{issue_thread.uuid}@test\n'
|
||||||
|
f'Message-ID: <3@test>\n\nbar'.encode('utf-8'))
|
||||||
|
result = async_to_sync(handler.handle_DATA)(server, session, envelope)
|
||||||
|
logging.disable(logging.NOTSET)
|
||||||
|
self.assertEqual('250 Message accepted for delivery', result)
|
||||||
|
self.assertEqual(3, len(Email.objects.all()))
|
||||||
|
self.assertEqual(3, len(Email.objects.filter(issue_thread=issue_thread)))
|
||||||
|
self.assertEqual(1, len(IssueThread.objects.all()))
|
||||||
|
aiosmtplib.send.assert_not_called()
|
||||||
|
self.assertEqual(Email.objects.all()[2].subject, 'foo')
|
||||||
|
self.assertEqual(Email.objects.all()[2].sender, '<test1@test>')
|
||||||
|
self.assertEqual(Email.objects.all()[2].recipient, 'ticket+{}@test'.format(issue_thread.uuid))
|
||||||
|
self.assertEqual(Email.objects.all()[2].body, 'bar')
|
||||||
|
self.assertEqual(Email.objects.all()[2].issue_thread, issue_thread)
|
||||||
|
self.assertEqual(Email.objects.all()[2].reference, '<3@test>')
|
||||||
|
self.assertEqual('test', IssueThread.objects.all()[0].name)
|
||||||
|
|
Loading…
Reference in a new issue