""" Konfigurationsklassen für die MYP Flask-Anwendung. Definiert verschiedene Konfigurationen für Development, Production und Testing. """ import os from datetime import timedelta import secrets class Config: """Basis-Konfigurationsklasse mit gemeinsamen Einstellungen.""" SECRET_KEY = os.environ.get('SECRET_KEY') or secrets.token_hex(32) DATABASE = os.environ.get('DATABASE_PATH', 'instance/myp.db') # Session-Konfiguration SESSION_COOKIE_HTTPONLY = True SESSION_COOKIE_SAMESITE = 'Lax' PERMANENT_SESSION_LIFETIME = timedelta(days=7) # Job-Konfiguration JOB_CHECK_INTERVAL = int(os.environ.get('JOB_CHECK_INTERVAL', '60')) # Sekunden # Tapo-Konfiguration TAPO_USERNAME = os.environ.get('TAPO_USERNAME') TAPO_PASSWORD = os.environ.get('TAPO_PASSWORD') # Logging-Konfiguration LOG_LEVEL = os.environ.get('LOG_LEVEL', 'INFO') LOG_MAX_BYTES = int(os.environ.get('LOG_MAX_BYTES', '10485760')) # 10MB LOG_BACKUP_COUNT = int(os.environ.get('LOG_BACKUP_COUNT', '10')) # Drucker-Konfiguration PRINTERS = os.environ.get('PRINTERS', '{}') # API-Konfiguration API_KEY = os.environ.get('API_KEY') # Rate Limiting RATE_LIMIT_ENABLED = True MAX_REQUESTS_PER_MINUTE = int(os.environ.get('MAX_REQUESTS_PER_MINUTE', '100')) RATE_LIMIT_WINDOW_MINUTES = int(os.environ.get('RATE_LIMIT_WINDOW_MINUTES', '15')) # Security SECURITY_ENABLED = True MAX_CONTENT_LENGTH = 16 * 1024 * 1024 # 16MB @staticmethod def init_app(app): """Initialisierung der Anwendung mit der Konfiguration.""" pass class DevelopmentConfig(Config): """Konfiguration für die Entwicklungsumgebung.""" DEBUG = True TESTING = False # Session-Cookies in Development weniger strikt SESSION_COOKIE_SECURE = False # Kürzere Job-Check-Intervalle für schnellere Entwicklung JOB_CHECK_INTERVAL = int(os.environ.get('JOB_CHECK_INTERVAL', '30')) # Weniger strikte Sicherheit in Development SECURITY_ENABLED = False RATE_LIMIT_ENABLED = False @staticmethod def init_app(app): Config.init_app(app) # Development-spezifische Initialisierung import logging logging.basicConfig(level=logging.DEBUG) class ProductionConfig(Config): """Konfiguration für die Produktionsumgebung.""" DEBUG = False TESTING = False # Sichere Session-Cookies in Production SESSION_COOKIE_SECURE = True SESSION_COOKIE_HTTPONLY = True SESSION_COOKIE_SAMESITE = 'Strict' # Strengere Sicherheitseinstellungen WTF_CSRF_ENABLED = True WTF_CSRF_TIME_LIMIT = None # Längere Job-Check-Intervalle für bessere Performance JOB_CHECK_INTERVAL = int(os.environ.get('JOB_CHECK_INTERVAL', '60')) # Produktions-Sicherheit SECURITY_ENABLED = True RATE_LIMIT_ENABLED = True MAX_REQUESTS_PER_MINUTE = int(os.environ.get('MAX_REQUESTS_PER_MINUTE', '60')) # HTTPS-Enforcement (wenn verfügbar) FORCE_HTTPS = os.environ.get('FORCE_HTTPS', 'False').lower() == 'true' @staticmethod def init_app(app): Config.init_app(app) # Production-spezifische Initialisierung import logging from logging.handlers import RotatingFileHandler, SysLogHandler # Datei-Logging if not os.path.exists('logs'): os.mkdir('logs') file_handler = RotatingFileHandler( 'logs/myp.log', maxBytes=Config.LOG_MAX_BYTES, backupCount=Config.LOG_BACKUP_COUNT ) file_handler.setFormatter(logging.Formatter( '%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d]' )) file_handler.setLevel(logging.INFO) app.logger.addHandler(file_handler) # Error-Logging error_handler = RotatingFileHandler( 'logs/myp-errors.log', maxBytes=Config.LOG_MAX_BYTES, backupCount=Config.LOG_BACKUP_COUNT ) error_handler.setFormatter(logging.Formatter( '%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d]' )) error_handler.setLevel(logging.ERROR) app.logger.addHandler(error_handler) # Security-Logging security_handler = RotatingFileHandler( 'logs/security.log', maxBytes=Config.LOG_MAX_BYTES, backupCount=Config.LOG_BACKUP_COUNT ) security_handler.setFormatter(logging.Formatter( '%(asctime)s SECURITY %(levelname)s: %(message)s [%(name)s]' )) security_handler.setLevel(logging.WARNING) # Security-Logger security_logger = logging.getLogger('security') security_logger.addHandler(security_handler) security_logger.setLevel(logging.WARNING) app.logger.setLevel(logging.INFO) app.logger.info('MYP Backend starting in production mode') # Sicherheits-Middleware registrieren if app.config.get('SECURITY_ENABLED', True): from security import security_middleware security_middleware.init_app(app) class TestingConfig(Config): """Konfiguration für die Testumgebung.""" DEBUG = True TESTING = True # In-Memory-Datenbank für Tests DATABASE = ':memory:' # Deaktiviere CSRF für Tests WTF_CSRF_ENABLED = False # Kürzere Session-Lebensdauer für Tests PERMANENT_SESSION_LIFETIME = timedelta(minutes=5) # Kürzere Job-Check-Intervalle für Tests JOB_CHECK_INTERVAL = 5 # Deaktiviere Sicherheit für Tests SECURITY_ENABLED = False RATE_LIMIT_ENABLED = False @staticmethod def init_app(app): Config.init_app(app) # Konfigurationsmapping config = { 'development': DevelopmentConfig, 'production': ProductionConfig, 'testing': TestingConfig, 'default': DevelopmentConfig }