Files
MClogger/web/config.py
simon 179a0e1042 modified: web/blueprints/auth.py
modified:   web/blueprints/group_admin.py
	modified:   web/blueprints/site_admin.py
	modified:   web/config.py
	modified:   web/panel_db.py
	modified:   web/templates/admin/audit_log.html
2026-04-15 10:48:37 +02:00

96 lines
4.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
MCLogger Konfiguration
Alle Einstellungen über ENV-Variablen (Coolify-kompatibel).
"""
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:
DEFAULT_SECRET_KEY = "change-me-use-a-long-random-string-min-32-chars"
DEFAULT_PASSWORD_PEPPER = "change-me-global-pepper-secret-never-change"
# ── Flask ──────────────────────────────────────────────────
SECRET_KEY = os.getenv("SECRET_KEY", DEFAULT_SECRET_KEY)
HOST = os.getenv("HOST") or "0.0.0.0"
PORT = int(os.getenv("PORT") or "5000")
DEBUG = _as_bool(os.getenv("DEBUG"), default=False)
# Session-Cookie-Hardening
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_SAMESITE = os.getenv("SESSION_COOKIE_SAMESITE") or "Lax"
SESSION_COOKIE_SECURE = _as_bool(os.getenv("SESSION_COOKIE_SECURE"), default=not DEBUG)
# Erzwingt sichere Secrets in Nicht-Debug-Umgebungen
ENFORCE_SECURE_CONFIG = _as_bool(os.getenv("ENFORCE_SECURE_CONFIG"), default=True)
# ── Panel-Datenbank (Nutzer, Gruppen, Mitgliedschaften) ────
PANEL_DB_HOST = os.getenv("PANEL_DB_HOST") or "localhost"
PANEL_DB_PORT = int(os.getenv("PANEL_DB_PORT") or "3306")
PANEL_DB_USER = os.getenv("PANEL_DB_USER") or "root"
PANEL_DB_PASSWORD = os.getenv("PANEL_DB_PASSWORD") or ""
PANEL_DB_NAME = os.getenv("PANEL_DB_NAME") or "mclogger_panel"
# ── Credentials-Datenbank (verschlüsselte MC-DB-Zugangsdaten) ──
CREDS_DB_HOST = os.getenv("CREDS_DB_HOST") or os.getenv("PANEL_DB_HOST") or "localhost"
CREDS_DB_PORT = int(os.getenv("CREDS_DB_PORT") or os.getenv("PANEL_DB_PORT") or "3306")
CREDS_DB_USER = os.getenv("CREDS_DB_USER") or os.getenv("PANEL_DB_USER") or "root"
CREDS_DB_PASSWORD = os.getenv("CREDS_DB_PASSWORD") or os.getenv("PANEL_DB_PASSWORD") or ""
CREDS_DB_NAME = os.getenv("CREDS_DB_NAME") or "mclogger_creds"
# ── Sicherheit ────────────────────────────────────────────
PASSWORD_PEPPER = os.getenv("PASSWORD_PEPPER", DEFAULT_PASSWORD_PEPPER)
# Generieren: python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
FERNET_KEY = os.getenv("FERNET_KEY", "")
# ── Mail defaults (can be overridden in admin panel) ─────
MAIL_PORT = int(os.getenv("MAIL_PORT") or "587")
MAIL_USE_TLS = _as_bool(os.getenv("MAIL_USE_TLS"), default=True)
MAIL_TIMEOUT = int(os.getenv("MAIL_TIMEOUT") or "15")
# ── Standard-Berechtigungen neuer Gruppenmitglieder ───────
INVITE_EXPIRY_HOURS = int(os.getenv("INVITE_EXPIRY_HOURS") or "72")
INVITE_MAX_ACTIVE_PER_GROUP = int(os.getenv("INVITE_MAX_ACTIVE_PER_GROUP") or "200")
INVITE_RESEND_COOLDOWN_SECONDS = int(os.getenv("INVITE_RESEND_COOLDOWN_SECONDS") or "120")
# ── Audit-Log-Aufbewahrung ────────────────────────────────
# Audit-Log-Einträge, die älter als dieser Wert (in Tagen) sind, werden automatisch gelöscht.
# IP-Adressen gelten als personenbezogene Daten (DSGVO Art. 4 Nr. 1); nach 90 Tagen sollten
# diese nicht mehr benötigt werden. Auf 0 setzen, um automatisches Löschen zu deaktivieren.
AUDIT_LOG_RETENTION_DAYS = int(os.getenv("AUDIT_LOG_RETENTION_DAYS") or "90")
DEFAULT_PERMISSIONS = {
"view_dashboard": True,
"view_players": True,
"view_sessions": True,
"view_chat": True,
"view_commands": True,
"view_deaths": True,
"view_blocks": True,
"view_proxy": False,
"view_server_events": False,
"view_perms": False,
}
@classmethod
def validate_security(cls):
"""Fail-fast, damit unsichere Defaults nicht in Produktion laufen."""
if not cls.ENFORCE_SECURE_CONFIG or cls.DEBUG:
return
issues = []
if cls.SECRET_KEY == cls.DEFAULT_SECRET_KEY:
issues.append("SECRET_KEY must be set to a strong random value.")
if cls.PASSWORD_PEPPER == cls.DEFAULT_PASSWORD_PEPPER:
issues.append("PASSWORD_PEPPER must be set to a strong secret value.")
if not cls.FERNET_KEY:
issues.append("FERNET_KEY must be configured.")
if issues:
raise RuntimeError("Invalid security configuration: " + " ".join(issues))