From 7cb516df1f8c9684e5b42b522083d5b128ec729a Mon Sep 17 00:00:00 2001 From: Raoul Snyman Date: Thu, 21 Oct 2021 22:56:00 -0700 Subject: [PATCH] SMTP forwarding service --- Dockerfile | 6 ++++++ libertyforward.py | 53 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 Dockerfile create mode 100644 libertyforward.py diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..18a5dd1 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,6 @@ +FROM python:alpine + +WORKDIR /usr/src/app +RUN pip install --no-cache requests configargparse xdg https://github.com/aio-libs/aiosmtpd/archive/refs/heads/master.zip +COPY ./mailforward.py . +CMD ["python", "/usr/src/app/mailforward.py"] diff --git a/libertyforward.py b/libertyforward.py new file mode 100644 index 0000000..8caace7 --- /dev/null +++ b/libertyforward.py @@ -0,0 +1,53 @@ +import requests +from asyncio import new_event_loop +from aiosmtpd.controller import UnthreadedController as Controller +from configargparse import ArgParser +from xdg import xdg_config_home + + +def parse_args(): + parser = ArgParser(default_config_files=['/etc/libertyforward/*.conf', + str(xdg_config_home() / 'LibertyTechForce' / 'libertyforward.conf')]) + parser.add('-c', '--config', is_config_file=True, help='config file path', env_var='LF_CONFIG_FILE') + parser.add('--mailer', help='name of the mailer backend to use', env_var='LF_MAILER') + parser.add('--api-token', help='token to use to authenticate against API', env_var='LF_API_TOKEN') + return parser.parse_args() + + +class MailerHandlerMixin: + """Base class for the mail handlers""" + _api_token = None + + @property + def api_token(self): + return self._api_token + + @api_token.setter + def api_token(self, value): + self._api_token = value + + +class KingMailerHandler(MailerHandlerMixin): + + async def handle_DATA(self, server, session, envelope): + payload = { + 'mail_from': envelope.mail_from, + 'rcpt_to': envelope.rcpt_tos, + 'data': envelope.content + } + headers = {'X-Server-API-Key': self.api_token} + response = requests.post('https://api.kingmailer.co/api/v1/send/raw', data=payload, headers=headers) + if response.ok: + return '250 Message accepted for delivery' + else: + return '500 Could not process your message' + + +if __name__ == '__main__': + args = parse_args() + loop = new_event_loop() + handler = KingMailerHandler() + handler.api_token = args.api_token + controller = Controller(handler, hostname='127.0.0.1', port=25, loop=loop) + controller.begin() + loop.run_forever()