82 lines
2.9 KiB
Python
82 lines
2.9 KiB
Python
"""Config-Klassen für die Projekt-Hub-App.
|
|
|
|
Liest Werte aus Umgebungsvariablen (.env wird in run.py / wsgi.py via
|
|
python-dotenv geladen). Keine Secrets im Code — alles über die Umgebung.
|
|
"""
|
|
|
|
import os
|
|
|
|
|
|
def _as_bool(value: str | None, default: bool = False) -> bool:
|
|
if value is None:
|
|
return default
|
|
return value.strip().lower() in {"1", "true", "yes", "on"}
|
|
|
|
|
|
class Config:
|
|
"""Basis-Config, gemeinsam für alle Umgebungen."""
|
|
|
|
SECRET_KEY = os.environ.get("SECRET_KEY", "dev-insecure-change-me")
|
|
|
|
# --- Datenbank ---
|
|
# Default landet in der instance/-Datei (Pfad wird in der App-Factory gesetzt,
|
|
# falls hier ein relativer sqlite-Name steht).
|
|
SQLALCHEMY_DATABASE_URI = os.environ.get("DATABASE_URL", "sqlite:///hub.sqlite")
|
|
SQLALCHEMY_TRACK_MODIFICATIONS = False
|
|
|
|
# --- Host / URL ---
|
|
SERVER_NAME = os.environ.get("SERVER_NAME") or None
|
|
PREFERRED_URL_SCHEME = "https"
|
|
|
|
# --- Session-Cookie-Sicherheit ---
|
|
SESSION_COOKIE_HTTPONLY = True
|
|
SESSION_COOKIE_SAMESITE = "Lax"
|
|
# In Produktion über HTTPS erzwingen; in Dev (HTTP) abschaltbar.
|
|
SESSION_COOKIE_SECURE = _as_bool(os.environ.get("SESSION_COOKIE_SECURE"), default=True)
|
|
|
|
# --- Auth ---
|
|
ALLOWED_EMAILS = [
|
|
e.strip().lower()
|
|
for e in os.environ.get("ALLOWED_EMAILS", "").split(",")
|
|
if e.strip()
|
|
]
|
|
LOGIN_CODE_TTL_MINUTES = int(os.environ.get("LOGIN_CODE_TTL_MINUTES", "10"))
|
|
LOGIN_CODE_RATE_LIMIT = os.environ.get("LOGIN_CODE_RATE_LIMIT", "5 per hour")
|
|
|
|
# --- Rate-Limiting (Flask-Limiter) ---
|
|
# Speicher-Backend. Default memory:// (pro Prozess, reicht für Dev/Einzelworker).
|
|
# In Produktion mit mehreren gunicorn-Workern: gemeinsames Backend nötig, sonst
|
|
# zählt jeder Worker eigene Limits. Empfehlung: redis://localhost:6379
|
|
RATELIMIT_STORAGE_URI = os.environ.get("RATELIMIT_STORAGE_URI", "memory://")
|
|
# Restzeit-/Limit-Header in Antworten mitschicken.
|
|
RATELIMIT_HEADERS_ENABLED = True
|
|
|
|
# --- Mail ---
|
|
MAIL_SERVER = os.environ.get("MAIL_SERVER", "127.0.0.1")
|
|
MAIL_PORT = int(os.environ.get("MAIL_PORT", "1025"))
|
|
MAIL_USE_TLS = _as_bool(os.environ.get("MAIL_USE_TLS"))
|
|
MAIL_USE_SSL = _as_bool(os.environ.get("MAIL_USE_SSL"))
|
|
MAIL_USERNAME = os.environ.get("MAIL_USERNAME") or None
|
|
MAIL_PASSWORD = os.environ.get("MAIL_PASSWORD") or None
|
|
MAIL_DEFAULT_SENDER = os.environ.get("MAIL_DEFAULT_SENDER", "hub@example.com")
|
|
|
|
|
|
class DevelopmentConfig(Config):
|
|
DEBUG = True
|
|
SESSION_COOKIE_SECURE = _as_bool(os.environ.get("SESSION_COOKIE_SECURE"), default=False)
|
|
|
|
|
|
class ProductionConfig(Config):
|
|
DEBUG = False
|
|
|
|
|
|
config_by_name = {
|
|
"development": DevelopmentConfig,
|
|
"production": ProductionConfig,
|
|
}
|
|
|
|
|
|
def get_config(name: str | None = None):
|
|
"""Wählt die Config-Klasse anhand von FLASK_ENV (Default: development)."""
|
|
name = name or os.environ.get("FLASK_ENV", "development")
|
|
return config_by_name.get(name, DevelopmentConfig)
|