152 lines
6.1 KiB
Python
152 lines
6.1 KiB
Python
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 |