Require production database configuration

This commit is contained in:
SowinskiBraeden committed 2026-06-28 17:52:22 -07:00
1 parent adbc60bfc3
commit 593420f984
3 files changed
+43 -2

No files matched your search

+1 -1
View File
@@ -94,7 +94,7 @@ The app reads these from `.env`:
- `MAIL_PASSWORD`
- `MAIL_DEFAULT_SENDER`
For public deployments, set `APP_ENV=production`. Production mode enables secure cookies and refuses to start with the development `SECRET_KEY`. Set `RATELIMIT_STORAGE_URI` to a shared backend such as Redis so login and signup limits are enforced across processes.
For public deployments, set `APP_ENV=production`. Production mode enables secure cookies and refuses to start with the development `SECRET_KEY` or the local SQLite database. Use PostgreSQL for `DATABASE_URL`, then run `flask --app app db upgrade` during deploy. Set `RATELIMIT_STORAGE_URI` to a shared backend such as Redis so login and signup limits are enforced across processes.
## Site Admin Access
+5 -1
View File
@@ -9,7 +9,7 @@ from flask import Flask, render_template, request
from werkzeug.exceptions import HTTPException
from boker.auth import current_user_id, is_logged_in, is_site_admin, normalize_email
from boker.config import DEFAULT_SECRET_KEY, Config, ProductionConfig
from boker.config import DEFAULT_DATABASE_URL, DEFAULT_SECRET_KEY, Config, ProductionConfig
from boker.db import database_extensions_available, db, init_database
from boker.extensions import csrf, limiter, mail
from boker.routes.account import account_bp
@@ -35,6 +35,10 @@ def create_app(config_overrides: dict | None = None) -> Flask:
if app.config["SESSION_COOKIE_SECURE"] and app.config["SECRET_KEY"] == DEFAULT_SECRET_KEY:
raise RuntimeError("Set SECRET_KEY before running in production.")
if app.config["SESSION_COOKIE_SECURE"]:
database_url = app.config["SQLALCHEMY_DATABASE_URI"]
if database_url == DEFAULT_DATABASE_URL or database_url.startswith("sqlite:"):
raise RuntimeError("Set DATABASE_URL to a production PostgreSQL database before running in production.")
ensure_data_file(app.config["DATA_PATH"])
init_database(app)
+37
View File
@@ -0,0 +1,37 @@
import os
import unittest
from unittest.mock import patch
from app import create_app
class ProductionConfigTests(unittest.TestCase):
def test_production_refuses_default_sqlite_database(self):
with patch.dict(
os.environ,
{"APP_ENV": "production"},
clear=False,
):
with self.assertRaisesRegex(RuntimeError, "DATABASE_URL"):
create_app({"SECRET_KEY": "test-production-secret"})
def test_production_accepts_postgresql_database_url(self):
with patch.dict(
os.environ,
{"APP_ENV": "production"},
clear=False,
):
app = create_app(
{
"SECRET_KEY": "test-production-secret",
"SQLALCHEMY_DATABASE_URI": "postgresql+psycopg://user:password@example.com/dbname",
}
)
self.assertTrue(app.config["SESSION_COOKIE_SECURE"])
self.assertEqual(app.config["SESSION_COOKIE_SAMESITE"], "Strict")
self.assertTrue(app.config["SQLALCHEMY_DATABASE_URI"].startswith("postgresql+psycopg://"))
if __name__ == "__main__":
unittest.main()