modified: web/blueprints/panel.py
modified: web/templates/admin/audit_log.html modified: web/templates/admin/dashboard.html
This commit is contained in:
@@ -14,6 +14,20 @@ from roles import can_manage_group
|
||||
panel = Blueprint("panel", __name__)
|
||||
|
||||
|
||||
def _audit(action: str, details: dict | None = None, entity_type: str | None = None, entity_id=None):
|
||||
"""Fire-and-forget audit event for panel data access (never raises)."""
|
||||
pdb.log_audit_event(
|
||||
session.get("user_id"),
|
||||
session.get("username"),
|
||||
action,
|
||||
entity_type=entity_type,
|
||||
entity_id=entity_id,
|
||||
details=details,
|
||||
group_id=session.get("group_id"),
|
||||
ip_address=request.remote_addr,
|
||||
)
|
||||
|
||||
|
||||
# ─────────────────────────────────────────────────────────────
|
||||
# Hilfsfunktionen
|
||||
# ─────────────────────────────────────────────────────────────
|
||||
@@ -170,6 +184,7 @@ def dashboard():
|
||||
def players():
|
||||
search = request.args.get("q", "")
|
||||
page = max(1, request.args.get("page", 1, type=int))
|
||||
_audit("panel.view_players", {"search": search, "page": page} if search else {"page": page})
|
||||
if search:
|
||||
base = "FROM players WHERE username LIKE %s"
|
||||
args = (f"%{search}%",)
|
||||
@@ -191,6 +206,8 @@ def player_detail(uuid):
|
||||
if not player:
|
||||
flash("Player not found.", "danger")
|
||||
return redirect(url_for("panel.players"))
|
||||
_audit("panel.view_player", {"player_name": player.get("username"), "uuid": uuid},
|
||||
entity_type="mc_player", entity_id=uuid)
|
||||
perms = session.get("permissions", {})
|
||||
is_admin = session.get("is_site_admin") or can_manage_group(session.get("role"))
|
||||
return render_template("panel/player_detail.html",
|
||||
@@ -216,6 +233,7 @@ def sessions():
|
||||
page = max(1, request.args.get("page", 1, type=int))
|
||||
player = request.args.get("player", "")
|
||||
server = request.args.get("server", "")
|
||||
_audit("panel.view_sessions", {"page": page})
|
||||
conditions, args = [], []
|
||||
if player: conditions.append("player_name LIKE %s"); args.append(f"%{player}%")
|
||||
if server: conditions.append("server_name = %s"); args.append(server)
|
||||
@@ -239,6 +257,7 @@ def sessions():
|
||||
def chat():
|
||||
page = max(1, request.args.get("page", 1, type=int))
|
||||
search = request.args.get("q", ""); server = request.args.get("server", "")
|
||||
_audit("panel.view_chat", {"page": page})
|
||||
date_from = request.args.get("from", ""); date_to = request.args.get("to", "")
|
||||
conditions, args = [], []
|
||||
if search: conditions.append("message LIKE %s"); args.append(f"%{search}%")
|
||||
@@ -265,6 +284,7 @@ def chat():
|
||||
def commands():
|
||||
page = max(1, request.args.get("page", 1, type=int))
|
||||
player = request.args.get("player", ""); search = request.args.get("q", ""); server = request.args.get("server", "")
|
||||
_audit("panel.view_commands", {"page": page})
|
||||
conditions, args = [], []
|
||||
if player: conditions.append("player_name LIKE %s"); args.append(f"%{player}%")
|
||||
if search: conditions.append("command LIKE %s"); args.append(f"%{search}%")
|
||||
@@ -289,6 +309,7 @@ def commands():
|
||||
def deaths():
|
||||
page = max(1, request.args.get("page", 1, type=int))
|
||||
player = request.args.get("player", ""); cause = request.args.get("cause", "")
|
||||
_audit("panel.view_deaths", {"page": page})
|
||||
conditions, args = [], []
|
||||
if player: conditions.append("player_name LIKE %s"); args.append(f"%{player}%")
|
||||
if cause: conditions.append("cause = %s"); args.append(cause)
|
||||
@@ -311,6 +332,7 @@ def deaths():
|
||||
def blocks():
|
||||
page = max(1, request.args.get("page", 1, type=int))
|
||||
event_type = request.args.get("type", ""); player = request.args.get("player", "")
|
||||
_audit("panel.view_blocks", {"page": page})
|
||||
world = request.args.get("world", ""); server = request.args.get("server", ""); block = request.args.get("block", "")
|
||||
conditions, args = [], []
|
||||
if event_type: conditions.append("event_type = %s"); args.append(event_type)
|
||||
@@ -340,6 +362,7 @@ def blocks():
|
||||
def proxy():
|
||||
page = max(1, request.args.get("page", 1, type=int))
|
||||
event_type = request.args.get("type", ""); player = request.args.get("player", "")
|
||||
_audit("panel.view_proxy", {"page": page})
|
||||
conditions, args = [], []
|
||||
if event_type: conditions.append("event_type = %s"); args.append(event_type)
|
||||
if player: conditions.append("player_name LIKE %s"); args.append(f"%{player}%")
|
||||
@@ -361,6 +384,7 @@ def proxy():
|
||||
def server_events():
|
||||
page = max(1, request.args.get("page", 1, type=int))
|
||||
server = request.args.get("server", ""); etype = request.args.get("type", "")
|
||||
_audit("panel.view_server_events", {"page": page})
|
||||
conditions, args = [], []
|
||||
if server: conditions.append("server_name = %s"); args.append(server)
|
||||
if etype: conditions.append("event_type = %s"); args.append(etype)
|
||||
@@ -385,6 +409,7 @@ def server_events():
|
||||
def perms():
|
||||
page = max(1, request.args.get("page", 1, type=int))
|
||||
player = request.args.get("player", ""); plugin_filter = request.args.get("plugin", ""); etype = request.args.get("type", "")
|
||||
_audit("panel.view_perms", {"page": page})
|
||||
conditions, args = [], []
|
||||
if player: conditions.append("player_name LIKE %s"); args.append(f"%{player}%")
|
||||
if plugin_filter: conditions.append("plugin_name = %s"); args.append(plugin_filter)
|
||||
|
||||
@@ -121,6 +121,16 @@
|
||||
'consent.given': 'badge bg-success',
|
||||
'consent.declined': 'badge bg-warning text-dark',
|
||||
'audit.purged': 'badge bg-danger',
|
||||
'panel.view_players': 'badge bg-dark border border-info',
|
||||
'panel.view_player': 'badge bg-info text-dark',
|
||||
'panel.view_sessions': 'badge bg-dark border border-info',
|
||||
'panel.view_chat': 'badge bg-dark border border-info',
|
||||
'panel.view_commands': 'badge bg-dark border border-info',
|
||||
'panel.view_deaths': 'badge bg-dark border border-info',
|
||||
'panel.view_blocks': 'badge bg-dark border border-info',
|
||||
'panel.view_proxy': 'badge bg-dark border border-info',
|
||||
'panel.view_server_events': 'badge bg-dark border border-info',
|
||||
'panel.view_perms': 'badge bg-dark border border-info',
|
||||
} %}
|
||||
<span class="{{ action_class.get(row.action, 'badge bg-secondary') }} font-monospace" style="font-size:.75em">
|
||||
{{ row.action }}
|
||||
|
||||
@@ -191,8 +191,16 @@
|
||||
'mail.settings_deleted': 'badge bg-danger',
|
||||
'consent.given': 'badge bg-success',
|
||||
'consent.declined': 'badge bg-warning text-dark',
|
||||
'audit.purged': 'badge bg-danger',
|
||||
} %}
|
||||
'audit.purged': 'badge bg-danger', 'panel.view_players': 'badge bg-dark border border-info',
|
||||
'panel.view_player': 'badge bg-info text-dark',
|
||||
'panel.view_sessions': 'badge bg-dark border border-info',
|
||||
'panel.view_chat': 'badge bg-dark border border-info',
|
||||
'panel.view_commands': 'badge bg-dark border border-info',
|
||||
'panel.view_deaths': 'badge bg-dark border border-info',
|
||||
'panel.view_blocks': 'badge bg-dark border border-info',
|
||||
'panel.view_proxy': 'badge bg-dark border border-info',
|
||||
'panel.view_server_events': 'badge bg-dark border border-info',
|
||||
'panel.view_perms': 'badge bg-dark border border-info', } %}
|
||||
<tr>
|
||||
<td class="text-muted small">{{ row.created_at | fmt_dt }}</td>
|
||||
<td>
|
||||
|
||||
Reference in New Issue
Block a user