187 lines
6.9 KiB
Python
187 lines
6.9 KiB
Python
from flask import Blueprint, render_template, request, redirect, url_for, flash, jsonify
|
|
from flask_login import login_required, current_user
|
|
from functools import wraps
|
|
from app.models import User, db
|
|
from werkzeug.security import generate_password_hash
|
|
|
|
admin_bp = Blueprint('admin', __name__, url_prefix='/admin')
|
|
|
|
def admin_required(f):
|
|
@wraps(f)
|
|
@login_required
|
|
def decorated_function(*args, **kwargs):
|
|
if not current_user.is_admin:
|
|
flash('Zugriff verweigert. Administrator-Rechte erforderlich.', 'error')
|
|
return redirect(url_for('main.dashboard'))
|
|
return f(*args, **kwargs)
|
|
return decorated_function
|
|
|
|
@admin_bp.route('/')
|
|
@admin_required
|
|
def admin_dashboard():
|
|
"""Admin Dashboard mit Benutzerübersicht"""
|
|
users = User.query.order_by(User.created_at.desc()).all()
|
|
return render_template('admin/dashboard.html', users=users)
|
|
|
|
@admin_bp.route('/users')
|
|
@admin_required
|
|
def users():
|
|
"""Benutzerverwaltung"""
|
|
users = User.query.order_by(User.created_at.desc()).all()
|
|
return render_template('admin/users.html', users=users)
|
|
|
|
@admin_bp.route('/users/create', methods=['GET', 'POST'])
|
|
@admin_required
|
|
def create_user():
|
|
"""Neuen Benutzer erstellen"""
|
|
if request.method == 'POST':
|
|
username = request.form.get('username', '').strip()
|
|
email = request.form.get('email', '').strip()
|
|
password = request.form.get('password', '').strip()
|
|
is_admin = 'is_admin' in request.form
|
|
|
|
# Validierung
|
|
if not username or not email or not password:
|
|
flash('Alle Felder sind erforderlich.', 'error')
|
|
return render_template('admin/create_user.html')
|
|
|
|
# Prüfe ob Benutzername bereits existiert
|
|
if User.query.filter_by(username=username).first():
|
|
flash('Benutzername bereits vergeben.', 'error')
|
|
return render_template('admin/create_user.html')
|
|
|
|
# Prüfe ob E-Mail bereits existiert
|
|
if User.query.filter_by(email=email).first():
|
|
flash('E-Mail-Adresse bereits vergeben.', 'error')
|
|
return render_template('admin/create_user.html')
|
|
|
|
try:
|
|
# Benutzer erstellen
|
|
user = User(
|
|
username=username,
|
|
email=email,
|
|
is_admin=is_admin
|
|
)
|
|
user.set_password(password)
|
|
|
|
db.session.add(user)
|
|
db.session.commit()
|
|
|
|
flash(f'Benutzer "{username}" erfolgreich erstellt.', 'success')
|
|
return redirect(url_for('admin.users'))
|
|
|
|
except Exception as e:
|
|
db.session.rollback()
|
|
flash(f'Fehler beim Erstellen des Benutzers: {str(e)}', 'error')
|
|
|
|
return render_template('admin/create_user.html')
|
|
|
|
@admin_bp.route('/users/<int:user_id>/edit', methods=['GET', 'POST'])
|
|
@admin_required
|
|
def edit_user(user_id):
|
|
"""Benutzer bearbeiten"""
|
|
user = User.query.get_or_404(user_id)
|
|
|
|
if request.method == 'POST':
|
|
username = request.form.get('username', '').strip()
|
|
email = request.form.get('email', '').strip()
|
|
password = request.form.get('password', '').strip()
|
|
is_admin = 'is_admin' in request.form
|
|
|
|
# Validierung
|
|
if not username or not email:
|
|
flash('Benutzername und E-Mail sind erforderlich.', 'error')
|
|
return render_template('admin/edit_user.html', user=user)
|
|
|
|
# Prüfe ob Benutzername bereits von anderem User verwendet wird
|
|
existing_user = User.query.filter_by(username=username).first()
|
|
if existing_user and existing_user.id != user_id:
|
|
flash('Benutzername bereits vergeben.', 'error')
|
|
return render_template('admin/edit_user.html', user=user)
|
|
|
|
# Prüfe ob E-Mail bereits von anderem User verwendet wird
|
|
existing_email = User.query.filter_by(email=email).first()
|
|
if existing_email and existing_email.id != user_id:
|
|
flash('E-Mail-Adresse bereits vergeben.', 'error')
|
|
return render_template('admin/edit_user.html', user=user)
|
|
|
|
try:
|
|
# Benutzer aktualisieren
|
|
user.username = username
|
|
user.email = email
|
|
user.is_admin = is_admin
|
|
|
|
# Passwort nur ändern wenn angegeben
|
|
if password:
|
|
user.set_password(password)
|
|
|
|
db.session.commit()
|
|
|
|
flash(f'Benutzer "{username}" erfolgreich aktualisiert.', 'success')
|
|
return redirect(url_for('admin.users'))
|
|
|
|
except Exception as e:
|
|
db.session.rollback()
|
|
flash(f'Fehler beim Aktualisieren des Benutzers: {str(e)}', 'error')
|
|
|
|
return render_template('admin/edit_user.html', user=user)
|
|
|
|
@admin_bp.route('/users/<int:user_id>/delete', methods=['POST'])
|
|
@admin_required
|
|
def delete_user(user_id):
|
|
"""Benutzer löschen"""
|
|
user = User.query.get_or_404(user_id)
|
|
|
|
# Verhindere dass der Admin sich selbst löscht
|
|
if user.id == current_user.id:
|
|
flash('Sie können sich nicht selbst löschen.', 'error')
|
|
return redirect(url_for('admin.users'))
|
|
|
|
# Verhindere das Löschen des letzten Admins
|
|
if user.is_admin:
|
|
admin_count = User.query.filter_by(is_admin=True).count()
|
|
if admin_count <= 1:
|
|
flash('Der letzte Administrator kann nicht gelöscht werden.', 'error')
|
|
return redirect(url_for('admin.users'))
|
|
|
|
try:
|
|
username = user.username
|
|
db.session.delete(user)
|
|
db.session.commit()
|
|
|
|
flash(f'Benutzer "{username}" erfolgreich gelöscht.', 'success')
|
|
except Exception as e:
|
|
db.session.rollback()
|
|
flash(f'Fehler beim Löschen des Benutzers: {str(e)}', 'error')
|
|
|
|
return redirect(url_for('admin.users'))
|
|
|
|
@admin_bp.route('/users/<int:user_id>/toggle_admin', methods=['POST'])
|
|
@admin_required
|
|
def toggle_admin(user_id):
|
|
"""Admin-Status umschalten"""
|
|
user = User.query.get_or_404(user_id)
|
|
|
|
# Verhindere dass der Admin sich selbst die Admin-Rechte entzieht
|
|
if user.id == current_user.id and user.is_admin:
|
|
return jsonify({'error': 'Sie können sich nicht selbst die Admin-Rechte entziehen.'}), 400
|
|
|
|
# Verhindere das Entziehen der Admin-Rechte des letzten Admins
|
|
if user.is_admin:
|
|
admin_count = User.query.filter_by(is_admin=True).count()
|
|
if admin_count <= 1:
|
|
return jsonify({'error': 'Der letzte Administrator kann nicht degradiert werden.'}), 400
|
|
|
|
try:
|
|
user.is_admin = not user.is_admin
|
|
db.session.commit()
|
|
|
|
status = 'Administrator' if user.is_admin else 'Benutzer'
|
|
return jsonify({
|
|
'success': True,
|
|
'message': f'{user.username} ist jetzt {status}.',
|
|
'is_admin': user.is_admin
|
|
})
|
|
except Exception as e:
|
|
db.session.rollback()
|
|
return jsonify({'error': str(e)}), 500 |