[email] Fix email parsing in kibicara_mda
This commit is contained in:
parent
b8113c59ae
commit
1bfa7b6a41
|
@ -3,6 +3,8 @@
|
|||
# SPDX-License-Identifier: 0BSD
|
||||
|
||||
import email.parser
|
||||
from email.policy import default
|
||||
import email.message
|
||||
import sys
|
||||
import re
|
||||
import requests
|
||||
|
@ -10,43 +12,102 @@ from logging import getLogger
|
|||
from kibicara.model import Hood
|
||||
from kibicara.platforms.email.model import Email
|
||||
import argparse
|
||||
from asyncio import run
|
||||
from fastapi import status
|
||||
from ormantic import NoMatch
|
||||
|
||||
|
||||
async def main():
|
||||
async def async_main(mail=None, hood_name=None):
|
||||
logger = getLogger(__name__)
|
||||
|
||||
# the MDA passes the recipient address as command line argument
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("recipient_address")
|
||||
args = parser.parse_args()
|
||||
if hood_name is None:
|
||||
parser.add_argument("recipient_address")
|
||||
args = parser.parse_args()
|
||||
# extract hood name from the envelope recipient address
|
||||
hood_name = args.recipient_address.split('@')[0].lower()
|
||||
|
||||
# read mail from STDIN
|
||||
mailbytes = bytes(sys.stdin.read())
|
||||
if mail is None:
|
||||
# read mail from STDIN
|
||||
mail = bytes(sys.stdin.read(), encoding='ascii')
|
||||
# parse plaintext to email.EmailMessage object
|
||||
mail = email.parser.BytesParser(policy=default).parsebytes(mail)
|
||||
else:
|
||||
mail = email.parser.Parser(policy=default).parsestr(mail)
|
||||
|
||||
# parse plaintext to email.EmailMessage object
|
||||
myparser = email.parser.BytesParser()
|
||||
mail = myparser.parsebytes(mailbytes)
|
||||
assert type(mail) == email.message.EmailMessage
|
||||
|
||||
# extract relevant data from mail
|
||||
for part in mail.walk():
|
||||
try:
|
||||
text = part.get_body(('plain',))
|
||||
if not text:
|
||||
text = re.sub(r'<[^>]*>', '', part.get_body(('html',)))
|
||||
except Exception:
|
||||
logger.info("No Body in this message part", exc_info=True)
|
||||
if not text:
|
||||
logger.error('No suitable message body')
|
||||
body = mail.get_body(preferencelist=('plain', 'html'))
|
||||
if body['content-type'].subtype == 'plain':
|
||||
text = str(body.get_content())
|
||||
elif body['content-type'].subtype == 'html':
|
||||
text = re.sub(r'<[^>]*>', '', body.get_content())
|
||||
|
||||
try:
|
||||
text = str(text)
|
||||
except UnboundLocalError:
|
||||
print('No suitable message body')
|
||||
exit(1)
|
||||
try:
|
||||
hood = await Hood.objects.get(name=hood_name)
|
||||
except NoMatch:
|
||||
print('No hood with this name')
|
||||
exit(1)
|
||||
# extract hood name from the envelope recipient address
|
||||
hood_name = args.recipient_address.split('@')[0].lower()
|
||||
hood = await Hood.objects.get(name=hood_name)
|
||||
email_row = await Email.objects.get(hood=hood)
|
||||
body = {
|
||||
'text': text,
|
||||
'author': mail.get_unixfrom(),
|
||||
'secret': email_row.secret,
|
||||
}
|
||||
requests.post(
|
||||
'http://localhost:8000/api/hoods/%d/email/messages/' % (hood.id), json=body
|
||||
response = requests.post(
|
||||
'http://localhost:8000/api/hoods/%d/email/messages/' % hood.id, json=body
|
||||
)
|
||||
print("Request sent:")
|
||||
if response.status_code == status.HTTP_201_CREATED:
|
||||
exit(0)
|
||||
elif response.status_code == status.HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS:
|
||||
print("Message was't accepted: " + text)
|
||||
elif response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY:
|
||||
print("Malformed request: " + str(response.json()))
|
||||
elif response.status_code == status.HTTP_401_UNAUTHORIZED:
|
||||
logger.error('Wrong API secret. kibicara_mda seems to be misconfigured')
|
||||
else:
|
||||
print(str(response.status_code))
|
||||
exit(1)
|
||||
|
||||
|
||||
def main():
|
||||
run(async_main())
|
||||
|
||||
|
||||
if __name__.endswith('kibicara_mda'):
|
||||
mail = """From test@example.com Tue Jun 16 15:33:19 2020
|
||||
Return-path: <test@example.com>
|
||||
Envelope-to: hood@localhost
|
||||
Delivery-date: Tue, 16 Jun 2020 15:33:19 +0200
|
||||
Received: from [23.143.35.123] (helo=example.com)
|
||||
by example.com with smtp (Exim 4.89)
|
||||
(envelope-from <test@example.com>)
|
||||
id 1jlC1e-0005ro-PL
|
||||
for hood@localhost; Tue, 16 Jun 2020 15:33:19 +0200
|
||||
Message-ID: <B5F50812.F55DFD8B@example.com>
|
||||
Date: Tue, 16 Jun 2020 06:53:19 -0700
|
||||
Reply-To: "Test" <test@example.com>
|
||||
From: "Test" <test@example.com>
|
||||
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.1.17) Gecko/20080914 Thunderbird/2.0.0.17
|
||||
MIME-Version: 1.0
|
||||
To: <hood@localhost>
|
||||
Subject: Chat: test
|
||||
Content-Type: multipart/mixed; boundary="AqNPlAX243a8sip3B7kXv8UKD8wuti"
|
||||
|
||||
|
||||
--AqNPlAX243a8sip3B7kXv8UKD8wuti
|
||||
Content-Type: text/plain; charset=utf-8
|
||||
|
||||
test
|
||||
|
||||
--AqNPlAX243a8sip3B7kXv8UKD8wuti--
|
||||
"""
|
||||
run(async_main(mail=mail, hood_name='hood'))
|
||||
|
|
|
@ -24,6 +24,7 @@ class EmailBot(Censor):
|
|||
""" Loop which waits for new messages and sends emails to all subscribers. """
|
||||
while True:
|
||||
message = await self.receive()
|
||||
logger.info("Received Email from %s: %s" % (message.author, message.text))
|
||||
for subscriber in EmailSubscribers.objects.filter(hood=self.hood.id):
|
||||
token = to_token(email=subscriber.email, hood=self.hood.id)
|
||||
unsubscribe_link = (
|
||||
|
|
Loading…
Reference in a new issue