aboutsummaryrefslogtreecommitdiff
path: root/gerboweb/deploy/notification_proxy.py
diff options
context:
space:
mode:
Diffstat (limited to 'gerboweb/deploy/notification_proxy.py')
-rw-r--r--gerboweb/deploy/notification_proxy.py89
1 files changed, 89 insertions, 0 deletions
diff --git a/gerboweb/deploy/notification_proxy.py b/gerboweb/deploy/notification_proxy.py
new file mode 100644
index 0000000..ae4d73e
--- /dev/null
+++ b/gerboweb/deploy/notification_proxy.py
@@ -0,0 +1,89 @@
+import smtplib
+import ssl
+import email.utils
+import hmac
+from email.mime.text import MIMEText
+from datetime import datetime
+import functools
+import json
+import binascii
+
+from flask import Flask, request, abort
+
+app = Flask(__name__)
+app.config.from_pyfile('config.py')
+
+smtp_server = "smtp.sendgrid.net"
+port = 465
+
+mail_routes = {}
+def mail_route(name, receiver, subject):
+ def wrap(func):
+ global routes
+ mail_routes[name] = (receiver, subject, func)
+ return func
+ return wrap
+
+
+def authenticate(secret):
+ def wrap(func):
+ func.last_seqnum = 0
+ @functools.wraps(func)
+ def wrapper(*args, **kwargs):
+ if not request.is_json:
+ abort(400)
+
+ if not 'auth' in request.json and 'payload' in request.json:
+ abort(400)
+
+ if not isinstance(request.json['auth'], str):
+ abort(400)
+ their_digest = binascii.unhexlify(request.json['auth'])
+
+ our_digest = hmac.digest(secret.encode('utf-8'), request.json['payload'].encode('utf-8'), 'sha256')
+ if not hmac.compare_digest(their_digest, our_digest):
+ abort(403)
+
+ try:
+ payload = json.loads(request.json['payload'])
+ except:
+ abort(400)
+
+ if not isinstance(payload['seq'], int) or payload['seq'] <= func.last_seqnum:
+ abort(400)
+
+ func.last_seqnum = payload['seq']
+ del payload['seq']
+ return func(payload)
+ return wrapper
+ return wrap
+
+@mail_route('klingel', 'computerstuff@jaseg.de', 'It rang!')
+@authenticate(app.config['SECRET_KLINGEL'])
+def klingel(_):
+ return f'Date: {datetime.utcnow().isoformat()}'
+
+
+@app.route('/notify/<route_name>', methods=['POST'])
+def notify(route_name):
+ try:
+ context = ssl.create_default_context()
+ smtp = smtplib.SMTP_SSL(smtp_server, port)
+ smtp.login('apikey', app.config['SENDGRID_APIKEY'])
+
+ sender = f'{route_name}@{app.config["DOMAIN"]}'
+
+ receiver, subject, func = mail_routes[route_name]
+
+ msg = MIMEText(func() or subject)
+ msg['Subject'] = subject
+ msg['From'] = sender
+ msg['To'] = receiver
+ msg['Date'] = email.utils.formatdate()
+ smtp.sendmail(sender, receiver, msg.as_string())
+ finally:
+ smtp.quit()
+ return 'success'
+
+if __name__ == '__main__':
+ app.run()