216 lines
5.4 KiB
Markdown
216 lines
5.4 KiB
Markdown
# 🔧 Admin Panel Integration – Schritt-für-Schritt
|
||
|
||
## 1. Templates-Datei erstellen
|
||
|
||
Kopiere `admin.html` in dein `templates/` Verzeichnis:
|
||
|
||
```bash
|
||
cp admin.html templates/admin.html
|
||
```
|
||
|
||
## 2. Flask Routes hinzufügen
|
||
|
||
Öffne `app.py` und füge die neuen Routes hinzu:
|
||
|
||
**Nach den Error Handlers (ca. Zeile 80), vor `if __name__ == "__main__"`, hinzufügen:**
|
||
|
||
```python
|
||
# ============================================================================
|
||
# ADMIN ROUTES
|
||
# ============================================================================
|
||
|
||
@app.route("/admin", methods=["GET"])
|
||
@auth.login_required
|
||
def admin_dashboard():
|
||
"""Admin Dashboard - nur für Admin-Benutzer"""
|
||
user = auth.current_user()
|
||
if user not in ADMIN_USERS:
|
||
log_access(user, "/admin", "GET", 403)
|
||
return jsonify({"error": "Unauthorized - Admin access required"}), 403
|
||
|
||
log_access(user, "/admin", "GET")
|
||
return render_template("admin.html")
|
||
|
||
|
||
@app.route("/api/admin/stats", methods=["GET"])
|
||
@auth.login_required
|
||
def get_admin_stats():
|
||
"""Statistiken für Admin Dashboard"""
|
||
user = auth.current_user()
|
||
if user not in ADMIN_USERS:
|
||
log_access(user, "/api/admin/stats", "GET", 403)
|
||
return jsonify({"error": "Unauthorized"}), 403
|
||
|
||
log_access(user, "/api/admin/stats", "GET")
|
||
|
||
logs = []
|
||
if os.path.exists(LOG_FILE):
|
||
try:
|
||
with open(LOG_FILE, "r") as f:
|
||
logs = json.load(f)
|
||
except json.JSONDecodeError:
|
||
logs = []
|
||
|
||
total_requests = len(logs)
|
||
unique_users = len(set(log.get("username", "unknown") for log in logs))
|
||
failed_logins = len([l for l in logs if l.get("status") == 401])
|
||
|
||
return jsonify({
|
||
"total_requests": total_requests,
|
||
"unique_users": unique_users,
|
||
"failed_logins": failed_logins,
|
||
"timestamp": datetime.now().isoformat()
|
||
}), 200
|
||
|
||
|
||
@app.route("/api/admin/logs", methods=["GET"])
|
||
@auth.login_required
|
||
def get_admin_logs():
|
||
"""Access Logs für Admin Dashboard"""
|
||
user = auth.current_user()
|
||
if user not in ADMIN_USERS:
|
||
log_access(user, "/api/admin/logs", "GET", 403)
|
||
return jsonify({"error": "Unauthorized"}), 403
|
||
|
||
log_access(user, "/api/admin/logs", "GET")
|
||
|
||
logs = []
|
||
if os.path.exists(LOG_FILE):
|
||
try:
|
||
with open(LOG_FILE, "r") as f:
|
||
logs = json.load(f)
|
||
except json.JSONDecodeError:
|
||
logs = []
|
||
|
||
logs_sorted = sorted(logs, key=lambda x: x.get("timestamp", ""), reverse=True)
|
||
return jsonify({"logs": logs_sorted[-500:]}), 200
|
||
```
|
||
|
||
## 3. Server testen
|
||
|
||
```bash
|
||
python app.py
|
||
```
|
||
|
||
## 4. Zugriff
|
||
|
||
- URL: **http://localhost:5000/admin**
|
||
- Login: **admin** / **admin_secure_pwd_2026**
|
||
|
||
---
|
||
|
||
## Features im Admin Panel
|
||
|
||
### 📊 Dashboard-Statistiken
|
||
- ✅ Gesamte API-Anfragen
|
||
- ✅ Eindeutige Benutzer
|
||
- ✅ Fehlgeschlagene Logins (401 Unauthorized)
|
||
|
||
### 📋 Access Logs
|
||
- ✅ Echtzeit-Logs mit Timestamp
|
||
- ✅ Benutzer, Endpoint, HTTP-Method, Status
|
||
- ✅ Farbcodierung nach HTTP-Status (200, 401, 403)
|
||
|
||
### 🔍 Filter & Suche
|
||
- ✅ Nach Benutzer filtern
|
||
- ✅ Nach Endpoint filtern
|
||
- ✅ Live-Filter während Eingabe
|
||
|
||
### ⬇️ Export
|
||
- ✅ Download als JSON
|
||
- ✅ Optionale CSV-Export
|
||
|
||
### 🔄 Auto-Refresh
|
||
- ✅ Automatische Aktualisierung alle 30 Sekunden
|
||
- ✅ Manueller Refresh-Button
|
||
|
||
---
|
||
|
||
## Sicherheit
|
||
|
||
### ✅ Implementiert:
|
||
- HTTP Basic Auth
|
||
- Admin-only Access (403 Unauthorized für Non-Admins)
|
||
- Audit-Logging aller Admin-Aktionen
|
||
- XSS-Protection (HTML-escaped)
|
||
|
||
### ⚠️ Für Production:
|
||
- HTTPS erforderlich (Basic Auth unsicher über HTTP!)
|
||
- Admin-Passwort ändern
|
||
- Logs regelmäßig archivieren
|
||
|
||
---
|
||
|
||
## Erweiterungen (Optional)
|
||
|
||
### Charts hinzufügen (Chart.js)
|
||
|
||
```html
|
||
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.9.1/chart.min.js"></script>
|
||
<canvas id="requestsChart"></canvas>
|
||
|
||
<script>
|
||
const ctx = document.getElementById('requestsChart').getContext('2d');
|
||
const chart = new Chart(ctx, {
|
||
type: 'line',
|
||
data: {
|
||
labels: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
|
||
datasets: [{
|
||
label: 'Requests',
|
||
data: [12, 19, 3, 5, 2, 3, 7]
|
||
}]
|
||
}
|
||
});
|
||
</script>
|
||
```
|
||
|
||
### Weitere Admin-Features
|
||
- User-Management (neue Benutzer hinzufügen)
|
||
- Konfiguration Editor
|
||
- System-Monitor (CPU, RAM)
|
||
- Backup-Manager
|
||
- Audit-Trail Export
|
||
|
||
---
|
||
|
||
## Troubleshooting
|
||
|
||
### "403 Unauthorized" beim Öffnen von /admin
|
||
✓ Du musst als Admin angemeldet sein
|
||
✓ Login mit: `admin` / `admin_secure_pwd_2026`
|
||
|
||
### "No JSON object could be decoded" (in access_log.json)
|
||
✓ Lösche `access_log.json` und starte neu
|
||
✓ Die Datei wird automatisch neu erstellt
|
||
|
||
### Logs werden nicht angezeigt
|
||
✓ Prüfe, ob `access_log.json` im Projektverzeichnis existiert
|
||
✓ Öffne Browser Console (F12) auf Fehler
|
||
|
||
---
|
||
|
||
## API-Referenz
|
||
|
||
| Endpoint | Method | Auth | Beschreibung |
|
||
|----------|--------|------|-------------|
|
||
| `/admin` | GET | Admin | Admin-Dashboard |
|
||
| `/api/admin/stats` | GET | Admin | Statistiken (JSON) |
|
||
| `/api/admin/logs` | GET | Admin | Access-Logs (JSON) |
|
||
| `/api/admin/export` | GET | Admin | Export als JSON/CSV |
|
||
| `/api/admin/clear-logs` | POST | Admin | Alle Logs löschen |
|
||
|
||
---
|
||
|
||
## Nächste Schritte
|
||
|
||
- [ ] `admin.html` in `templates/` speichern
|
||
- [ ] Routes in `app.py` hinzufügen
|
||
- [ ] Server neustarten
|
||
- [ ] http://localhost:5000/admin testen
|
||
- [ ] Mit Admin-Credentials anmelden
|
||
- [ ] Logs prüfen
|
||
|
||
---
|
||
|
||
**Fertig!** 🎉 Dein Admin-Panel ist jetzt integriert!
|