import os import time import json import logging import requests from io import BytesIO from datetime import datetime, timedelta from zoneinfo import ZoneInfo from pathlib import Path from flask import Flask, render_template, request, redirect, session, url_for, send_file, jsonify, flash from flask_session import Session from werkzeug.middleware.proxy_fix import ProxyFix from apscheduler.schedulers.background import BackgroundScheduler import pandas as pd from psycopg2.extras import Json # Import our new modules import config from db import get_connection, get_db_connection, get_db_cursor, execute_query from auth.decorators import login_required from auth.password import hash_password, verify_password from auth.two_factor import ( generate_totp_secret, generate_qr_code, verify_totp, generate_backup_codes, hash_backup_code, verify_backup_code ) from auth.rate_limiting import ( get_client_ip, check_ip_blocked, record_failed_attempt, reset_login_attempts, get_login_attempts ) from utils.audit import log_audit from utils.license import generate_license_key, validate_license_key from utils.backup import create_backup, restore_backup, get_or_create_encryption_key from utils.export import ( create_excel_export, format_datetime_for_export, prepare_license_export_data, prepare_customer_export_data, prepare_session_export_data, prepare_audit_export_data ) from models import get_user_by_username app = Flask(__name__) # Load configuration from config module app.config['SECRET_KEY'] = config.SECRET_KEY app.config['SESSION_TYPE'] = config.SESSION_TYPE app.config['JSON_AS_ASCII'] = config.JSON_AS_ASCII app.config['JSONIFY_MIMETYPE'] = config.JSONIFY_MIMETYPE app.config['PERMANENT_SESSION_LIFETIME'] = config.PERMANENT_SESSION_LIFETIME app.config['SESSION_COOKIE_HTTPONLY'] = config.SESSION_COOKIE_HTTPONLY app.config['SESSION_COOKIE_SECURE'] = config.SESSION_COOKIE_SECURE app.config['SESSION_COOKIE_SAMESITE'] = config.SESSION_COOKIE_SAMESITE app.config['SESSION_COOKIE_NAME'] = config.SESSION_COOKIE_NAME app.config['SESSION_REFRESH_EACH_REQUEST'] = config.SESSION_REFRESH_EACH_REQUEST Session(app) # ProxyFix für korrekte IP-Adressen hinter Nginx app.wsgi_app = ProxyFix( app.wsgi_app, x_for=1, x_proto=1, x_host=1, x_prefix=1 ) # Configuration is now loaded from config module # Scheduler für automatische Backups scheduler = BackgroundScheduler() scheduler.start() # Logging konfigurieren logging.basicConfig(level=logging.INFO) # Scheduled Backup Job def scheduled_backup(): """Führt ein geplantes Backup aus""" logging.info("Starte geplantes Backup...") create_backup(backup_type="scheduled", created_by="scheduler") # Scheduler konfigurieren - täglich um 3:00 Uhr scheduler.add_job( scheduled_backup, 'cron', hour=config.SCHEDULER_CONFIG['backup_hour'], minute=config.SCHEDULER_CONFIG['backup_minute'], id='daily_backup', replace_existing=True ) def verify_recaptcha(response): """Verifiziert die reCAPTCHA v2 Response mit Google""" secret_key = config.RECAPTCHA_SECRET_KEY # Wenn kein Secret Key konfiguriert ist, CAPTCHA als bestanden werten (für PoC) if not secret_key: logging.warning("RECAPTCHA_SECRET_KEY nicht konfiguriert - CAPTCHA wird übersprungen") return True # Verifizierung bei Google try: verify_url = 'https://www.google.com/recaptcha/api/siteverify' data = { 'secret': secret_key, 'response': response } # Timeout für Request setzen r = requests.post(verify_url, data=data, timeout=5) result = r.json() # Log für Debugging if not result.get('success'): logging.warning(f"reCAPTCHA Validierung fehlgeschlagen: {result.get('error-codes', [])}") return result.get('success', False) except requests.exceptions.RequestException as e: logging.error(f"reCAPTCHA Verifizierung fehlgeschlagen: {str(e)}") # Bei Netzwerkfehlern CAPTCHA als bestanden werten return True except Exception as e: logging.error(f"Unerwarteter Fehler bei reCAPTCHA: {str(e)}") return False # Now copy all the route handlers from the original file # Starting from line 693...