366 lines
14 KiB
Python

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("/api/update-settings", methods=["POST"])
@login_required
def api_update_settings():
"""API-Endpunkt für Einstellungen-Updates (JSON)"""
return update_settings()
@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