Files
PatchBay/web/patchbay_web/__init__.py
mueller_minki 8e83a98ef4 Initial Awawawa
2026-10-04 09:08:27 +02:00

68 lines
2.1 KiB
Python

"""PatchBay web frontend (runs on the target only)."""
import datetime
import secrets
from flask import Flask, g
from . import api, auth, db, security, views
from .conf import Config
def prepare_config(conf):
"""Replaces a plaintext SysopPassword in the file with its hash."""
pw = conf.get("sysoppassword")
if pw and not security.is_hashed(pw):
conf.update({"SysopPassword": security.hash_password(pw)})
def create_app(conf_path, testing=False):
conf = Config(conf_path)
prepare_config(conf)
db.init(conf.get("database"))
app = Flask(__name__)
conn = db.connect(conf.get("database"))
row = conn.execute("SELECT value FROM settings WHERE key = 'secret_key'").fetchone()
if row:
secret = row[0]
else:
secret = secrets.token_hex(32)
conn.execute("INSERT INTO settings (key, value) VALUES ('secret_key', ?)", (secret,))
conn.close()
app.config.update(
PB_CONF=conf,
PB_DB=conf.get("database"),
SECRET_KEY=secret,
TESTING=testing,
SESSION_COOKIE_NAME="patchbay_session",
SESSION_COOKIE_SECURE=not testing,
SESSION_COOKIE_HTTPONLY=True,
SESSION_COOKIE_SAMESITE="Strict",
PERMANENT_SESSION_LIFETIME=datetime.timedelta(hours=conf.getint("sessionhours", 12)),
MAX_CONTENT_LENGTH=2 * 1024 * 1024,
)
app.register_blueprint(auth.bp)
app.register_blueprint(views.bp)
app.register_blueprint(api.bp)
app.teardown_appcontext(db.close)
@app.context_processor
def inject():
return {"csrf_token": auth.csrf_token, "user": g.get("user")}
@app.after_request
def headers(resp):
resp.headers["Content-Security-Policy"] = (
"default-src 'self'; img-src 'self' data:; style-src 'self'; script-src 'self'; "
"frame-ancestors 'none'; base-uri 'none'; form-action 'self'")
resp.headers["X-Content-Type-Options"] = "nosniff"
resp.headers["Referrer-Policy"] = "no-referrer"
if not testing:
resp.headers["Strict-Transport-Security"] = "max-age=31536000"
return resp
return app