feat: Implement frontend production deployment and enhance admin dashboard functionality
This commit is contained in:
@@ -1,2 +0,0 @@
|
||||
# Blueprint package initialization file
|
||||
# Makes the directory a proper Python package
|
@@ -1,559 +0,0 @@
|
||||
from flask import Blueprint, jsonify, request, session, current_app
|
||||
from datetime import datetime, timedelta
|
||||
import logging
|
||||
import uuid
|
||||
import json
|
||||
import os
|
||||
|
||||
from models import User, Job, Printer, SystemLog
|
||||
from database.db_manager import DatabaseManager
|
||||
from flask_login import login_required, current_user
|
||||
|
||||
api_bp = Blueprint('api', __name__, url_prefix='/api')
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@api_bp.route('/jobs')
|
||||
def get_jobs():
|
||||
"""Get jobs with optional filtering"""
|
||||
try:
|
||||
db = DatabaseManager()
|
||||
|
||||
# Get query parameters
|
||||
status = request.args.get('status')
|
||||
limit = request.args.get('limit', type=int)
|
||||
|
||||
# Use a session for proper relationship handling
|
||||
session = db.get_session()
|
||||
|
||||
try:
|
||||
from sqlalchemy.orm import joinedload
|
||||
|
||||
# Get jobs based on filters with eager loading of relationships
|
||||
if status == 'active':
|
||||
jobs_query = session.query(Job).options(
|
||||
joinedload(Job.user),
|
||||
joinedload(Job.printer)
|
||||
).filter(Job.status == 'running')
|
||||
|
||||
jobs = jobs_query.all() or []
|
||||
|
||||
# Also include pending jobs
|
||||
pending_jobs_query = session.query(Job).options(
|
||||
joinedload(Job.user),
|
||||
joinedload(Job.printer)
|
||||
).filter(Job.status == 'pending')
|
||||
|
||||
pending_jobs = pending_jobs_query.all() or []
|
||||
jobs.extend(pending_jobs)
|
||||
else:
|
||||
jobs_query = session.query(Job).options(
|
||||
joinedload(Job.user),
|
||||
joinedload(Job.printer)
|
||||
)
|
||||
jobs = jobs_query.all() or []
|
||||
|
||||
# Apply limit
|
||||
if limit:
|
||||
jobs = jobs[:limit]
|
||||
|
||||
# Format jobs for API response - convert all data while session is open
|
||||
formatted_jobs = []
|
||||
for job in jobs:
|
||||
if hasattr(job, '__dict__'):
|
||||
# Access all relationship data here while the session is still open
|
||||
printer_name = job.printer.name if job.printer else 'Kein Drucker'
|
||||
user_name = job.user.name if job.user else 'Kein Benutzer'
|
||||
|
||||
job_data = {
|
||||
'id': getattr(job, 'id', None),
|
||||
'name': getattr(job, 'name', 'Unbenannter Auftrag'),
|
||||
'status': getattr(job, 'status', 'unknown'),
|
||||
'progress': getattr(job, 'progress', 0),
|
||||
'printer_name': printer_name,
|
||||
'user_name': user_name,
|
||||
'created_at': getattr(job, 'created_at', datetime.now()).isoformat() if hasattr(job, 'created_at') else datetime.now().isoformat(),
|
||||
'estimated_time': getattr(job, 'estimated_time', 0),
|
||||
'print_time': getattr(job, 'print_time', 0)
|
||||
}
|
||||
formatted_jobs.append(job_data)
|
||||
finally:
|
||||
# Always close the session
|
||||
session.close()
|
||||
|
||||
return jsonify(formatted_jobs)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error getting jobs: {str(e)}")
|
||||
return jsonify([])
|
||||
|
||||
@api_bp.route('/printers', methods=['GET'])
|
||||
def get_printers():
|
||||
"""Get all printers"""
|
||||
try:
|
||||
db = DatabaseManager()
|
||||
session = db.get_session()
|
||||
|
||||
try:
|
||||
printers = session.query(Printer).all() or []
|
||||
|
||||
# Format printers for API response
|
||||
formatted_printers = []
|
||||
for printer in printers:
|
||||
printer_data = {
|
||||
'id': printer.id,
|
||||
'name': printer.name,
|
||||
'model': printer.model,
|
||||
'location': printer.location,
|
||||
'mac_address': printer.mac_address,
|
||||
'plug_ip': printer.plug_ip,
|
||||
'status': printer.status,
|
||||
'created_at': printer.created_at.isoformat() if printer.created_at else datetime.now().isoformat()
|
||||
}
|
||||
formatted_printers.append(printer_data)
|
||||
|
||||
return jsonify({'printers': formatted_printers})
|
||||
finally:
|
||||
session.close()
|
||||
except Exception as e:
|
||||
logger.error(f"Error getting printers: {str(e)}")
|
||||
return jsonify({'printers': []})
|
||||
|
||||
@api_bp.route('/printers', methods=['POST'])
|
||||
@login_required
|
||||
def add_printer():
|
||||
"""Add a new printer"""
|
||||
# Überprüfe, ob der Benutzer Admin-Rechte hat
|
||||
if not current_user.is_admin:
|
||||
return jsonify({'error': 'Nur Administratoren können Drucker hinzufügen'}), 403
|
||||
|
||||
try:
|
||||
# Hole die Daten aus dem Request
|
||||
data = request.json
|
||||
if not data:
|
||||
return jsonify({'error': 'Keine Daten erhalten'}), 400
|
||||
|
||||
# Überprüfe, ob alle notwendigen Felder vorhanden sind
|
||||
required_fields = ['name', 'model', 'location', 'mac_address', 'plug_ip']
|
||||
for field in required_fields:
|
||||
if field not in data:
|
||||
return jsonify({'error': f'Feld {field} fehlt'}), 400
|
||||
|
||||
# Erstelle ein neues Printer-Objekt
|
||||
new_printer = Printer(
|
||||
name=data['name'],
|
||||
model=data['model'],
|
||||
location=data['location'],
|
||||
mac_address=data['mac_address'],
|
||||
plug_ip=data['plug_ip'],
|
||||
plug_username='admin', # Default-Werte für Plug-Credentials
|
||||
plug_password='vT6Vsd^p', # Korrektes Passwort für Router-Zugang
|
||||
status='available'
|
||||
)
|
||||
|
||||
# Speichere den Drucker in der Datenbank
|
||||
db = DatabaseManager()
|
||||
session = db.get_session()
|
||||
|
||||
try:
|
||||
session.add(new_printer)
|
||||
session.commit()
|
||||
|
||||
# Gib die Drucker-Daten zurück
|
||||
printer_data = {
|
||||
'id': new_printer.id,
|
||||
'name': new_printer.name,
|
||||
'model': new_printer.model,
|
||||
'location': new_printer.location,
|
||||
'mac_address': new_printer.mac_address,
|
||||
'plug_ip': new_printer.plug_ip,
|
||||
'status': new_printer.status,
|
||||
'created_at': new_printer.created_at.isoformat() if new_printer.created_at else datetime.now().isoformat()
|
||||
}
|
||||
|
||||
return jsonify({'printer': printer_data, 'message': 'Drucker erfolgreich hinzugefügt'}), 201
|
||||
except Exception as e:
|
||||
session.rollback()
|
||||
logger.error(f"Error adding printer: {str(e)}")
|
||||
return jsonify({'error': f'Fehler beim Hinzufügen des Druckers: {str(e)}'}), 500
|
||||
finally:
|
||||
session.close()
|
||||
except Exception as e:
|
||||
logger.error(f"Error adding printer: {str(e)}")
|
||||
return jsonify({'error': f'Fehler beim Hinzufügen des Druckers: {str(e)}'}), 500
|
||||
|
||||
@api_bp.route('/printers/<int:printer_id>', methods=['DELETE'])
|
||||
@login_required
|
||||
def delete_printer(printer_id):
|
||||
"""Delete a printer by ID"""
|
||||
# Überprüfe, ob der Benutzer Admin-Rechte hat
|
||||
if not current_user.is_admin:
|
||||
return jsonify({'error': 'Nur Administratoren können Drucker löschen'}), 403
|
||||
|
||||
try:
|
||||
db = DatabaseManager()
|
||||
session = db.get_session()
|
||||
|
||||
try:
|
||||
# Finde den Drucker
|
||||
printer = session.query(Printer).filter(Printer.id == printer_id).first()
|
||||
if not printer:
|
||||
return jsonify({'error': f'Drucker mit ID {printer_id} nicht gefunden'}), 404
|
||||
|
||||
# Lösche den Drucker
|
||||
session.delete(printer)
|
||||
session.commit()
|
||||
|
||||
return jsonify({'message': 'Drucker erfolgreich gelöscht'}), 200
|
||||
except Exception as e:
|
||||
session.rollback()
|
||||
logger.error(f"Error deleting printer: {str(e)}")
|
||||
return jsonify({'error': f'Fehler beim Löschen des Druckers: {str(e)}'}), 500
|
||||
finally:
|
||||
session.close()
|
||||
except Exception as e:
|
||||
logger.error(f"Error deleting printer: {str(e)}")
|
||||
return jsonify({'error': f'Fehler beim Löschen des Druckers: {str(e)}'}), 500
|
||||
|
||||
# API-Route für Admin-Statistiken
|
||||
@api_bp.route('/admin/stats', methods=['GET'])
|
||||
@login_required
|
||||
def get_admin_stats():
|
||||
if not current_user.is_admin:
|
||||
return jsonify({"error": "Unauthorized"}), 403
|
||||
|
||||
# Statistikdaten sammeln
|
||||
total_users = User.query.count()
|
||||
total_printers = Printer.query.count()
|
||||
active_jobs = Job.query.filter_by(status='running').count()
|
||||
|
||||
# Erfolgsrate berechnen
|
||||
total_completed_jobs = Job.query.filter_by(status='completed').count()
|
||||
total_jobs = Job.query.filter(Job.status.in_(['completed', 'failed'])).count()
|
||||
|
||||
success_rate = "0%"
|
||||
if total_jobs > 0:
|
||||
success_rate = f"{int((total_completed_jobs / total_jobs) * 100)}%"
|
||||
|
||||
# Scheduler-Status (Beispiel)
|
||||
scheduler_status = True # In einer echten Anwendung würde hier der tatsächliche Status geprüft
|
||||
|
||||
# Systeminformationen
|
||||
system_stats = {
|
||||
"cpu_usage": "25%",
|
||||
"memory_usage": "40%",
|
||||
"disk_usage": "30%",
|
||||
"uptime": "3d 12h 45m"
|
||||
}
|
||||
|
||||
# Drucker-Status
|
||||
printer_status = {
|
||||
"available": Printer.query.filter_by(status='available').count(),
|
||||
"busy": Printer.query.filter_by(status='busy').count(),
|
||||
"offline": Printer.query.filter_by(status='offline').count(),
|
||||
"maintenance": Printer.query.filter_by(status='maintenance').count()
|
||||
}
|
||||
|
||||
return jsonify({
|
||||
"total_users": total_users,
|
||||
"total_printers": total_printers,
|
||||
"active_jobs": active_jobs,
|
||||
"success_rate": success_rate,
|
||||
"scheduler_status": scheduler_status,
|
||||
"system_stats": system_stats,
|
||||
"printer_status": printer_status,
|
||||
"last_updated": datetime.now().isoformat()
|
||||
})
|
||||
|
||||
# API-Route für Protokolle
|
||||
@api_bp.route('/logs', methods=['GET'])
|
||||
@login_required
|
||||
def get_logs():
|
||||
if not current_user.is_admin:
|
||||
return jsonify({"error": "Unauthorized"}), 403
|
||||
|
||||
# Logs aus der Datenbank abrufen
|
||||
logs = SystemLog.query.order_by(SystemLog.timestamp.desc()).limit(100).all()
|
||||
|
||||
log_data = []
|
||||
for log in logs:
|
||||
log_data.append({
|
||||
"id": log.id,
|
||||
"timestamp": log.timestamp.isoformat(),
|
||||
"level": log.level,
|
||||
"source": log.source,
|
||||
"message": log.message
|
||||
})
|
||||
|
||||
return jsonify({"logs": log_data})
|
||||
|
||||
# Scheduler-Status abrufen
|
||||
@api_bp.route('/scheduler/status', methods=['GET'])
|
||||
@login_required
|
||||
def get_scheduler_status():
|
||||
if not current_user.is_admin:
|
||||
return jsonify({"error": "Unauthorized"}), 403
|
||||
|
||||
# In einer echten Anwendung würde hier der tatsächliche Status geprüft werden
|
||||
scheduler_active = True
|
||||
|
||||
# Aktuelle Aufgaben (Beispiel)
|
||||
tasks = [
|
||||
{
|
||||
"id": 1,
|
||||
"name": "Druckaufträge verarbeiten",
|
||||
"status": "running",
|
||||
"last_run": datetime.now().isoformat(),
|
||||
"next_run": datetime.now().isoformat()
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "Status-Updates sammeln",
|
||||
"status": "idle",
|
||||
"last_run": datetime.now().isoformat(),
|
||||
"next_run": datetime.now().isoformat()
|
||||
}
|
||||
]
|
||||
|
||||
return jsonify({
|
||||
"active": scheduler_active,
|
||||
"tasks": tasks,
|
||||
"last_updated": datetime.now().isoformat()
|
||||
})
|
||||
|
||||
# Scheduler starten
|
||||
@api_bp.route('/scheduler/start', methods=['POST'])
|
||||
@login_required
|
||||
def start_scheduler():
|
||||
if not current_user.is_admin:
|
||||
return jsonify({"error": "Unauthorized"}), 403
|
||||
|
||||
# In einer echten Anwendung würde hier der Scheduler gestartet werden
|
||||
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"message": "Scheduler started successfully",
|
||||
"active": True
|
||||
})
|
||||
|
||||
# Scheduler stoppen
|
||||
@api_bp.route('/scheduler/stop', methods=['POST'])
|
||||
@login_required
|
||||
def stop_scheduler():
|
||||
if not current_user.is_admin:
|
||||
return jsonify({"error": "Unauthorized"}), 403
|
||||
|
||||
# In einer echten Anwendung würde hier der Scheduler gestoppt werden
|
||||
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"message": "Scheduler stopped successfully",
|
||||
"active": False
|
||||
})
|
||||
|
||||
# Benutzer abrufen
|
||||
@api_bp.route('/users', methods=['GET'])
|
||||
@login_required
|
||||
def get_users():
|
||||
if not current_user.is_admin:
|
||||
return jsonify({"error": "Unauthorized"}), 403
|
||||
|
||||
users = User.query.all()
|
||||
|
||||
result = []
|
||||
for user in users:
|
||||
result.append({
|
||||
'id': user.id,
|
||||
'name': user.name,
|
||||
'email': user.email,
|
||||
'is_admin': user.is_admin,
|
||||
'is_active': user.is_active,
|
||||
'created_at': user.created_at.isoformat()
|
||||
})
|
||||
|
||||
return jsonify({"users": result})
|
||||
|
||||
# Neuen Benutzer hinzufügen
|
||||
@api_bp.route('/users', methods=['POST'])
|
||||
@login_required
|
||||
def add_user():
|
||||
if not current_user.is_admin:
|
||||
return jsonify({"error": "Unauthorized"}), 403
|
||||
|
||||
data = request.json
|
||||
|
||||
if not data:
|
||||
return jsonify({"error": "No data provided"}), 400
|
||||
|
||||
required_fields = ['name', 'email', 'password']
|
||||
for field in required_fields:
|
||||
if field not in data:
|
||||
return jsonify({"error": f"Missing required field: {field}"}), 400
|
||||
|
||||
# Prüfen, ob E-Mail bereits existiert
|
||||
existing_user = User.query.filter_by(email=data['email']).first()
|
||||
if existing_user:
|
||||
return jsonify({"error": "Email already exists"}), 400
|
||||
|
||||
# Neuen Benutzer erstellen
|
||||
user = User(
|
||||
name=data['name'],
|
||||
email=data['email'],
|
||||
is_admin=data.get('role') == 'admin',
|
||||
is_active=data.get('status') == 'active'
|
||||
)
|
||||
user.set_password(data['password'])
|
||||
|
||||
try:
|
||||
db = DatabaseManager()
|
||||
session = db.get_session()
|
||||
session.add(user)
|
||||
session.commit()
|
||||
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"message": "User added successfully",
|
||||
"user": {
|
||||
"id": user.id,
|
||||
"name": user.name,
|
||||
"email": user.email,
|
||||
"is_admin": user.is_admin,
|
||||
"is_active": user.is_active,
|
||||
"created_at": user.created_at.isoformat()
|
||||
}
|
||||
}), 201
|
||||
except Exception as e:
|
||||
db.get_session().rollback()
|
||||
return jsonify({"error": str(e)}), 500
|
||||
|
||||
# Benutzer löschen
|
||||
@api_bp.route('/users/<int:user_id>', methods=['DELETE'])
|
||||
@login_required
|
||||
def delete_user(user_id):
|
||||
if not current_user.is_admin:
|
||||
return jsonify({"error": "Unauthorized"}), 403
|
||||
|
||||
# Benutzer kann sich nicht selbst löschen
|
||||
if current_user.id == user_id:
|
||||
return jsonify({"error": "Cannot delete yourself"}), 400
|
||||
|
||||
user = User.query.get(user_id)
|
||||
|
||||
if not user:
|
||||
return jsonify({"error": "User not found"}), 404
|
||||
|
||||
try:
|
||||
db = DatabaseManager()
|
||||
session = db.get_session()
|
||||
session.delete(user)
|
||||
session.commit()
|
||||
return jsonify({"success": True, "message": "User deleted successfully"})
|
||||
except Exception as e:
|
||||
session.rollback()
|
||||
return jsonify({"error": str(e)}), 500
|
||||
|
||||
# Cache leeren
|
||||
@api_bp.route('/admin/cache/clear', methods=['POST'])
|
||||
@login_required
|
||||
def clear_cache():
|
||||
"""Cache leeren"""
|
||||
if not current_user.is_admin:
|
||||
return jsonify({"error": "Unauthorized"}), 403
|
||||
|
||||
try:
|
||||
# Hier würde normalerweise der Cache geleert werden
|
||||
# Für dieses Beispiel simulieren wir es
|
||||
logger.info(f"Cache cleared by admin user {current_user.name}")
|
||||
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"message": "Cache erfolgreich geleert"
|
||||
})
|
||||
except Exception as e:
|
||||
logger.error(f"Error clearing cache: {str(e)}")
|
||||
return jsonify({"error": f"Fehler beim Leeren des Cache: {str(e)}"}), 500
|
||||
|
||||
# Datenbank optimieren
|
||||
@api_bp.route('/admin/database/optimize', methods=['POST'])
|
||||
@login_required
|
||||
def optimize_database():
|
||||
"""Datenbank optimieren"""
|
||||
if not current_user.is_admin:
|
||||
return jsonify({"error": "Unauthorized"}), 403
|
||||
|
||||
try:
|
||||
# Hier würde normalerweise die Datenbank optimiert werden
|
||||
# Für dieses Beispiel simulieren wir es
|
||||
logger.info(f"Database optimization started by admin user {current_user.name}")
|
||||
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"message": "Datenbank erfolgreich optimiert"
|
||||
})
|
||||
except Exception as e:
|
||||
logger.error(f"Error optimizing database: {str(e)}")
|
||||
return jsonify({"error": f"Fehler bei der Datenbankoptimierung: {str(e)}"}), 500
|
||||
|
||||
# Backup erstellen
|
||||
@api_bp.route('/admin/backup/create', methods=['POST'])
|
||||
@login_required
|
||||
def create_backup():
|
||||
"""Backup erstellen"""
|
||||
if not current_user.is_admin:
|
||||
return jsonify({"error": "Unauthorized"}), 403
|
||||
|
||||
try:
|
||||
# Hier würde normalerweise ein Backup erstellt werden
|
||||
# Für dieses Beispiel simulieren wir es
|
||||
backup_filename = f"backup_{datetime.now().strftime('%Y%m%d_%H%M%S')}.sql"
|
||||
logger.info(f"Backup created: {backup_filename} by admin user {current_user.name}")
|
||||
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"message": f"Backup erfolgreich erstellt: {backup_filename}",
|
||||
"filename": backup_filename
|
||||
})
|
||||
except Exception as e:
|
||||
logger.error(f"Error creating backup: {str(e)}")
|
||||
return jsonify({"error": f"Fehler beim Erstellen des Backups: {str(e)}"}), 500
|
||||
|
||||
# Drucker aktualisieren
|
||||
@api_bp.route('/admin/printers/update', methods=['POST'])
|
||||
@login_required
|
||||
def update_printers():
|
||||
"""Alle Drucker aktualisieren"""
|
||||
if not current_user.is_admin:
|
||||
return jsonify({"error": "Unauthorized"}), 403
|
||||
|
||||
try:
|
||||
# Hier würde normalerweise der Status aller Drucker aktualisiert werden
|
||||
# Für dieses Beispiel simulieren wir es
|
||||
logger.info(f"Printer update initiated by admin user {current_user.name}")
|
||||
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"message": "Alle Drucker wurden erfolgreich aktualisiert"
|
||||
})
|
||||
except Exception as e:
|
||||
logger.error(f"Error updating printers: {str(e)}")
|
||||
return jsonify({"error": f"Fehler beim Aktualisieren der Drucker: {str(e)}"}), 500
|
||||
|
||||
# System neustarten
|
||||
@api_bp.route('/admin/system/restart', methods=['POST'])
|
||||
@login_required
|
||||
def restart_system():
|
||||
"""System neustarten"""
|
||||
if not current_user.is_admin:
|
||||
return jsonify({"error": "Unauthorized"}), 403
|
||||
|
||||
try:
|
||||
# Hier würde normalerweise das System neugestartet werden
|
||||
# Für dieses Beispiel simulieren wir es
|
||||
logger.warning(f"System restart initiated by admin user {current_user.name}")
|
||||
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"message": "System wird neugestartet..."
|
||||
})
|
||||
except Exception as e:
|
||||
logger.error(f"Error restarting system: {str(e)}")
|
||||
return jsonify({"error": f"Fehler beim Neustart des Systems: {str(e)}"}), 500
|
@@ -1,152 +0,0 @@
|
||||
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
|
@@ -1,135 +0,0 @@
|
||||
from flask import Blueprint, request, jsonify, session
|
||||
from werkzeug.security import check_password_hash, generate_password_hash
|
||||
import subprocess
|
||||
import os
|
||||
import logging
|
||||
|
||||
# Logger für Kiosk-Aktivitäten
|
||||
kiosk_logger = logging.getLogger('kiosk')
|
||||
|
||||
# Blueprint erstellen
|
||||
kiosk_bp = Blueprint('kiosk', __name__, url_prefix='/api/kiosk')
|
||||
|
||||
# Sicheres Passwort-Hash für Kiosk-Deaktivierung
|
||||
KIOSK_PASSWORD_HASH = generate_password_hash("744563017196A")
|
||||
|
||||
@kiosk_bp.route('/status', methods=['GET'])
|
||||
def get_kiosk_status():
|
||||
"""Kiosk-Status abrufen."""
|
||||
try:
|
||||
# Prüfen ob Kiosk-Modus aktiv ist
|
||||
kiosk_active = os.path.exists('/tmp/kiosk_active')
|
||||
|
||||
return jsonify({
|
||||
"active": kiosk_active,
|
||||
"message": "Kiosk-Status erfolgreich abgerufen"
|
||||
})
|
||||
except Exception as e:
|
||||
kiosk_logger.error(f"Fehler beim Abrufen des Kiosk-Status: {str(e)}")
|
||||
return jsonify({"error": "Fehler beim Abrufen des Status"}), 500
|
||||
|
||||
|
||||
@kiosk_bp.route('/deactivate', methods=['POST'])
|
||||
def deactivate_kiosk():
|
||||
"""Kiosk-Modus mit Passwort deaktivieren."""
|
||||
try:
|
||||
data = request.get_json()
|
||||
if not data or 'password' not in data:
|
||||
return jsonify({"error": "Passwort erforderlich"}), 400
|
||||
|
||||
password = data['password']
|
||||
|
||||
# Passwort überprüfen
|
||||
if not check_password_hash(KIOSK_PASSWORD_HASH, password):
|
||||
kiosk_logger.warning(f"Fehlgeschlagener Kiosk-Deaktivierungsversuch von IP: {request.remote_addr}")
|
||||
return jsonify({"error": "Ungültiges Passwort"}), 401
|
||||
|
||||
# Kiosk deaktivieren
|
||||
try:
|
||||
# Kiosk-Service stoppen
|
||||
subprocess.run(['sudo', 'systemctl', 'stop', 'myp-kiosk'], check=True)
|
||||
subprocess.run(['sudo', 'systemctl', 'disable', 'myp-kiosk'], check=True)
|
||||
|
||||
# Kiosk-Marker entfernen
|
||||
if os.path.exists('/tmp/kiosk_active'):
|
||||
os.remove('/tmp/kiosk_active')
|
||||
|
||||
# Normale Desktop-Umgebung wiederherstellen
|
||||
subprocess.run(['sudo', 'systemctl', 'set-default', 'graphical.target'], check=True)
|
||||
|
||||
kiosk_logger.info(f"Kiosk-Modus erfolgreich deaktiviert von IP: {request.remote_addr}")
|
||||
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"message": "Kiosk-Modus erfolgreich deaktiviert. System wird neu gestartet."
|
||||
})
|
||||
|
||||
except subprocess.CalledProcessError as e:
|
||||
kiosk_logger.error(f"Fehler beim Deaktivieren des Kiosk-Modus: {str(e)}")
|
||||
return jsonify({"error": "Fehler beim Deaktivieren des Kiosk-Modus"}), 500
|
||||
|
||||
except Exception as e:
|
||||
kiosk_logger.error(f"Unerwarteter Fehler bei Kiosk-Deaktivierung: {str(e)}")
|
||||
return jsonify({"error": "Unerwarteter Fehler"}), 500
|
||||
|
||||
|
||||
@kiosk_bp.route('/activate', methods=['POST'])
|
||||
def activate_kiosk():
|
||||
"""Kiosk-Modus aktivieren (nur für Admins)."""
|
||||
try:
|
||||
# Hier könnte eine Admin-Authentifizierung hinzugefügt werden
|
||||
|
||||
# Kiosk aktivieren
|
||||
try:
|
||||
# Kiosk-Marker setzen
|
||||
with open('/tmp/kiosk_active', 'w') as f:
|
||||
f.write('1')
|
||||
|
||||
# Kiosk-Service aktivieren
|
||||
subprocess.run(['sudo', 'systemctl', 'enable', 'myp-kiosk'], check=True)
|
||||
subprocess.run(['sudo', 'systemctl', 'start', 'myp-kiosk'], check=True)
|
||||
|
||||
kiosk_logger.info(f"Kiosk-Modus erfolgreich aktiviert von IP: {request.remote_addr}")
|
||||
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"message": "Kiosk-Modus erfolgreich aktiviert"
|
||||
})
|
||||
|
||||
except subprocess.CalledProcessError as e:
|
||||
kiosk_logger.error(f"Fehler beim Aktivieren des Kiosk-Modus: {str(e)}")
|
||||
return jsonify({"error": "Fehler beim Aktivieren des Kiosk-Modus"}), 500
|
||||
|
||||
except Exception as e:
|
||||
kiosk_logger.error(f"Unerwarteter Fehler bei Kiosk-Aktivierung: {str(e)}")
|
||||
return jsonify({"error": "Unerwarteter Fehler"}), 500
|
||||
|
||||
|
||||
@kiosk_bp.route('/restart', methods=['POST'])
|
||||
def restart_system():
|
||||
"""System neu starten (nur nach Kiosk-Deaktivierung)."""
|
||||
try:
|
||||
data = request.get_json()
|
||||
if not data or 'password' not in data:
|
||||
return jsonify({"error": "Passwort erforderlich"}), 400
|
||||
|
||||
password = data['password']
|
||||
|
||||
# Passwort überprüfen
|
||||
if not check_password_hash(KIOSK_PASSWORD_HASH, password):
|
||||
kiosk_logger.warning(f"Fehlgeschlagener Neustart-Versuch von IP: {request.remote_addr}")
|
||||
return jsonify({"error": "Ungültiges Passwort"}), 401
|
||||
|
||||
kiosk_logger.info(f"System-Neustart initiiert von IP: {request.remote_addr}")
|
||||
|
||||
# System nach kurzer Verzögerung neu starten
|
||||
subprocess.Popen(['sudo', 'shutdown', '-r', '+1'])
|
||||
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"message": "System wird in 1 Minute neu gestartet"
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
kiosk_logger.error(f"Fehler beim System-Neustart: {str(e)}")
|
||||
return jsonify({"error": "Fehler beim Neustart"}), 500
|
@@ -1,366 +0,0 @@
|
||||
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
|
Reference in New Issue
Block a user