252 lines
10 KiB
Python
252 lines
10 KiB
Python
"""
|
||
MCLogger – Site-Admin-Bereich
|
||
Verwaltet alle Gruppen und Nutzer global.
|
||
"""
|
||
from functools import wraps
|
||
from flask import Blueprint, render_template, request, redirect, url_for, session, flash
|
||
import panel_db as db
|
||
|
||
site_admin = Blueprint("site_admin", __name__, url_prefix="/admin")
|
||
|
||
|
||
def admin_required(f):
|
||
@wraps(f)
|
||
def decorated(*args, **kwargs):
|
||
if not session.get("is_site_admin"):
|
||
return redirect(url_for("auth.admin_login"))
|
||
return f(*args, **kwargs)
|
||
return decorated
|
||
|
||
|
||
# ──────────────────────────────────────────────────────────────
|
||
# Dashboard
|
||
# ──────────────────────────────────────────────────────────────
|
||
|
||
@site_admin.route("/")
|
||
@admin_required
|
||
def dashboard():
|
||
try:
|
||
groups = db.list_all_groups() or []
|
||
users = db.list_all_users() or []
|
||
for g in groups:
|
||
try:
|
||
g["has_db"] = db.has_db_configured(g["id"])
|
||
except Exception:
|
||
g["has_db"] = False
|
||
except Exception:
|
||
groups, users = [], []
|
||
stats = {
|
||
"group_count": len(groups),
|
||
"user_count": len(users),
|
||
"db_configured": sum(1 for g in groups if g.get("has_db")),
|
||
"admin_count": sum(1 for u in users if u.get("is_site_admin")),
|
||
}
|
||
return render_template("admin/dashboard.html", groups=groups, users=users, stats=stats)
|
||
|
||
|
||
# ──────────────────────────────────────────────────────────────
|
||
# Gruppen verwalten
|
||
# ──────────────────────────────────────────────────────────────
|
||
|
||
@site_admin.route("/groups")
|
||
@admin_required
|
||
def groups():
|
||
all_groups = db.list_all_groups()
|
||
for g in all_groups:
|
||
g["has_db"] = db.has_db_configured(g["id"])
|
||
return render_template("admin/groups.html", groups=all_groups)
|
||
|
||
|
||
@site_admin.route("/groups/new", methods=["GET", "POST"])
|
||
@admin_required
|
||
def group_new():
|
||
if request.method == "POST":
|
||
name = request.form.get("name", "").strip()
|
||
desc = request.form.get("description", "").strip()
|
||
if not name:
|
||
flash("Group name must not be empty.", "danger")
|
||
elif db.get_group_by_name(name):
|
||
flash("A group with that name already exists.", "danger")
|
||
else:
|
||
db.create_group(name, desc)
|
||
flash(f"Group '{name}' created.", "success")
|
||
return redirect(url_for("site_admin.groups"))
|
||
return render_template("admin/group_edit.html", group=None)
|
||
|
||
|
||
@site_admin.route("/groups/<int:group_id>/edit", methods=["GET", "POST"])
|
||
@admin_required
|
||
def group_edit(group_id):
|
||
group = db.get_group_by_id(group_id)
|
||
if not group:
|
||
flash("Group not found.", "danger")
|
||
return redirect(url_for("site_admin.groups"))
|
||
if request.method == "POST":
|
||
name = request.form.get("name", "").strip()
|
||
desc = request.form.get("description", "").strip()
|
||
if not name:
|
||
flash("Group name must not be empty.", "danger")
|
||
else:
|
||
db.update_group(group_id, name, desc)
|
||
flash("Group updated.", "success")
|
||
return redirect(url_for("site_admin.groups"))
|
||
return render_template("admin/group_edit.html", group=group)
|
||
|
||
|
||
@site_admin.route("/groups/<int:group_id>/delete", methods=["POST"])
|
||
@admin_required
|
||
def group_delete(group_id):
|
||
db.delete_group(group_id)
|
||
flash("Group deleted.", "success")
|
||
return redirect(url_for("site_admin.groups"))
|
||
|
||
|
||
@site_admin.route("/groups/<int:group_id>/members")
|
||
@admin_required
|
||
def group_members(group_id):
|
||
group = db.get_group_by_id(group_id)
|
||
members = db.get_group_members(group_id)
|
||
all_users = db.list_all_users()
|
||
member_ids = {m["id"] for m in members}
|
||
non_members = [u for u in all_users if u["id"] not in member_ids]
|
||
return render_template("admin/group_members.html",
|
||
group=group, members=members, non_members=non_members)
|
||
|
||
|
||
@site_admin.route("/groups/<int:group_id>/members/add", methods=["POST"])
|
||
@admin_required
|
||
def group_member_add(group_id):
|
||
user_id = request.form.get("user_id", type=int)
|
||
role = request.form.get("role", "member")
|
||
if user_id:
|
||
db.add_group_member(user_id, group_id, role)
|
||
flash("Member added.", "success")
|
||
return redirect(url_for("site_admin.group_members", group_id=group_id))
|
||
|
||
|
||
@site_admin.route("/groups/<int:group_id>/members/<int:user_id>/remove", methods=["POST"])
|
||
@admin_required
|
||
def group_member_remove(group_id, user_id):
|
||
db.remove_group_member(user_id, group_id)
|
||
flash("Member removed.", "success")
|
||
return redirect(url_for("site_admin.group_members", group_id=group_id))
|
||
|
||
|
||
@site_admin.route("/groups/<int:group_id>/members/<int:user_id>/toggle-role", methods=["POST"])
|
||
@admin_required
|
||
def group_member_toggle_role(group_id, user_id):
|
||
member = db.get_group_member(user_id, group_id)
|
||
if member:
|
||
import json as _json
|
||
new_role = "member" if member["role"] == "admin" else "admin"
|
||
perms = member["permissions"] if isinstance(member["permissions"], dict) else (_json.loads(member["permissions"]) if member["permissions"] else {})
|
||
db.update_member(user_id, group_id, new_role, perms)
|
||
flash(f"Role changed to '{new_role}'.", "success")
|
||
return redirect(url_for("site_admin.group_members", group_id=group_id))
|
||
|
||
|
||
# ──────────────────────────────────────────────────────────────
|
||
# Nutzer verwalten
|
||
# ──────────────────────────────────────────────────────────────
|
||
|
||
@site_admin.route("/users")
|
||
@admin_required
|
||
def users():
|
||
return render_template("admin/users.html", users=db.list_all_users())
|
||
|
||
|
||
@site_admin.route("/users/new", methods=["GET", "POST"])
|
||
@admin_required
|
||
def user_new():
|
||
if request.method == "POST":
|
||
username = request.form.get("username", "").strip()
|
||
email = request.form.get("email", "").strip()
|
||
password = request.form.get("password", "")
|
||
is_site_admin = request.form.get("is_site_admin") == "1"
|
||
if not username or not email or not password:
|
||
flash("All fields are required.", "danger")
|
||
elif db.get_user_by_username(username):
|
||
flash("Username already taken.", "danger")
|
||
elif db.get_user_by_email(email):
|
||
flash("Email address already in use.", "danger")
|
||
else:
|
||
db.create_user(username, email, password, is_site_admin)
|
||
flash(f"User '{username}' created.", "success")
|
||
return redirect(url_for("site_admin.users"))
|
||
return render_template("admin/user_edit.html", user=None)
|
||
|
||
|
||
@site_admin.route("/users/<int:user_id>/edit", methods=["GET", "POST"])
|
||
@admin_required
|
||
def user_edit(user_id):
|
||
user = db.get_user_by_id(user_id)
|
||
if not user:
|
||
flash("User not found.", "danger")
|
||
return redirect(url_for("site_admin.users"))
|
||
if request.method == "POST":
|
||
username = request.form.get("username", "").strip()
|
||
email = request.form.get("email", "").strip()
|
||
is_site_admin = request.form.get("is_site_admin") == "1"
|
||
new_password = request.form.get("new_password", "")
|
||
existing = db.get_user_by_email(email)
|
||
if existing and existing["id"] != user_id:
|
||
flash("Email address already in use.", "danger")
|
||
return render_template("admin/user_edit.html", user=user)
|
||
db.update_user(user_id, username, email, is_site_admin)
|
||
if new_password:
|
||
db.change_password(user_id, new_password)
|
||
flash("Password changed.", "info")
|
||
flash("User updated.", "success")
|
||
return redirect(url_for("site_admin.users"))
|
||
return render_template("admin/user_edit.html", user=user)
|
||
|
||
|
||
@site_admin.route("/users/<int:user_id>/delete", methods=["POST"])
|
||
@admin_required
|
||
def user_delete(user_id):
|
||
if user_id == session.get("user_id"):
|
||
flash("You cannot delete yourself.", "danger")
|
||
else:
|
||
db.delete_user(user_id)
|
||
flash("User deleted.", "success")
|
||
return redirect(url_for("site_admin.users"))
|
||
|
||
|
||
# ──────────────────────────────────────────────────────────────
|
||
# Als Gruppe anzeigen (Site-Admin liest Gruppen-DB)
|
||
# ──────────────────────────────────────────────────────────────
|
||
|
||
@site_admin.route("/view-group/<int:group_id>")
|
||
@admin_required
|
||
def view_group(group_id):
|
||
"""Site Admin temporarily switches into a group to view its MC data."""
|
||
group = db.get_group_by_id(group_id)
|
||
if not group:
|
||
flash("Group not found.", "danger")
|
||
return redirect(url_for("site_admin.dashboard"))
|
||
if not db.has_db_configured(group_id):
|
||
flash("No database configured for this group.", "warning")
|
||
return redirect(url_for("site_admin.dashboard"))
|
||
# Alle Berechtigungen als Admin
|
||
all_perms = {k: True for k in ["view_dashboard","view_players","view_sessions",
|
||
"view_chat","view_commands","view_deaths","view_blocks",
|
||
"view_proxy","view_server_events","view_perms"]}
|
||
session["group_id"] = group_id
|
||
session["group_name"] = group["name"]
|
||
session["role"] = "admin"
|
||
session["permissions"] = all_perms
|
||
session["admin_viewing"] = True
|
||
return redirect(url_for("panel.dashboard"))
|
||
|
||
|
||
@site_admin.route("/stop-view")
|
||
@admin_required
|
||
def stop_view():
|
||
"""Kehrt zum Site-Admin-Dashboard zurück."""
|
||
session.pop("group_id", None)
|
||
session.pop("group_name", None)
|
||
session.pop("role", None)
|
||
session.pop("permissions", None)
|
||
session.pop("admin_viewing", None)
|
||
return redirect(url_for("site_admin.dashboard"))
|