diff --git a/app.py b/app.py index 890c0c6..a2b6113 100644 --- a/app.py +++ b/app.py @@ -1,5 +1,6 @@ import argparse import base64 +import binascii import json import secrets from urllib.parse import urlencode @@ -7,7 +8,7 @@ from urllib.parse import urlencode import yaml from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives.asymmetric import padding, rsa -from flask import Flask, redirect, render_template, request, session, url_for +from flask import Flask, redirect, render_template, request, session parser = argparse.ArgumentParser() parser.add_argument("config", help="Path to configuration file") @@ -20,6 +21,10 @@ app = Flask(__name__) app.secret_key = config["secret_key"] private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048) +public_key = private_key.public_key().public_bytes( + serialization.Encoding.PEM, + serialization.PublicFormat.SubjectPublicKeyInfo, +).decode() @app.route("/") @@ -29,15 +34,9 @@ def index(): @app.route("/authorize") def authorize(): - public_key = private_key.public_key().public_bytes( - serialization.Encoding.PEM, - serialization.PublicFormat.SubjectPublicKeyInfo, - ).decode() - nonce = secrets.token_hex(16) client_id = secrets.token_hex(48) session["nonce"] = nonce - session["client_id"] = client_id params = { "auth_redirect": config["redirect_url"], @@ -58,16 +57,23 @@ def callback(): try: payload = base64.b64decode(payload_b64) + except binascii.Error: + return "Failed to decode payload", 400 + + try: data = private_key.decrypt(payload, padding.PKCS1v15()) response = json.loads(data) - except Exception: + except (ValueError, json.JSONDecodeError): return "Failed to decrypt or decode payload", 400 if response.get("nonce") != session.get("nonce"): return "Invalid nonce", 400 key = response["key"] - calendar_url = f"{config['forum_url']}/discourse-post-event/events.ics?order=desc&api_key={key}" + calendar_url = ( + f"{config['forum_url']}/discourse-post-event/events.ics?" + + urlencode({"order": "desc", "api_key": key}) + ) return render_template( "result.html",