Project_Manager/app/config.py
2026-06-26 18:21:22 +02:00

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)