from flask import Blueprint, render_template, request, redirect, url_for, flash, jsonify from flask_login import login_user, logout_user, current_user, login_required from datetime import datetime from models import User from utils.logging_config import get_logger from models import get_db_session # Logger für Authentifizierung auth_logger = get_logger("auth") # Blueprint erstellen auth_bp = Blueprint('auth', __name__, url_prefix='/auth') @auth_bp.route("/login", methods=["GET", "POST"]) def login(): if current_user.is_authenticated: return redirect(url_for("index")) error = None if request.method == "POST": # Unterscheiden zwischen JSON-Anfragen und normalen Formular-Anfragen is_json_request = request.is_json or request.headers.get('Content-Type') == 'application/json' # Daten je nach Anfrageart auslesen if is_json_request: data = request.get_json() username = data.get("username") password = data.get("password") remember_me = data.get("remember_me", False) else: username = request.form.get("username") password = request.form.get("password") remember_me = request.form.get("remember-me") == "on" if not username or not password: error = "Benutzername und Passwort müssen angegeben werden." if is_json_request: return jsonify({"error": error}), 400 else: try: db_session = get_db_session() # Suche nach Benutzer mit übereinstimmendem Benutzernamen oder E-Mail user = db_session.query(User).filter( (User.username == username) | (User.email == username) ).first() if user and user.check_password(password): login_user(user, remember=remember_me) auth_logger.info(f"Benutzer {username} hat sich angemeldet") next_page = request.args.get("next") db_session.close() if is_json_request: return jsonify({"success": True, "redirect_url": next_page or url_for("index")}) else: if next_page: return redirect(next_page) return redirect(url_for("index")) else: error = "Ungültiger Benutzername oder Passwort." auth_logger.warning(f"Fehlgeschlagener Login-Versuch für Benutzer {username}") db_session.close() if is_json_request: return jsonify({"error": error}), 401 except Exception as e: # Fehlerbehandlung für Datenbankprobleme error = "Anmeldefehler. Bitte versuchen Sie es später erneut." auth_logger.error(f"Fehler bei der Anmeldung: {str(e)}") if is_json_request: return jsonify({"error": error}), 500 return render_template("login.html", error=error) @auth_bp.route("/logout", methods=["GET", "POST"]) @login_required def logout(): username = current_user.username if hasattr(current_user, "username") else "Unbekannt" logout_user() auth_logger.info(f"Benutzer {username} hat sich abgemeldet") # Unterscheiden zwischen JSON-Anfragen und normalen Anfragen if request.is_json or request.headers.get('Content-Type') == 'application/json': return jsonify({"success": True, "redirect_url": url_for("auth.login")}) else: return redirect(url_for("auth.login")) @auth_bp.route("/api/login", methods=["POST"]) def api_login(): """API-Login-Endpunkt für Frontend""" try: data = request.get_json() if not data: return jsonify({"error": "Keine Daten erhalten"}), 400 username = data.get("username") password = data.get("password") remember_me = data.get("remember_me", False) if not username or not password: return jsonify({"error": "Benutzername und Passwort müssen angegeben werden"}), 400 db_session = get_db_session() user = db_session.query(User).filter( (User.username == username) | (User.email == username) ).first() if user and user.check_password(password): login_user(user, remember=remember_me) auth_logger.info(f"API-Login erfolgreich für Benutzer {username}") user_data = { "id": user.id, "username": user.username, "name": user.name, "email": user.email, "is_admin": user.is_admin } db_session.close() return jsonify({ "success": True, "user": user_data, "redirect_url": url_for("index") }) else: auth_logger.warning(f"Fehlgeschlagener API-Login für Benutzer {username}") db_session.close() return jsonify({"error": "Ungültiger Benutzername oder Passwort"}), 401 except Exception as e: auth_logger.error(f"Fehler beim API-Login: {str(e)}") return jsonify({"error": "Anmeldefehler. Bitte versuchen Sie es später erneut"}), 500 @auth_bp.route("/api/callback", methods=["GET", "POST"]) def api_callback(): """OAuth-Callback-Endpunkt für externe Authentifizierung""" try: # Dieser Endpunkt würde für OAuth-Integration verwendet werden # Hier könnte GitHub/OAuth-Code verarbeitet werden # Placeholder für OAuth-Integration return jsonify({ "message": "OAuth-Callback noch nicht implementiert", "redirect_url": url_for("auth.login") }) except Exception as e: auth_logger.error(f"Fehler im OAuth-Callback: {str(e)}") return jsonify({"error": "OAuth-Callback-Fehler"}), 500