experimental mail transport

This commit is contained in:
j3d1 2023-11-23 23:17:20 +01:00
parent e43d4837c3
commit d52575aa42
12 changed files with 271 additions and 85 deletions

0
core/lmtp/__init__.py Normal file
View file

50
core/lmtp/protocol.py Normal file
View file

@ -0,0 +1,50 @@
import asyncio
import logging
from helper import create_task
def make_reply(message, to, subject):
from email.message import EmailMessage
from core.settings import MAIL_DOMAIN
reply = EmailMessage()
reply["From"] = "noreply@" + MAIL_DOMAIN
reply["To"] = to
reply["Subject"] = subject
reply.set_content(message)
return reply
async def send_smtp(message):
await asyncio.sleep(30)
import aiosmtplib
log = logging.getLogger('mail.log')
log.info('Sending message to %s' % message['To'])
await aiosmtplib.send(message, hostname="127.0.0.1", port=25, use_tls=False, start_tls=False)
class LMTPHandler:
async def handle_RCPT(self, server, session, envelope, address, rcpt_options):
from core.settings import MAIL_DOMAIN
if not address.endswith('@' + MAIL_DOMAIN):
return '550 not relaying to that domain'
envelope.rcpt_tos.append(address)
return '250 OK'
async def handle_DATA(self, server, session, envelope):
log = logging.getLogger('mail.log')
log.info('Message from %s' % envelope.mail_from)
log.info('Message for %s' % envelope.rcpt_tos)
log.info('Message data:\n')
for ln in envelope.content.decode('utf8', errors='replace').splitlines():
log.info(f'> {ln}'.strip())
log.info('End of message')
create_task(send_smtp(make_reply("Thank you for your message.", envelope.mail_from, 'Message received')))
# asyncio.create_task(send_reply())
return '250 Message accepted for delivery'

31
core/lmtp/socket.py Normal file
View file

@ -0,0 +1,31 @@
from abc import ABCMeta
from aiosmtpd.controller import BaseController, UnixSocketMixin
from aiosmtpd.lmtp import LMTP
class BaseAsyncController(BaseController, metaclass=ABCMeta):
def __init__(
self,
handler,
loop,
**SMTP_parameters,
):
super().__init__(
handler,
loop,
**SMTP_parameters,
)
def serve(self):
return self._create_server()
class UnixSocketLMTPController(UnixSocketMixin, BaseAsyncController):
def factory(self):
return LMTP(self.handler)
def _trigger_server(self): # pragma: no-unixsock
# Prevent confusion on which _trigger_server() to invoke.
# Or so LGTM.com claimed
UnixSocketMixin._trigger_server(self)