ich geh behindert
This commit is contained in:
319
backend/utils/config.py
Normal file
319
backend/utils/config.py
Normal file
@ -0,0 +1,319 @@
|
||||
"""
|
||||
Zentrale Konfiguration für das 3D-Druck-Management-System
|
||||
|
||||
Diese Datei konsolidiert alle Konfigurationseinstellungen aus dem ehemaligen config-Ordner.
|
||||
"""
|
||||
|
||||
import os
|
||||
import json
|
||||
from datetime import timedelta
|
||||
|
||||
# ===== BASIS-KONFIGURATION =====
|
||||
|
||||
def get_env_variable(name: str, default: str = None) -> str:
|
||||
"""
|
||||
Holt eine Umgebungsvariable oder gibt den Standardwert zurück.
|
||||
|
||||
Args:
|
||||
name: Name der Umgebungsvariable
|
||||
default: Standardwert, falls die Variable nicht gesetzt ist
|
||||
|
||||
Returns:
|
||||
str: Wert der Umgebungsvariable oder Standardwert
|
||||
"""
|
||||
return os.environ.get(name, default)
|
||||
|
||||
# Geheimschlüssel für Flask-Sessions und CSRF-Schutz
|
||||
SECRET_KEY = "7445630171969DFAC92C53CEC92E67A9CB2E00B3CB2F"
|
||||
|
||||
# Pfad-Konfiguration
|
||||
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
PROJECT_ROOT = os.path.dirname(BASE_DIR)
|
||||
DATABASE_PATH = os.path.join(BASE_DIR, "instance", "printer_manager.db")
|
||||
|
||||
# ===== SMART PLUG KONFIGURATION =====
|
||||
# TP-Link Tapo P110 Standardkonfiguration
|
||||
TAPO_USERNAME = "till.tomczak@mercedes-benz.com"
|
||||
TAPO_PASSWORD = "744563017196A"
|
||||
|
||||
# Automatische Steckdosen-Erkennung
|
||||
TAPO_AUTO_DISCOVERY = True
|
||||
|
||||
# Standard-Steckdosen-IPs
|
||||
DEFAULT_TAPO_IPS = [
|
||||
"192.168.0.103",
|
||||
"192.168.0.104",
|
||||
"192.168.0.100",
|
||||
"192.168.0.101",
|
||||
"192.168.0.102",
|
||||
"192.168.0.105"
|
||||
]
|
||||
|
||||
# Timeout-Konfiguration für Tapo-Verbindungen
|
||||
TAPO_TIMEOUT = 10 # Sekunden
|
||||
TAPO_RETRY_COUNT = 3 # Anzahl Wiederholungsversuche
|
||||
|
||||
# ===== DRUCKER-KONFIGURATION =====
|
||||
PRINTERS = {
|
||||
"Printer 1": {"ip": "192.168.0.100"},
|
||||
"Printer 2": {"ip": "192.168.0.101"},
|
||||
"Printer 3": {"ip": "192.168.0.102"},
|
||||
"Printer 4": {"ip": "192.168.0.103"},
|
||||
"Printer 5": {"ip": "192.168.0.104"},
|
||||
"Printer 6": {"ip": "192.168.0.106"}
|
||||
}
|
||||
|
||||
# ===== LOGGING-KONFIGURATION =====
|
||||
LOG_DIR = os.path.join(BASE_DIR, "logs")
|
||||
LOG_SUBDIRS = ["app", "scheduler", "auth", "jobs", "printers", "errors", "admin", "admin_api",
|
||||
"user", "kiosk", "guest", "uploads", "sessions", "maintenance", "analytics",
|
||||
"security", "database", "queue_manager", "printer_monitor"]
|
||||
LOG_LEVEL = get_env_variable("LOG_LEVEL", "INFO")
|
||||
LOG_FORMAT = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
|
||||
LOG_DATE_FORMAT = "%Y-%m-%d %H:%M:%S"
|
||||
LOG_FILE_MAX_BYTES = 10 * 1024 * 1024 # 10MB
|
||||
LOG_BACKUP_COUNT = 5
|
||||
|
||||
# ===== FLASK-KONFIGURATION =====
|
||||
FLASK_HOST = get_env_variable("FLASK_HOST", "0.0.0.0")
|
||||
FLASK_PORT = int(get_env_variable("FLASK_PORT", "5000"))
|
||||
FLASK_FALLBACK_PORT = 8080
|
||||
FLASK_DEBUG = get_env_variable("FLASK_DEBUG", "False").lower() in ("true", "1", "yes")
|
||||
SESSION_LIFETIME = timedelta(hours=2)
|
||||
|
||||
# ===== UPLOAD-KONFIGURATION =====
|
||||
UPLOAD_FOLDER = os.path.join(BASE_DIR, "uploads")
|
||||
ALLOWED_EXTENSIONS = {'txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif', 'gcode', '3mf', 'stl', 'obj', 'amf'}
|
||||
MAX_CONTENT_LENGTH = 16 * 1024 * 1024 # 16MB Maximum-Dateigröße
|
||||
MAX_FILE_SIZE = 16 * 1024 * 1024 # 16MB Maximum-Dateigröße für Drag & Drop System
|
||||
|
||||
# ===== UMGEBUNG =====
|
||||
ENVIRONMENT = get_env_variable("MYP_ENVIRONMENT", "development")
|
||||
|
||||
# ===== SSL-KONFIGURATION =====
|
||||
SSL_ENABLED = get_env_variable("MYP_SSL_ENABLED", "False").lower() in ("true", "1", "yes")
|
||||
SSL_CERT_PATH = os.path.join(BASE_DIR, "certs", "myp.crt")
|
||||
SSL_KEY_PATH = os.path.join(BASE_DIR, "certs", "myp.key")
|
||||
SSL_HOSTNAME = get_env_variable("MYP_SSL_HOSTNAME", "localhost")
|
||||
|
||||
# ===== SCHEDULER-KONFIGURATION =====
|
||||
SCHEDULER_INTERVAL = 60 # Sekunden
|
||||
SCHEDULER_ENABLED = get_env_variable("SCHEDULER_ENABLED", "True").lower() in ("true", "1", "yes")
|
||||
|
||||
# ===== DATENBANK-KONFIGURATION =====
|
||||
DATABASE_URL = get_env_variable("DATABASE_URL", f"sqlite:///{DATABASE_PATH}")
|
||||
SQLALCHEMY_DATABASE_URI = DATABASE_URL
|
||||
SQLALCHEMY_TRACK_MODIFICATIONS = False
|
||||
SQLALCHEMY_ENGINE_OPTIONS = {
|
||||
'pool_pre_ping': True,
|
||||
'pool_recycle': 300,
|
||||
'connect_args': {
|
||||
'check_same_thread': False
|
||||
}
|
||||
}
|
||||
|
||||
# ===== SICHERHEITS-KONFIGURATION =====
|
||||
|
||||
# CSRF-Schutz
|
||||
WTF_CSRF_ENABLED = True
|
||||
WTF_CSRF_TIME_LIMIT = 3600 # 1 Stunde
|
||||
|
||||
# Session-Sicherheit
|
||||
SESSION_COOKIE_SECURE = SSL_ENABLED # Nur bei HTTPS
|
||||
SESSION_COOKIE_HTTPONLY = True
|
||||
SESSION_COOKIE_SAMESITE = 'Lax'
|
||||
PERMANENT_SESSION_LIFETIME = SESSION_LIFETIME
|
||||
|
||||
# Sicherheits-Headers
|
||||
SECURITY_HEADERS = {
|
||||
'Content-Security-Policy': (
|
||||
"default-src 'self'; "
|
||||
"script-src 'self' 'unsafe-eval' 'unsafe-inline'; "
|
||||
"script-src-elem 'self' 'unsafe-inline'; "
|
||||
"style-src 'self' 'unsafe-inline'; "
|
||||
"font-src 'self'; "
|
||||
"img-src 'self' data:; "
|
||||
"connect-src 'self'; "
|
||||
"worker-src 'self' blob:; "
|
||||
"frame-src 'none'; "
|
||||
"object-src 'none'; "
|
||||
"base-uri 'self'; "
|
||||
"form-action 'self'; "
|
||||
"frame-ancestors 'none';"
|
||||
),
|
||||
'X-Content-Type-Options': 'nosniff',
|
||||
'X-Frame-Options': 'DENY',
|
||||
'X-XSS-Protection': '1; mode=block',
|
||||
'Referrer-Policy': 'strict-origin-when-cross-origin',
|
||||
'Permissions-Policy': 'geolocation=(), microphone=(), camera=()'
|
||||
}
|
||||
|
||||
# Nur HTTPS-Header wenn SSL aktiviert
|
||||
if SSL_ENABLED:
|
||||
SECURITY_HEADERS['Strict-Transport-Security'] = 'max-age=31536000; includeSubDomains'
|
||||
|
||||
# Rate Limiting
|
||||
RATE_LIMITS = {
|
||||
'default': "200 per day, 50 per hour",
|
||||
'login': "5 per minute",
|
||||
'api': "100 per hour",
|
||||
'admin': "500 per hour"
|
||||
}
|
||||
|
||||
# ===== MAIL-KONFIGURATION (Optional) =====
|
||||
MAIL_SERVER = get_env_variable('MAIL_SERVER')
|
||||
MAIL_PORT = int(get_env_variable('MAIL_PORT', '587'))
|
||||
MAIL_USE_TLS = get_env_variable('MAIL_USE_TLS', 'true').lower() in ['true', 'on', '1']
|
||||
MAIL_USERNAME = get_env_variable('MAIL_USERNAME')
|
||||
MAIL_PASSWORD = get_env_variable('MAIL_PASSWORD')
|
||||
|
||||
# ===== HILFSFUNKTIONEN =====
|
||||
|
||||
def get_log_file(category: str) -> str:
|
||||
"""
|
||||
Gibt den Pfad zur Log-Datei für eine bestimmte Kategorie zurück.
|
||||
|
||||
Args:
|
||||
category: Log-Kategorie
|
||||
|
||||
Returns:
|
||||
str: Pfad zur Log-Datei
|
||||
"""
|
||||
if category not in LOG_SUBDIRS:
|
||||
category = "app"
|
||||
|
||||
return os.path.join(LOG_DIR, category, f"{category}.log")
|
||||
|
||||
def ensure_log_directories():
|
||||
"""Erstellt alle erforderlichen Log-Verzeichnisse."""
|
||||
os.makedirs(LOG_DIR, exist_ok=True)
|
||||
for subdir in LOG_SUBDIRS:
|
||||
os.makedirs(os.path.join(LOG_DIR, subdir), exist_ok=True)
|
||||
|
||||
def ensure_database_directory():
|
||||
"""Erstellt das Datenbank-Verzeichnis."""
|
||||
db_dir = os.path.dirname(DATABASE_PATH)
|
||||
if db_dir:
|
||||
os.makedirs(db_dir, exist_ok=True)
|
||||
|
||||
def ensure_ssl_directory():
|
||||
"""Erstellt das SSL-Verzeichnis, falls es nicht existiert."""
|
||||
ssl_dir = os.path.dirname(SSL_CERT_PATH)
|
||||
if ssl_dir and not os.path.exists(ssl_dir):
|
||||
os.makedirs(ssl_dir, exist_ok=True)
|
||||
|
||||
def ensure_upload_directory():
|
||||
"""Erstellt das Upload-Verzeichnis, falls es nicht existiert."""
|
||||
if not os.path.exists(UPLOAD_FOLDER):
|
||||
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
|
||||
# Unterverzeichnisse erstellen
|
||||
subdirs = ["jobs", "avatars", "assets", "logs", "backups", "temp", "guests"]
|
||||
for subdir in subdirs:
|
||||
os.makedirs(os.path.join(UPLOAD_FOLDER, subdir), exist_ok=True)
|
||||
|
||||
def get_security_headers():
|
||||
"""Gibt die Sicherheits-Headers zurück"""
|
||||
return SECURITY_HEADERS
|
||||
|
||||
def create_simple_ssl_cert():
|
||||
"""
|
||||
Erstellt ein Mercedes-Benz SSL-Zertifikat mit dem SSL-Manager.
|
||||
"""
|
||||
try:
|
||||
from utils.ssl_manager import ssl_manager
|
||||
success = ssl_manager.generate_mercedes_certificate()
|
||||
|
||||
if success:
|
||||
print(f"Mercedes-Benz SSL-Zertifikat erfolgreich erstellt: {SSL_CERT_PATH}")
|
||||
return True
|
||||
else:
|
||||
print("Fehler beim Erstellen des Mercedes-Benz SSL-Zertifikats")
|
||||
return False
|
||||
|
||||
except ImportError as e:
|
||||
print(f"SSL-Manager nicht verfügbar: {e}")
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"Fehler beim Erstellen der SSL-Zertifikate: {e}")
|
||||
return False
|
||||
|
||||
# ===== KONFIGURATIONSKLASSEN FÜR VERSCHIEDENE UMGEBUNGEN =====
|
||||
|
||||
class Config:
|
||||
"""Basis-Konfigurationsklasse"""
|
||||
|
||||
# Alle Attribute aus den Konstanten übernehmen
|
||||
SECRET_KEY = SECRET_KEY
|
||||
DATABASE_URL = DATABASE_URL
|
||||
SQLALCHEMY_DATABASE_URI = SQLALCHEMY_DATABASE_URI
|
||||
SQLALCHEMY_TRACK_MODIFICATIONS = SQLALCHEMY_TRACK_MODIFICATIONS
|
||||
SQLALCHEMY_ENGINE_OPTIONS = SQLALCHEMY_ENGINE_OPTIONS
|
||||
|
||||
UPLOAD_FOLDER = UPLOAD_FOLDER
|
||||
MAX_CONTENT_LENGTH = MAX_CONTENT_LENGTH
|
||||
ALLOWED_EXTENSIONS = ALLOWED_EXTENSIONS
|
||||
|
||||
WTF_CSRF_ENABLED = WTF_CSRF_ENABLED
|
||||
WTF_CSRF_TIME_LIMIT = WTF_CSRF_TIME_LIMIT
|
||||
|
||||
SESSION_COOKIE_SECURE = SESSION_COOKIE_SECURE
|
||||
SESSION_COOKIE_HTTPONLY = SESSION_COOKIE_HTTPONLY
|
||||
SESSION_COOKIE_SAMESITE = SESSION_COOKIE_SAMESITE
|
||||
PERMANENT_SESSION_LIFETIME = PERMANENT_SESSION_LIFETIME
|
||||
|
||||
LOG_LEVEL = LOG_LEVEL
|
||||
LOG_FILE_MAX_BYTES = LOG_FILE_MAX_BYTES
|
||||
LOG_BACKUP_COUNT = LOG_BACKUP_COUNT
|
||||
|
||||
SCHEDULER_ENABLED = SCHEDULER_ENABLED
|
||||
SCHEDULER_INTERVAL = SCHEDULER_INTERVAL
|
||||
|
||||
SSL_ENABLED = SSL_ENABLED
|
||||
SSL_CERT_PATH = SSL_CERT_PATH
|
||||
SSL_KEY_PATH = SSL_KEY_PATH
|
||||
|
||||
DEFAULT_PORT = FLASK_PORT
|
||||
DEFAULT_HOST = FLASK_HOST
|
||||
|
||||
@staticmethod
|
||||
def init_app(app):
|
||||
"""Initialisiert die Anwendung mit dieser Konfiguration."""
|
||||
pass
|
||||
|
||||
class DevelopmentConfig(Config):
|
||||
"""Entwicklungsumgebung-Konfiguration"""
|
||||
DEBUG = True
|
||||
TESTING = False
|
||||
LOG_LEVEL = 'DEBUG'
|
||||
SESSION_COOKIE_SECURE = False
|
||||
WTF_CSRF_ENABLED = False # Für einfacheres API-Testing
|
||||
|
||||
class TestingConfig(Config):
|
||||
"""Test-Umgebung-Konfiguration"""
|
||||
TESTING = True
|
||||
DEBUG = True
|
||||
DATABASE_URL = 'sqlite:///:memory:'
|
||||
SQLALCHEMY_DATABASE_URI = DATABASE_URL
|
||||
WTF_CSRF_ENABLED = False
|
||||
PERMANENT_SESSION_LIFETIME = timedelta(minutes=5)
|
||||
|
||||
class ProductionConfig(Config):
|
||||
"""Produktionsumgebung-Konfiguration"""
|
||||
DEBUG = False
|
||||
TESTING = False
|
||||
SESSION_COOKIE_SECURE = True
|
||||
WTF_CSRF_ENABLED = True
|
||||
LOG_LEVEL = 'WARNING'
|
||||
SSL_ENABLED = True
|
||||
|
||||
# Konfigurationswörterbuch
|
||||
config = {
|
||||
'development': DevelopmentConfig,
|
||||
'testing': TestingConfig,
|
||||
'production': ProductionConfig,
|
||||
'default': DevelopmentConfig
|
||||
}
|
||||
|
||||
def get_config_by_name(config_name):
|
||||
"""Gibt die Konfigurationsklasse nach Name zurück."""
|
||||
return config.get(config_name, config['default'])
|
Reference in New Issue
Block a user