This commit is contained in:
j3d1 2023-12-06 12:34:55 +01:00
parent 6b1df14f92
commit a1d41430bf
2 changed files with 19 additions and 26 deletions

View file

@ -5,7 +5,7 @@ from channels.layers import get_channel_layer
from mail.models import Email, EventAddress from mail.models import Email, EventAddress
from notify_sessions.models import SystemEvent from notify_sessions.models import SystemEvent
from tickets.models import IssueThread from tickets.models import IssueThread, StateChange
def collect_references(issue_thread): def collect_references(issue_thread):
@ -49,9 +49,10 @@ async def send_smtp(message, log):
def find_active_issue_thread(in_reply_to, subject=None): def find_active_issue_thread(in_reply_to, subject=None):
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 return reply_to.first().issue_thread, False
else: else:
return IssueThread.objects.create(name=subject) issue = IssueThread.objects.create(name=subject)
return issue, True
class LMTPHandler: class LMTPHandler:
@ -111,7 +112,7 @@ class LMTPHandler:
except EventAddress.DoesNotExist: except EventAddress.DoesNotExist:
pass pass
active_issue_thread = await sync_to_async(find_active_issue_thread)(header_in_reply_to, subject) active_issue_thread, new = await sync_to_async(find_active_issue_thread)(header_in_reply_to, subject)
email = await sync_to_async(Email.objects.create)(sender=sender, email = await sync_to_async(Email.objects.create)(sender=sender,
recipient=recipient, recipient=recipient,
@ -125,26 +126,26 @@ class LMTPHandler:
log.info(f"Created email {email.id}") log.info(f"Created email {email.id}")
systemevent = await sync_to_async(SystemEvent.objects.create)(type='email received', reference=email.id) systemevent = await sync_to_async(SystemEvent.objects.create)(type='email received', reference=email.id)
log.info(f"Created system event {systemevent.id}") log.info(f"Created system event {systemevent.id}")
state_change = await sync_to_async(
active_issue_thread.state_changes.create)(state='new', issue_thread=active_issue_thread)
channel_layer = get_channel_layer() channel_layer = get_channel_layer()
await channel_layer.group_send( await channel_layer.group_send(
'general', {"type": "generic.event", "name": "send_message_to_frontend", "event_id": systemevent.id, 'general', {"type": "generic.event", "name": "send_message_to_frontend", "event_id": systemevent.id,
"message": "email received"} "message": "email received"}
) )
log.info(f"Sent message to frontend") log.info(f"Sent message to frontend")
if new:
await sync_to_async(StateChange.objects.create)(issue_thread=active_issue_thread, state='new')
references = await sync_to_async(collect_references)(active_issue_thread) references = await sync_to_async(collect_references)(active_issue_thread)
reply_email = await sync_to_async(Email.objects.create)(sender=recipient, # "noreply@" + MAIL_DOMAIN, reply_email = await sync_to_async(Email.objects.create)(sender=recipient, # "noreply@" + MAIL_DOMAIN,
recipient=sender, recipient=sender,
body="Thank you for your message.", body="Thank you for your message.",
subject="Message received", subject="Message received",
in_reply_to=header_message_id, in_reply_to=header_message_id,
event=target_event, event=target_event,
issue_thread=active_issue_thread) issue_thread=active_issue_thread)
await send_smtp(make_reply(reply_email, references), log) await send_smtp(make_reply(reply_email, references), log)
log.info("Sent reply") log.info("Sent auto reply")
return '250 Message accepted for delivery' return '250 Message accepted for delivery'
except Exception as e: except Exception as e:

View file

@ -121,9 +121,9 @@ class LMTPHandlerTestCase(TestCase): # TODO replace with less hacky test
f'In-Reply-To: {mail1_reply.reference}'.encode('utf-8') + b'\n\ntest') f'In-Reply-To: {mail1_reply.reference}'.encode('utf-8') + b'\n\ntest')
result = async_to_sync(handler.handle_DATA)(server, session, envelope) result = async_to_sync(handler.handle_DATA)(server, session, envelope)
self.assertEqual(result, '250 Message accepted for delivery') self.assertEqual(result, '250 Message accepted for delivery')
self.assertEqual(len(Email.objects.all()), 4) self.assertEqual(len(Email.objects.all()), 3)
self.assertEqual(len(IssueThread.objects.all()), 1) self.assertEqual(len(IssueThread.objects.all()), 1)
aiosmtplib.send.assert_called_once() aiosmtplib.send.assert_not_called()
self.assertEqual(Email.objects.all()[2].subject, 'Re: test') self.assertEqual(Email.objects.all()[2].subject, 'Re: test')
self.assertEqual(Email.objects.all()[2].sender, 'test1@test') self.assertEqual(Email.objects.all()[2].sender, 'test1@test')
self.assertEqual(Email.objects.all()[2].recipient, 'test2@test') self.assertEqual(Email.objects.all()[2].recipient, 'test2@test')
@ -131,14 +131,6 @@ class LMTPHandlerTestCase(TestCase): # TODO replace with less hacky test
self.assertEqual(Email.objects.all()[2].issue_thread, issue_thread) self.assertEqual(Email.objects.all()[2].issue_thread, issue_thread)
self.assertEqual(Email.objects.all()[2].reference, '<3@test>') self.assertEqual(Email.objects.all()[2].reference, '<3@test>')
self.assertEqual(Email.objects.all()[2].in_reply_to, mail1_reply.reference) self.assertEqual(Email.objects.all()[2].in_reply_to, mail1_reply.reference)
self.assertEqual(Email.objects.all()[3].subject, 'Message received')
self.assertEqual(Email.objects.all()[3].sender, 'test2@test')
self.assertEqual(Email.objects.all()[3].recipient, 'test1@test')
self.assertEqual(Email.objects.all()[3].body, 'Thank you for your message.')
self.assertEqual(Email.objects.all()[3].issue_thread, issue_thread)
self.assertTrue(Email.objects.all()[3].reference.startswith("<"))
self.assertTrue(Email.objects.all()[3].reference.endswith("@localhost>"))
self.assertEqual(Email.objects.all()[3].in_reply_to, "<3@test>")
self.assertEqual(IssueThread.objects.all()[0].name, 'test') self.assertEqual(IssueThread.objects.all()[0].name, 'test')
self.assertEqual(IssueThread.objects.all()[0].state, 'new') self.assertEqual(IssueThread.objects.all()[0].state, 'new')
self.assertEqual(IssueThread.objects.all()[0].assigned_to, None) self.assertEqual(IssueThread.objects.all()[0].assigned_to, None)