add /ws/2/notify/ socket
This commit is contained in:
parent
97503e91e0
commit
101fa7b69d
10 changed files with 138 additions and 81 deletions
0
core/mail/__init__.py
Normal file
0
core/mail/__init__.py
Normal file
0
core/mail/migrations/__init__.py
Normal file
0
core/mail/migrations/__init__.py
Normal file
69
core/mail/protocol.py
Normal file
69
core/mail/protocol.py
Normal file
|
@ -0,0 +1,69 @@
|
|||
import logging
|
||||
import aiosmtplib
|
||||
|
||||
|
||||
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, 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):
|
||||
import email
|
||||
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')
|
||||
|
||||
try:
|
||||
parsed = email.message_from_bytes(envelope.content)
|
||||
body = ""
|
||||
if parsed.is_multipart():
|
||||
for part in parsed.walk():
|
||||
ctype = part.get_content_type()
|
||||
cdispo = str(part.get('Content-Disposition'))
|
||||
|
||||
# skip any text/plain (txt) attachments
|
||||
if ctype == 'text/plain' and 'attachment' not in cdispo:
|
||||
body = part.get_payload(decode=True)
|
||||
else:
|
||||
log.info("Attachment", ctype, cdispo)
|
||||
else:
|
||||
body = parsed.get_payload(decode=True)
|
||||
log.info(body)
|
||||
|
||||
header_from = parsed.get('From')
|
||||
header_to = parsed.get('To')
|
||||
|
||||
if header_from != envelope.mail_from:
|
||||
log.warning("Header from does not match envelope from")
|
||||
|
||||
if header_to != envelope.rcpt_tos[0]:
|
||||
log.warning("Header to does not match envelope to")
|
||||
|
||||
await send_smtp(make_reply("Thank you for your message.", envelope.mail_from, 'Message received'), log)
|
||||
log.info("Sent reply")
|
||||
return '250 Message accepted for delivery'
|
||||
except Exception as e:
|
||||
log.error(e)
|
||||
return '550 Message rejected'
|
31
core/mail/socket.py
Normal file
31
core/mail/socket.py
Normal 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)
|
0
core/mail/tests/__init__.py
Normal file
0
core/mail/tests/__init__.py
Normal file
0
core/mail/tests/v2/__init__.py
Normal file
0
core/mail/tests/v2/__init__.py
Normal file
Loading…
Add table
Add a link
Reference in a new issue