fix async bug in mailadress target event lookup

This commit is contained in:
j3d1 2023-12-30 18:33:45 +01:00
parent 68812fe6b9
commit fd7847993b
2 changed files with 66 additions and 12 deletions

View file

@ -90,6 +90,15 @@ def find_active_issue_thread(in_reply_to, subject=None):
return issue, True return issue, True
def find_target_event(address):
try:
address_map = EventAddress.objects.get(address=address)
if address_map.event:
return address_map.event
except EventAddress.DoesNotExist:
pass
return None
class LMTPHandler: class LMTPHandler:
async def handle_RCPT(self, server, session, envelope, address, rcpt_options): async def handle_RCPT(self, server, session, envelope, address, rcpt_options):
from core.settings import MAIL_DOMAIN from core.settings import MAIL_DOMAIN
@ -142,13 +151,7 @@ class LMTPHandler:
subject = parsed.get('Subject') subject = parsed.get('Subject')
subject = unescape_and_decode_quoted_printable(subject) subject = unescape_and_decode_quoted_printable(subject)
subject = unescape_and_decode_base64(subject) subject = unescape_and_decode_base64(subject)
target_event = None target_event = await sync_to_async(find_target_event)(recipient)
try:
address_map = await sync_to_async(EventAddress.objects.get)(address=recipient)
if address_map.event:
target_event = address_map.event
except EventAddress.DoesNotExist:
pass
active_issue_thread, new = 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)
body_decoded = body.decode('utf-8') body_decoded = body.decode('utf-8')

View file

@ -8,9 +8,9 @@ from knox.models import AuthToken
from authentication.models import ExtendedUser from authentication.models import ExtendedUser
from core.settings import MAIL_DOMAIN from core.settings import MAIL_DOMAIN
from inventory.models import Event from inventory.models import Event
from mail.models import Email from mail.models import Email, EventAddress
from mail.protocol import LMTPHandler from mail.protocol import LMTPHandler
from tickets.models import IssueThread from tickets.models import IssueThread, StateChange
def make_mocked_coro(return_value=mock.sentinel, raise_exception=mock.sentinel): def make_mocked_coro(return_value=mock.sentinel, raise_exception=mock.sentinel):
@ -102,9 +102,11 @@ class LMTPHandlerTestCase(TestCase): # TODO replace with less hacky test
self.assertTrue(Email.objects.all()[1].reference.endswith("@localhost>")) self.assertTrue(Email.objects.all()[1].reference.endswith("@localhost>"))
self.assertEqual("<1@test>", Email.objects.all()[1].in_reply_to) self.assertEqual("<1@test>", Email.objects.all()[1].in_reply_to)
self.assertEqual('test', IssueThread.objects.all()[0].name) self.assertEqual('test', IssueThread.objects.all()[0].name)
self.assertEqual('pending_new', IssueThread.objects.all()[0].state) #self.assertEqual('pending_new', IssueThread.objects.all()[0].state)
self.assertEqual(None, IssueThread.objects.all()[0].assigned_to) self.assertEqual(None, IssueThread.objects.all()[0].assigned_to)
states = StateChange.objects.filter(issue_thread=IssueThread.objects.all()[0])
self.assertEqual(1, len(states))
self.assertEqual('pending_new', states[0].state)
def test_handle_quoted_printable(self): def test_handle_quoted_printable(self):
from aiosmtpd.smtp import Envelope from aiosmtpd.smtp import Envelope
from asgiref.sync import async_to_sync from asgiref.sync import async_to_sync
@ -126,7 +128,6 @@ class LMTPHandlerTestCase(TestCase): # TODO replace with less hacky test
self.assertEqual('Text mit Quoted-Printable-Kodierung: äöüß', Email.objects.all()[0].body) self.assertEqual('Text mit Quoted-Printable-Kodierung: äöüß', Email.objects.all()[0].body)
def test_handle_quoted_printable_2(self): def test_handle_quoted_printable_2(self):
#=?UTF-8?Q?suche_M=C3=BCtze?=
from aiosmtpd.smtp import Envelope from aiosmtpd.smtp import Envelope
from asgiref.sync import async_to_sync from asgiref.sync import async_to_sync
import aiosmtplib import aiosmtplib
@ -249,3 +250,53 @@ class LMTPHandlerTestCase(TestCase): # TODO replace with less hacky test
self.assertTrue(Email.objects.all()[2].reference.startswith("<")) self.assertTrue(Email.objects.all()[2].reference.startswith("<"))
self.assertTrue(Email.objects.all()[2].reference.endswith("@localhost>")) self.assertTrue(Email.objects.all()[2].reference.endswith("@localhost>"))
self.assertEqual(Email.objects.all()[2].in_reply_to, mail1.reference) self.assertEqual(Email.objects.all()[2].in_reply_to, mail1.reference)
def test_match_event(self):
event = Event.objects.create(
name="Test event",
slug="test-event",
)
event_address = EventAddress.objects.create(
event=event,
address="test_event@localhost",
)
from aiosmtpd.smtp import Envelope
from asgiref.sync import async_to_sync
import aiosmtplib
aiosmtplib.send = make_mocked_coro()
handler = LMTPHandler()
server = mock.Mock()
session = mock.Mock()
envelope = Envelope()
envelope.mail_from = 'test1@test'
envelope.rcpt_tos = ['test_event@localhost']
envelope.content = b'Subject: test\nFrom: test1@test\nTo: test_event@localhost\nMessage-ID: <1@test>\n\ntest'
result = async_to_sync(handler.handle_DATA)(server, session, envelope)
self.assertEqual(result, '250 Message accepted for delivery')
self.assertEqual(len(Email.objects.all()), 2)
self.assertEqual(len(IssueThread.objects.all()), 1)
aiosmtplib.send.assert_called_once()
self.assertEqual(event, Email.objects.all()[0].event)
self.assertEqual(event, Email.objects.all()[1].event)
self.assertEqual('test', Email.objects.all()[0].subject)
self.assertEqual('Message received', Email.objects.all()[1].subject)
self.assertEqual('test1@test', Email.objects.all()[0].sender)
self.assertEqual('test_event@localhost', Email.objects.all()[0].recipient)
self.assertEqual('test_event@localhost', Email.objects.all()[1].sender)
self.assertEqual('test1@test', Email.objects.all()[1].recipient)
self.assertEqual('test', Email.objects.all()[0].body)
self.assertEqual('Thank you for your message.', Email.objects.all()[1].body)
self.assertEqual(IssueThread.objects.all()[0], Email.objects.all()[0].issue_thread)
self.assertEqual(IssueThread.objects.all()[0], Email.objects.all()[1].issue_thread)
self.assertEqual('<1@test>', Email.objects.all()[0].reference)
self.assertEqual(None, Email.objects.all()[0].in_reply_to)
self.assertTrue(Email.objects.all()[1].reference.startswith("<"))
self.assertTrue(Email.objects.all()[1].reference.endswith("@localhost>"))
self.assertEqual("<1@test>", Email.objects.all()[1].in_reply_to)
self.assertEqual('test', IssueThread.objects.all()[0].name)
self.assertEqual(None, IssueThread.objects.all()[0].assigned_to)
states = StateChange.objects.filter(issue_thread=IssueThread.objects.all()[0])
self.assertEqual(1, len(states))
self.assertEqual('pending_new', states[0].state)