ticketfrei3/kibicara/platforms/email/mda.py

83 lines
2.7 KiB
Python
Raw Normal View History

2020-07-15 21:50:24 +00:00
# Copyright (C) 2020 by Maike <maike@systemli.org>
# Copyright (C) 2020 by Cathy Hu <cathy.hu@fau.de>
# Copyright (C) 2020 by Thomas Lindner <tom@dl6tom.de>
#
# SPDX-License-Identifier: 0BSD
from asyncio import run as asyncio_run
from email.parser import BytesParser
from email.policy import default
2020-09-11 20:03:02 +00:00
from email.utils import parseaddr
2020-07-15 21:50:24 +00:00
from fastapi import status
from kibicara.config import args, config
2020-09-11 20:03:02 +00:00
from kibicara.platforms.email.model import Email, EmailSubscribers
2020-07-15 21:50:24 +00:00
from logging import getLogger
from ormantic import NoMatch
from re import sub
from requests import post
from sys import stdin
logger = getLogger(__name__)
class Main:
def __init__(self):
asyncio_run(self.__run())
async def __run(self):
# extract email from the recipient
email_name = args.recipient.lower()
try:
email = await Email.objects.get(name=email_name)
except NoMatch:
logger.error('No recipient with this name')
exit(1)
# read mail from STDIN and parse to EmailMessage object
message = BytesParser(policy=default).parsebytes(stdin.buffer.read())
2020-09-11 20:03:02 +00:00
sender = ''
if message.get('sender'):
sender = message.get('sender')
elif message.get('from'):
sender = message.get('from')
else:
logger.error('No Sender of From header')
exit(1)
sender = parseaddr(sender)[1]
if not sender:
logger.error('Could not parse sender')
exit(1)
maybe_subscriber = await EmailSubscribers.objects.filter(email=sender).all()
2020-09-11 20:19:51 +00:00
if len(maybe_subscriber) != 1 or maybe_subscriber[0].hood.id != email.hood.id:
2020-09-11 20:03:02 +00:00
logger.error('Not a subscriber')
exit(1)
2020-07-15 21:50:24 +00:00
# extract relevant data from mail
text = sub(
r'<[^>]*>',
'',
message.get_body(preferencelist=('plain', 'html')).get_content(),
)
response = post(
'%s/api/hoods/%d/email/messages/' % (config['root_url'], email.hood.pk),
json={'text': text, 'secret': email.secret},
)
if response.status_code == status.HTTP_201_CREATED:
exit(0)
elif response.status_code == status.HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS:
logger.error('Message was\'t accepted: %s' % text)
elif response.status_code == status.HTTP_422_UNPROCESSABLE_ENTITY:
logger.error('Malformed request: %s' % response.json())
elif response.status_code == status.HTTP_401_UNAUTHORIZED:
logger.error('Wrong API secret. kibicara_mda seems to be misconfigured')
else:
logger.error(
'REST-API failed with response status %d' % response.status_code
)
exit(1)