from functools import wraps from flask import session, redirect, url_for, flash, request from datetime import datetime, timedelta from zoneinfo import ZoneInfo import logging from utils.audit import log_audit logger = logging.getLogger(__name__) def login_required(f): @wraps(f) def decorated_function(*args, **kwargs): if 'logged_in' not in session: return redirect(url_for('auth.login')) # Check if session has expired if 'last_activity' in session: last_activity = datetime.fromisoformat(session['last_activity']) time_since_activity = datetime.now(ZoneInfo("Europe/Berlin")).replace(tzinfo=None) - last_activity # Debug logging logger.info(f"Session check for {session.get('username', 'unknown')}: " f"Last activity: {last_activity}, " f"Time since: {time_since_activity.total_seconds()} seconds") if time_since_activity > timedelta(minutes=5): # Session expired - Logout username = session.get('username', 'unbekannt') logger.info(f"Session timeout for user {username} - auto logout") # Audit log for automatic logout (before session.clear()!) try: log_audit('AUTO_LOGOUT', 'session', additional_info={'reason': 'Session timeout (5 minutes)', 'username': username}) except: pass session.clear() flash('Ihre Sitzung ist abgelaufen. Bitte melden Sie sich erneut an.', 'warning') return redirect(url_for('auth.login')) # Activity is NOT automatically updated # Only on explicit user actions (done by heartbeat) return f(*args, **kwargs) return decorated_function