less spaghetti, more whitelist

This commit is contained in:
Clemens Klug 2018-10-18 09:09:24 +02:00
parent 600b11b700
commit 052df38541

View File

@ -1,12 +1,9 @@
import json import json
from collections import namedtuple
from string import Formatter
from flask import Flask, render_template, request from flask import Flask, render_template, request
from flask_mail import Mail, Message from flask_mail import Mail, Message
from jinja2 import Environment, meta, Template from jinja2 import Environment, meta, Template
Placeholder = namedtuple("Placeholder", ["name", "type", "desc", "default"])
env = Environment() env = Environment()
@ -15,39 +12,45 @@ def load_config(conf="config.json"):
placeholders = [] placeholders = []
for i in config["placeholders"]: for i in config["placeholders"]:
p_h = config["placeholders"][i] p_h = config["placeholders"][i]
p = Placeholder( p = {
name=i, "name": i,
type=p_h.get("type", "text"), "type": p_h.get("type", "text"),
desc=p_h["desc"], "desc": p_h["desc"],
default=p_h.get("default")) "default": p_h.get("default")}
placeholders.append(p) placeholders.append(p)
config.pop("placeholders") config.pop("placeholders")
flat = [] flat = []
whitelist = []
for org in config: for org in config:
target = config[org] target = config[org]
templates = [] templates = []
whitelist.append(config[org]["mail"].lower())
for issue_name in target["templates"]: for issue_name in target["templates"]:
text = target["templates"][issue_name] text = target["templates"][issue_name]
ast = env.parse(text) ast = env.parse(text)
fields = list(meta.find_undeclared_variables(ast)) fields = list(meta.find_undeclared_variables(ast))
#fields = [name for _, name, _, _ in Formatter().parse(text)]
name = f"{org}: {issue_name}" name = f"{org}: {issue_name}"
value = { value = {
"org": org, "org": org,
"name": issue_name, "name": issue_name,
"mail": config[org]["mail"], "mail": config[org]["mail"],
"text": text, "text": text,
"placeholders": [i._asdict() for i in placeholders if i.name in fields] "placeholders": [i for i in placeholders if i["name"] in fields]
} }
flat.append({"name": name, "value": value}) flat.append({"name": name, "value": value})
return flat return flat, whitelist
def missing_fields(fields):
return not all([field in request.form for field in fields])
MAIL_SERVER = "smtp.uni-bamberg.de" MAIL_SERVER = "smtp.uni-bamberg.de"
MAIL_PORT = 587 MAIL_PORT = 587
#TESTING=True #MAIL_DEBUG=True
#MAIL_USE_TLS=True
#MAIL_USE_SSL=True sender_whitelist = [
MAIL_DEBUG=True "@stud.uni-bamberg.de",
"@uni-bamberg.de",
]
app = Flask(__name__) app = Flask(__name__)
app.config.from_object(__name__) app.config.from_object(__name__)
@ -56,7 +59,7 @@ app.config.from_object(__name__)
mail = Mail(app) mail = Mail(app)
issues = load_config() issues, whitelist = load_config()
@app.route("/") @app.route("/")
def index(): def index():
@ -64,28 +67,30 @@ def index():
@app.route("/send", methods=["POST"]) @app.route("/send", methods=["POST"])
def send(): def send():
if all([field in request.form for field in ("text", "sender", "target")]): if missing_fields(("text", "sender", "target")):
text = request.form["text"] print([(field,field in request.form) for field in ("text", "sender", "target")])
print("all fields present") print(request.form)
ast = env.parse(text) return "1"
fields = list(meta.find_undeclared_variables(ast)) print("all fields present")
#fields = [name for _, name, _, _ in Formatter().parse(text)] sender = request.form["sender"].lower()
if None in fields: recipients = [request.form["target"].lower()]
fields.remove(None) text = request.form["text"]
if all([field in request.form for field in fields]): if not any([sender.endswith(white) for white in sender_whitelist]):
values = {field: request.form[field] for field in fields} return f"Whitelist error!"
text = Template(text).render(**values) if any([recip not in whitelist for recip in recipients]):
sender = request.form["sender"] return f"Whitelist error!"
recipients = [request.form["target"]] ast = env.parse(text)
msg = Message("Störungsmeldung", body=text, sender=sender, recipients=recipients) fields = list(meta.find_undeclared_variables(ast))
print(msg) if None in fields:
result = mail.send(msg) fields.remove(None)
if result is None: if missing_fields(fields):
return f"Success! ({result})"
else:
return f"Fail :( ({result})"
print([(field,field in request.form) for field in fields]) print([(field,field in request.form) for field in fields])
return "2" return "2"
print([(field,field in request.form) for field in ("text", "sender", "target")]) values = {field: request.form[field] for field in fields}
print(request.form) text = Template(text).render(**values)
return "1" msg = Message("Störungsmeldung", body=text, sender=sender, recipients=recipients) # TODO: subject?
result = mail.send(msg)
if result is None:
return f"Success! ({result})"
else:
return f"Fail :( ({result})"