Clean up code smells in app.py
/ build (push) Successful in 42s Details

- Cache public key at startup instead of re-serializing per request
- Remove unused url_for import
- Remove unused session["client_id"]
- Narrow bare except Exception to specific exception types
- Use urlencode for calendar URL query params

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
kosma 2026-03-04 15:53:40 +01:00
parent e2b3df52ff
commit 5f7b61eb37
1 changed files with 15 additions and 9 deletions

24
app.py
View File

@ -1,5 +1,6 @@
import argparse import argparse
import base64 import base64
import binascii
import json import json
import secrets import secrets
from urllib.parse import urlencode from urllib.parse import urlencode
@ -7,7 +8,7 @@ from urllib.parse import urlencode
import yaml import yaml
from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import padding, rsa 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 = argparse.ArgumentParser()
parser.add_argument("config", help="Path to configuration file") parser.add_argument("config", help="Path to configuration file")
@ -20,6 +21,10 @@ app = Flask(__name__)
app.secret_key = config["secret_key"] app.secret_key = config["secret_key"]
private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048) 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("/") @app.route("/")
@ -29,15 +34,9 @@ def index():
@app.route("/authorize") @app.route("/authorize")
def authorize(): def authorize():
public_key = private_key.public_key().public_bytes(
serialization.Encoding.PEM,
serialization.PublicFormat.SubjectPublicKeyInfo,
).decode()
nonce = secrets.token_hex(16) nonce = secrets.token_hex(16)
client_id = secrets.token_hex(48) client_id = secrets.token_hex(48)
session["nonce"] = nonce session["nonce"] = nonce
session["client_id"] = client_id
params = { params = {
"auth_redirect": config["redirect_url"], "auth_redirect": config["redirect_url"],
@ -58,16 +57,23 @@ def callback():
try: try:
payload = base64.b64decode(payload_b64) payload = base64.b64decode(payload_b64)
except binascii.Error:
return "Failed to decode payload", 400
try:
data = private_key.decrypt(payload, padding.PKCS1v15()) data = private_key.decrypt(payload, padding.PKCS1v15())
response = json.loads(data) response = json.loads(data)
except Exception: except (ValueError, json.JSONDecodeError):
return "Failed to decrypt or decode payload", 400 return "Failed to decrypt or decode payload", 400
if response.get("nonce") != session.get("nonce"): if response.get("nonce") != session.get("nonce"):
return "Invalid nonce", 400 return "Invalid nonce", 400
key = response["key"] 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( return render_template(
"result.html", "result.html",