from flask import Blueprint, render_template, request, redirect, url_for, flash, jsonify from flask_login import current_user, login_required from datetime import datetime from utils.logging_config import get_logger from models import User, get_db_session # Logger für Benutzeraktionen user_logger = get_logger("user") # Blueprint erstellen user_bp = Blueprint('user', __name__, url_prefix='/user') @user_bp.route("/profile", methods=["GET"]) @login_required def profile(): """Profil-Seite anzeigen""" user_logger.info(f"Benutzer {current_user.username} hat seine Profilseite aufgerufen") return render_template("profile.html", user=current_user) @user_bp.route("/settings", methods=["GET"]) @login_required def settings(): """Einstellungen-Seite anzeigen""" user_logger.info(f"Benutzer {current_user.username} hat seine Einstellungsseite aufgerufen") return render_template("settings.html", user=current_user) @user_bp.route("/update-profile", methods=["POST"]) @login_required def update_profile(): """Benutzerprofilinformationen aktualisieren""" try: # Überprüfen, ob es sich um eine JSON-Anfrage handelt is_json_request = request.is_json or request.headers.get('Content-Type') == 'application/json' if is_json_request: data = request.get_json() name = data.get("name") email = data.get("email") department = data.get("department") position = data.get("position") phone = data.get("phone") else: name = request.form.get("name") email = request.form.get("email") department = request.form.get("department") position = request.form.get("position") phone = request.form.get("phone") db_session = get_db_session() user = db_session.query(User).filter(User.id == current_user.id).first() if user: # Aktualisiere die Benutzerinformationen if name: user.name = name if email: user.email = email if department: user.department = department if position: user.position = position if phone: user.phone = phone user.updated_at = datetime.now() db_session.commit() user_logger.info(f"Benutzer {current_user.username} hat sein Profil aktualisiert") if is_json_request: return jsonify({ "success": True, "message": "Profil erfolgreich aktualisiert" }) else: flash("Profil erfolgreich aktualisiert", "success") return redirect(url_for("user.profile")) else: error = "Benutzer nicht gefunden." if is_json_request: return jsonify({"error": error}), 404 else: flash(error, "error") return redirect(url_for("user.profile")) except Exception as e: error = f"Fehler beim Aktualisieren des Profils: {str(e)}" user_logger.error(error) if request.is_json: return jsonify({"error": error}), 500 else: flash(error, "error") return redirect(url_for("user.profile")) finally: db_session.close() @user_bp.route("/update-settings", methods=["POST"]) @login_required def update_settings(): """Benutzereinstellungen aktualisieren""" try: # Überprüfen, ob es sich um eine JSON-Anfrage handelt is_json_request = request.is_json or request.headers.get('Content-Type') == 'application/json' # Einstellungen aus der Anfrage extrahieren if is_json_request: data = request.get_json() theme = data.get("theme") reduced_motion = data.get("reduced_motion", False) contrast = data.get("contrast", "normal") notifications = data.get("notifications", {}) privacy = data.get("privacy", {}) else: theme = request.form.get("theme", "system") reduced_motion = request.form.get("reduced_motion") == "on" contrast = request.form.get("contrast", "normal") notifications = { "new_jobs": request.form.get("notify_new_jobs") == "on", "job_updates": request.form.get("notify_job_updates") == "on", "system": request.form.get("notify_system") == "on", "email": request.form.get("notify_email") == "on" } privacy = { "activity_logs": request.form.get("activity_logs") == "on", "two_factor": request.form.get("two_factor") == "on", "auto_logout": request.form.get("auto_logout", "60") } db_session = get_db_session() user = db_session.query(User).filter(User.id == current_user.id).first() if user: # Erstelle ein Einstellungs-Dictionary, das wir als JSON speichern können settings = { "theme": theme, "reduced_motion": reduced_motion, "contrast": contrast, "notifications": notifications, "privacy": privacy, "last_updated": datetime.now().isoformat() } # In einer echten Anwendung würden wir die Einstellungen in der Datenbank speichern # Hier simulieren wir dies durch Aktualisierung des User-Objekts # Wenn die User-Tabelle eine settings-Spalte hat, würden wir diese verwenden # user.settings = json.dumps(settings) # Für Demonstrationszwecke speichern wir die letzten Einstellungen im Session-Cookie # (In einer Produktionsumgebung würde man dies in der Datenbank speichern) from flask import session session['user_settings'] = settings user.updated_at = datetime.now() db_session.commit() user_logger.info(f"Benutzer {current_user.username} hat seine Einstellungen aktualisiert") if is_json_request: return jsonify({ "success": True, "message": "Einstellungen erfolgreich aktualisiert", "settings": settings }) else: flash("Einstellungen erfolgreich aktualisiert", "success") return redirect(url_for("user.settings")) else: error = "Benutzer nicht gefunden." if is_json_request: return jsonify({"error": error}), 404 else: flash(error, "error") return redirect(url_for("user.settings")) except Exception as e: error = f"Fehler beim Aktualisieren der Einstellungen: {str(e)}" user_logger.error(error) if request.is_json: return jsonify({"error": error}), 500 else: flash(error, "error") return redirect(url_for("user.settings")) finally: db_session.close() @user_bp.route("/change-password", methods=["POST"]) @login_required def change_password(): """Benutzerpasswort ändern""" try: # Überprüfen, ob es sich um eine JSON-Anfrage handelt is_json_request = request.is_json or request.headers.get('Content-Type') == 'application/json' if is_json_request: data = request.get_json() current_password = data.get("current_password") new_password = data.get("new_password") confirm_password = data.get("confirm_password") else: current_password = request.form.get("current_password") new_password = request.form.get("new_password") confirm_password = request.form.get("confirm_password") # Prüfen, ob alle Felder ausgefüllt sind if not current_password or not new_password or not confirm_password: error = "Alle Passwortfelder müssen ausgefüllt sein." if is_json_request: return jsonify({"error": error}), 400 else: flash(error, "error") return redirect(url_for("user.profile")) # Prüfen, ob das neue Passwort und die Bestätigung übereinstimmen if new_password != confirm_password: error = "Das neue Passwort und die Bestätigung stimmen nicht überein." if is_json_request: return jsonify({"error": error}), 400 else: flash(error, "error") return redirect(url_for("user.profile")) db_session = get_db_session() user = db_session.query(User).filter(User.id == current_user.id).first() if user and user.check_password(current_password): # Passwort aktualisieren user.set_password(new_password) user.updated_at = datetime.now() db_session.commit() user_logger.info(f"Benutzer {current_user.username} hat sein Passwort geändert") if is_json_request: return jsonify({ "success": True, "message": "Passwort erfolgreich geändert" }) else: flash("Passwort erfolgreich geändert", "success") return redirect(url_for("user.profile")) else: error = "Das aktuelle Passwort ist nicht korrekt." if is_json_request: return jsonify({"error": error}), 401 else: flash(error, "error") return redirect(url_for("user.profile")) except Exception as e: error = f"Fehler beim Ändern des Passworts: {str(e)}" user_logger.error(error) if request.is_json: return jsonify({"error": error}), 500 else: flash(error, "error") return redirect(url_for("user.profile")) finally: db_session.close() @user_bp.route("/export", methods=["GET"]) @login_required def export_user_data(): """Exportiert alle Benutzerdaten als JSON für DSGVO-Konformität""" try: db_session = get_db_session() user = db_session.query(User).filter(User.id == current_user.id).first() if not user: db_session.close() return jsonify({"error": "Benutzer nicht gefunden"}), 404 # Benutzerdaten abrufen from sqlalchemy.orm import joinedload user_data = user.to_dict() # Jobs des Benutzers abrufen from models import Job jobs = db_session.query(Job).filter(Job.user_id == user.id).all() user_data["jobs"] = [job.to_dict() for job in jobs] # Aktivitäten und Einstellungen hinzufügen from flask import session user_data["settings"] = session.get('user_settings', {}) # Persönliche Statistiken user_data["statistics"] = { "total_jobs": len(jobs), "completed_jobs": len([j for j in jobs if j.status == "finished"]), "failed_jobs": len([j for j in jobs if j.status == "failed"]), "account_created": user.created_at.isoformat() if user.created_at else None, "last_login": user.last_login.isoformat() if user.last_login else None } db_session.close() # Daten als JSON-Datei zum Download anbieten from flask import make_response import json response = make_response(json.dumps(user_data, indent=4)) response.headers["Content-Disposition"] = f"attachment; filename=user_data_{user.username}.json" response.headers["Content-Type"] = "application/json" user_logger.info(f"Benutzer {current_user.username} hat seine Daten exportiert") return response except Exception as e: error = f"Fehler beim Exportieren der Benutzerdaten: {str(e)}" user_logger.error(error) return jsonify({"error": error}), 500 @user_bp.route("/profile", methods=["PUT"]) @login_required def update_profile_api(): """API-Endpunkt zum Aktualisieren des Benutzerprofils""" try: if not request.is_json: return jsonify({"error": "Anfrage muss im JSON-Format sein"}), 400 data = request.get_json() db_session = get_db_session() user = db_session.query(User).filter(User.id == current_user.id).first() if not user: db_session.close() return jsonify({"error": "Benutzer nicht gefunden"}), 404 # Aktualisiere nur die bereitgestellten Felder if "name" in data: user.name = data["name"] if "email" in data: user.email = data["email"] if "department" in data: user.department = data["department"] if "position" in data: user.position = data["position"] if "phone" in data: user.phone = data["phone"] if "bio" in data: user.bio = data["bio"] user.updated_at = datetime.now() db_session.commit() # Aktualisierte Benutzerdaten zurückgeben user_data = user.to_dict() db_session.close() user_logger.info(f"Benutzer {current_user.username} hat sein Profil über die API aktualisiert") return jsonify({ "success": True, "message": "Profil erfolgreich aktualisiert", "user": user_data }) except Exception as e: error = f"Fehler beim Aktualisieren des Profils: {str(e)}" user_logger.error(error) return jsonify({"error": error}), 500