236 Zeilen
12 KiB
HTML
236 Zeilen
12 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="de">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<title>Audit-Log - Admin Panel</title>
|
||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||
<style>
|
||
.audit-details {
|
||
font-size: 0.85em;
|
||
max-width: 300px;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
}
|
||
.json-display {
|
||
background-color: #f8f9fa;
|
||
padding: 5px;
|
||
border-radius: 3px;
|
||
font-family: monospace;
|
||
font-size: 0.8em;
|
||
max-height: 100px;
|
||
overflow-y: auto;
|
||
}
|
||
.action-CREATE { color: #28a745; }
|
||
.action-UPDATE { color: #007bff; }
|
||
.action-DELETE { color: #dc3545; }
|
||
.action-LOGIN { color: #17a2b8; }
|
||
.action-LOGOUT { color: #6c757d; }
|
||
.action-EXPORT { color: #ffc107; }
|
||
</style>
|
||
</head>
|
||
<body class="bg-light">
|
||
<nav class="navbar navbar-dark bg-dark">
|
||
<div class="container">
|
||
<span class="navbar-brand">🎛️ Lizenzverwaltung</span>
|
||
<div class="d-flex align-items-center">
|
||
<span class="text-white me-3">Angemeldet als: {{ username }}</span>
|
||
<a href="/logout" class="btn btn-outline-light btn-sm">Abmelden</a>
|
||
</div>
|
||
</div>
|
||
</nav>
|
||
|
||
<div class="container py-5">
|
||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||
<h2>📋 Audit-Log</h2>
|
||
<div>
|
||
<a href="/" class="btn btn-secondary">📊 Dashboard</a>
|
||
<a href="/licenses" class="btn btn-secondary">📋 Lizenzen</a>
|
||
<a href="/customers" class="btn btn-secondary">👥 Kunden</a>
|
||
<a href="/sessions" class="btn btn-secondary">🟢 Sessions</a>
|
||
<a href="/backups" class="btn btn-secondary">💾 Backups</a>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Filter -->
|
||
<div class="card mb-3">
|
||
<div class="card-body">
|
||
<form method="get" action="/audit">
|
||
<div class="row g-3 align-items-end">
|
||
<div class="col-md-3">
|
||
<label for="user" class="form-label">Benutzer</label>
|
||
<input type="text" class="form-control" id="user" name="user"
|
||
placeholder="Benutzername..." value="{{ filter_user }}">
|
||
</div>
|
||
<div class="col-md-3">
|
||
<label for="action" class="form-label">Aktion</label>
|
||
<select class="form-select" id="action" name="action">
|
||
<option value="">Alle Aktionen</option>
|
||
<option value="CREATE" {% if filter_action == 'CREATE' %}selected{% endif %}>➕ Erstellt</option>
|
||
<option value="UPDATE" {% if filter_action == 'UPDATE' %}selected{% endif %}>✏️ Bearbeitet</option>
|
||
<option value="DELETE" {% if filter_action == 'DELETE' %}selected{% endif %}>🗑️ Gelöscht</option>
|
||
<option value="LOGIN" {% if filter_action == 'LOGIN' %}selected{% endif %}>🔑 Anmeldung</option>
|
||
<option value="LOGOUT" {% if filter_action == 'LOGOUT' %}selected{% endif %}>🚪 Abmeldung</option>
|
||
<option value="EXPORT" {% if filter_action == 'EXPORT' %}selected{% endif %}>📥 Export</option>
|
||
</select>
|
||
</div>
|
||
<div class="col-md-3">
|
||
<label for="entity" class="form-label">Entität</label>
|
||
<select class="form-select" id="entity" name="entity">
|
||
<option value="">Alle Entitäten</option>
|
||
<option value="license" {% if filter_entity == 'license' %}selected{% endif %}>Lizenz</option>
|
||
<option value="customer" {% if filter_entity == 'customer' %}selected{% endif %}>Kunde</option>
|
||
<option value="user" {% if filter_entity == 'user' %}selected{% endif %}>Benutzer</option>
|
||
<option value="session" {% if filter_entity == 'session' %}selected{% endif %}>Session</option>
|
||
</select>
|
||
</div>
|
||
<div class="col-md-3">
|
||
<button type="submit" class="btn btn-primary">Filter anwenden</button>
|
||
<a href="/audit" class="btn btn-outline-secondary">Zurücksetzen</a>
|
||
</div>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Audit Log Tabelle -->
|
||
<div class="card">
|
||
<div class="card-body">
|
||
<div class="table-responsive">
|
||
<table class="table table-hover">
|
||
<thead>
|
||
<tr>
|
||
<th>Zeitstempel</th>
|
||
<th>Benutzer</th>
|
||
<th>Aktion</th>
|
||
<th>Entität</th>
|
||
<th>Details</th>
|
||
<th>IP-Adresse</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
{% for log in logs %}
|
||
<tr>
|
||
<td>{{ log[1].strftime('%d.%m.%Y %H:%M:%S') }}</td>
|
||
<td><strong>{{ log[2] }}</strong></td>
|
||
<td>
|
||
<span class="action-{{ log[3] }}">
|
||
{% if log[3] == 'CREATE' %}➕ Erstellt
|
||
{% elif log[3] == 'UPDATE' %}✏️ Bearbeitet
|
||
{% elif log[3] == 'DELETE' %}🗑️ Gelöscht
|
||
{% elif log[3] == 'LOGIN' %}🔑 Anmeldung
|
||
{% elif log[3] == 'LOGOUT' %}🚪 Abmeldung
|
||
{% elif log[3] == 'EXPORT' %}📥 Export
|
||
{% else %}{{ log[3] }}
|
||
{% endif %}
|
||
</span>
|
||
</td>
|
||
<td>
|
||
{{ log[4] }}
|
||
{% if log[5] %}
|
||
<small class="text-muted">#{{ log[5] }}</small>
|
||
{% endif %}
|
||
</td>
|
||
<td class="audit-details">
|
||
{% if log[10] %}
|
||
<div class="mb-1"><small class="text-muted">{{ log[10] }}</small></div>
|
||
{% endif %}
|
||
|
||
{% if log[6] and log[3] == 'DELETE' %}
|
||
<details>
|
||
<summary>Gelöschte Werte</summary>
|
||
<div class="json-display">
|
||
{% for key, value in log[6].items() %}
|
||
<strong>{{ key }}:</strong> {{ value }}<br>
|
||
{% endfor %}
|
||
</div>
|
||
</details>
|
||
{% elif log[6] and log[7] and log[3] == 'UPDATE' %}
|
||
<details>
|
||
<summary>Änderungen anzeigen</summary>
|
||
<div class="json-display">
|
||
<strong>Vorher:</strong><br>
|
||
{% for key, value in log[6].items() %}
|
||
{% if log[7][key] != value %}
|
||
{{ key }}: {{ value }}<br>
|
||
{% endif %}
|
||
{% endfor %}
|
||
<hr class="my-1">
|
||
<strong>Nachher:</strong><br>
|
||
{% for key, value in log[7].items() %}
|
||
{% if log[6][key] != value %}
|
||
{{ key }}: {{ value }}<br>
|
||
{% endif %}
|
||
{% endfor %}
|
||
</div>
|
||
</details>
|
||
{% elif log[7] and log[3] == 'CREATE' %}
|
||
<details>
|
||
<summary>Erstellte Werte</summary>
|
||
<div class="json-display">
|
||
{% for key, value in log[7].items() %}
|
||
<strong>{{ key }}:</strong> {{ value }}<br>
|
||
{% endfor %}
|
||
</div>
|
||
</details>
|
||
{% endif %}
|
||
</td>
|
||
<td>
|
||
<small class="text-muted">{{ log[8] or '-' }}</small>
|
||
</td>
|
||
</tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
</table>
|
||
|
||
{% if not logs %}
|
||
<div class="text-center py-5">
|
||
<p class="text-muted">Keine Audit-Log-Einträge gefunden.</p>
|
||
</div>
|
||
{% endif %}
|
||
</div>
|
||
|
||
<!-- Pagination -->
|
||
{% if total_pages > 1 %}
|
||
<nav aria-label="Seitennavigation" class="mt-3">
|
||
<ul class="pagination justify-content-center">
|
||
<!-- Erste Seite -->
|
||
<li class="page-item {% if page == 1 %}disabled{% endif %}">
|
||
<a class="page-link" href="{{ url_for('audit_log', page=1, user=filter_user, action=filter_action, entity=filter_entity) }}">Erste</a>
|
||
</li>
|
||
|
||
<!-- Vorherige Seite -->
|
||
<li class="page-item {% if page == 1 %}disabled{% endif %}">
|
||
<a class="page-link" href="{{ url_for('audit_log', page=page-1, user=filter_user, action=filter_action, entity=filter_entity) }}">←</a>
|
||
</li>
|
||
|
||
<!-- Seitenzahlen -->
|
||
{% for p in range(1, total_pages + 1) %}
|
||
{% if p >= page - 2 and p <= page + 2 %}
|
||
<li class="page-item {% if p == page %}active{% endif %}">
|
||
<a class="page-link" href="{{ url_for('audit_log', page=p, user=filter_user, action=filter_action, entity=filter_entity) }}">{{ p }}</a>
|
||
</li>
|
||
{% endif %}
|
||
{% endfor %}
|
||
|
||
<!-- Nächste Seite -->
|
||
<li class="page-item {% if page == total_pages %}disabled{% endif %}">
|
||
<a class="page-link" href="{{ url_for('audit_log', page=page+1, user=filter_user, action=filter_action, entity=filter_entity) }}">→</a>
|
||
</li>
|
||
|
||
<!-- Letzte Seite -->
|
||
<li class="page-item {% if page == total_pages %}disabled{% endif %}">
|
||
<a class="page-link" href="{{ url_for('audit_log', page=total_pages, user=filter_user, action=filter_action, entity=filter_entity) }}">Letzte</a>
|
||
</li>
|
||
</ul>
|
||
<p class="text-center text-muted">
|
||
Seite {{ page }} von {{ total_pages }} | Gesamt: {{ total }} Einträge
|
||
</p>
|
||
</nav>
|
||
{% endif %}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
|
||
</body>
|
||
</html> |