new file: .gitignore
new file: README.md new file: database/schema.sql new file: paper-plugin/pom.xml new file: paper-plugin/src/main/java/de/simolzimol/mclogger/paper/PaperLoggerPlugin.java new file: paper-plugin/src/main/java/de/simolzimol/mclogger/paper/commands/MCLoggerCommand.java new file: paper-plugin/src/main/java/de/simolzimol/mclogger/paper/database/DatabaseManager.java new file: paper-plugin/src/main/java/de/simolzimol/mclogger/paper/listeners/BlockListener.java new file: paper-plugin/src/main/java/de/simolzimol/mclogger/paper/listeners/EntityListener.java new file: paper-plugin/src/main/java/de/simolzimol/mclogger/paper/listeners/InventoryListener.java new file: paper-plugin/src/main/java/de/simolzimol/mclogger/paper/listeners/LuckPermsListener.java new file: paper-plugin/src/main/java/de/simolzimol/mclogger/paper/listeners/PlayerChatCommandListener.java new file: paper-plugin/src/main/java/de/simolzimol/mclogger/paper/listeners/PlayerDeathListener.java new file: paper-plugin/src/main/java/de/simolzimol/mclogger/paper/listeners/PlayerMiscListener.java new file: paper-plugin/src/main/java/de/simolzimol/mclogger/paper/listeners/PlayerSessionListener.java new file: paper-plugin/src/main/java/de/simolzimol/mclogger/paper/listeners/WorldListener.java new file: paper-plugin/src/main/resources/config.yml new file: paper-plugin/src/main/resources/plugin.yml new file: paper-plugin/target/classes/config.yml new file: paper-plugin/target/classes/de/simolzimol/mclogger/paper/PaperLoggerPlugin.class new file: paper-plugin/target/classes/de/simolzimol/mclogger/paper/commands/MCLoggerCommand$RsConsumer.class new file: paper-plugin/target/classes/de/simolzimol/mclogger/paper/commands/MCLoggerCommand.class new file: paper-plugin/target/classes/de/simolzimol/mclogger/paper/database/DatabaseManager$ThrowingRunnable.class new file: paper-plugin/target/classes/de/simolzimol/mclogger/paper/database/DatabaseManager.class new file: paper-plugin/target/classes/de/simolzimol/mclogger/paper/listeners/BlockListener.class new file: paper-plugin/target/classes/de/simolzimol/mclogger/paper/listeners/EntityListener.class new file: paper-plugin/target/classes/de/simolzimol/mclogger/paper/listeners/InventoryListener.class new file: paper-plugin/target/classes/de/simolzimol/mclogger/paper/listeners/LuckPermsListener.class new file: paper-plugin/target/classes/de/simolzimol/mclogger/paper/listeners/PlayerChatCommandListener.class new file: paper-plugin/target/classes/de/simolzimol/mclogger/paper/listeners/PlayerDeathListener.class new file: paper-plugin/target/classes/de/simolzimol/mclogger/paper/listeners/PlayerMiscListener.class new file: paper-plugin/target/classes/de/simolzimol/mclogger/paper/listeners/PlayerSessionListener.class new file: paper-plugin/target/classes/de/simolzimol/mclogger/paper/listeners/WorldListener.class new file: paper-plugin/target/classes/plugin.yml new file: paper-plugin/target/maven-archiver/pom.properties new file: paper-plugin/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file: paper-plugin/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file: paper-plugin/target/mclogger-paper-1.0.0.jar new file: paper-plugin/target/original-mclogger-paper-1.0.0.jar new file: velocity-plugin/pom.xml new file: velocity-plugin/src/main/java/de/simolzimol/mclogger/velocity/VelocityLoggerPlugin.java new file: velocity-plugin/src/main/java/de/simolzimol/mclogger/velocity/database/VelocityDatabaseManager.java new file: velocity-plugin/src/main/java/de/simolzimol/mclogger/velocity/listeners/VelocityEventListener.java new file: velocity-plugin/src/main/resources/velocity-config.yml new file: velocity-plugin/target/classes/de/simolzimol/mclogger/velocity/VelocityLoggerPlugin.class new file: velocity-plugin/target/classes/de/simolzimol/mclogger/velocity/database/VelocityDatabaseManager$ThrowingRunnable.class new file: velocity-plugin/target/classes/de/simolzimol/mclogger/velocity/database/VelocityDatabaseManager.class new file: velocity-plugin/target/classes/de/simolzimol/mclogger/velocity/listeners/VelocityEventListener.class new file: velocity-plugin/target/classes/velocity-config.yml new file: velocity-plugin/target/classes/velocity-plugin.json new file: velocity-plugin/target/maven-archiver/pom.properties new file: velocity-plugin/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst new file: velocity-plugin/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst new file: velocity-plugin/target/mclogger-velocity-1.0.0.jar new file: velocity-plugin/target/original-mclogger-velocity-1.0.0.jar new file: web/Dockerfile new file: web/app.py new file: web/blueprints/__init__.py new file: web/blueprints/auth.py new file: web/blueprints/group_admin.py new file: web/blueprints/panel.py new file: web/blueprints/site_admin.py new file: web/config.py new file: web/crypto.py new file: web/docker-compose.yml new file: web/panel_db.py new file: web/requirements.txt new file: web/static/css/style.css new file: web/static/js/main.js new file: web/templates/_pagination.html new file: web/templates/admin/base.html new file: web/templates/admin/dashboard.html new file: web/templates/admin/group_edit.html new file: web/templates/admin/group_members.html new file: web/templates/admin/groups.html new file: web/templates/admin/user_edit.html new file: web/templates/admin/users.html new file: web/templates/auth/admin_login.html new file: web/templates/auth/login.html new file: web/templates/base.html new file: web/templates/blocks.html new file: web/templates/chat.html new file: web/templates/commands.html new file: web/templates/dashboard.html new file: web/templates/deaths.html new file: web/templates/group_admin/base.html new file: web/templates/group_admin/dashboard.html new file: web/templates/group_admin/database.html new file: web/templates/group_admin/member_edit.html new file: web/templates/group_admin/members.html new file: web/templates/login.html new file: web/templates/panel/blocks.html new file: web/templates/panel/chat.html new file: web/templates/panel/commands.html new file: web/templates/panel/dashboard.html new file: web/templates/panel/deaths.html new file: web/templates/panel/no_db.html new file: web/templates/panel/perms.html new file: web/templates/panel/player_detail.html new file: web/templates/panel/players.html new file: web/templates/panel/proxy.html new file: web/templates/panel/server_events.html new file: web/templates/panel/sessions.html new file: web/templates/perms.html new file: web/templates/player_detail.html new file: web/templates/players.html new file: web/templates/proxy.html new file: web/templates/server_events.html new file: web/templates/sessions.html
This commit is contained in:
221
web/blueprints/site_admin.py
Normal file
221
web/blueprints/site_admin.py
Normal file
@@ -0,0 +1,221 @@
|
||||
"""
|
||||
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():
|
||||
groups = db.list_all_groups()
|
||||
users = db.list_all_users()
|
||||
# Für jede Gruppe DB-Status prüfen
|
||||
for g in groups:
|
||||
g["has_db"] = db.has_db_configured(g["id"])
|
||||
return render_template("admin/dashboard.html", groups=groups, users=users)
|
||||
|
||||
|
||||
# ──────────────────────────────────────────────────────────────
|
||||
# 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("Gruppenname darf nicht leer sein.", "danger")
|
||||
elif db.get_group_by_name(name):
|
||||
flash("Eine Gruppe mit diesem Namen existiert bereits.", "danger")
|
||||
else:
|
||||
db.create_group(name, desc)
|
||||
flash(f"Gruppe '{name}' erstellt.", "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("Gruppe nicht gefunden.", "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("Gruppenname darf nicht leer sein.", "danger")
|
||||
else:
|
||||
db.update_group(group_id, name, desc)
|
||||
flash("Gruppe aktualisiert.", "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("Gruppe gelöscht.", "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("Mitglied hinzugefügt.", "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("Mitglied entfernt.", "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("Alle Felder sind Pflichtfelder.", "danger")
|
||||
elif db.get_user_by_username(username):
|
||||
flash("Benutzername bereits vergeben.", "danger")
|
||||
else:
|
||||
db.create_user(username, email, password, is_site_admin)
|
||||
flash(f"Nutzer '{username}' erstellt.", "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("Nutzer nicht gefunden.", "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", "")
|
||||
db.update_user(user_id, username, email, is_site_admin)
|
||||
if new_password:
|
||||
db.change_password(user_id, new_password)
|
||||
flash("Passwort geändert.", "info")
|
||||
flash("Nutzer aktualisiert.", "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("Du kannst dich nicht selbst löschen.", "danger")
|
||||
else:
|
||||
db.delete_user(user_id)
|
||||
flash("Nutzer gelöscht.", "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 wechselt temporär in eine Gruppe, um deren MC-Daten zu sehen."""
|
||||
group = db.get_group_by_id(group_id)
|
||||
if not group:
|
||||
flash("Gruppe nicht gefunden.", "danger")
|
||||
return redirect(url_for("site_admin.dashboard"))
|
||||
if not db.has_db_configured(group_id):
|
||||
flash("Für diese Gruppe ist noch keine Datenbank konfiguriert.", "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"))
|
||||
Reference in New Issue
Block a user