Export Button geht jetzt
Dieser Commit ist enthalten in:
@@ -5,7 +5,7 @@ from flask import Blueprint, request, send_file
|
||||
|
||||
import config
|
||||
from auth.decorators import login_required
|
||||
from utils.export import create_excel_export, prepare_audit_export_data
|
||||
from utils.export import create_excel_export, create_csv_export, prepare_audit_export_data, format_datetime_for_export
|
||||
from db import get_connection
|
||||
|
||||
# Create Blueprint
|
||||
@@ -20,61 +20,32 @@ def export_licenses():
|
||||
cur = conn.cursor()
|
||||
|
||||
try:
|
||||
# Filter aus Request
|
||||
show_fake = request.args.get('show_fake', 'false') == 'true'
|
||||
|
||||
# SQL Query mit optionalem Test-Filter
|
||||
if show_fake:
|
||||
query = """
|
||||
SELECT
|
||||
l.id,
|
||||
l.license_key,
|
||||
c.name as customer_name,
|
||||
c.email as customer_email,
|
||||
l.license_type,
|
||||
l.valid_from,
|
||||
l.valid_until,
|
||||
l.is_active,
|
||||
l.device_limit,
|
||||
l.created_at,
|
||||
l.is_fake,
|
||||
CASE
|
||||
WHEN l.valid_until < CURRENT_DATE THEN 'Abgelaufen'
|
||||
WHEN l.is_active = false THEN 'Deaktiviert'
|
||||
ELSE 'Aktiv'
|
||||
END as status,
|
||||
(SELECT COUNT(*) FROM sessions s WHERE s.license_key = l.license_key AND s.is_active = true) as active_sessions,
|
||||
(SELECT COUNT(DISTINCT hardware_id) FROM sessions s WHERE s.license_key = l.license_key) as registered_devices
|
||||
FROM licenses l
|
||||
LEFT JOIN customers c ON l.customer_id = c.id
|
||||
ORDER BY l.created_at DESC
|
||||
"""
|
||||
else:
|
||||
query = """
|
||||
SELECT
|
||||
l.id,
|
||||
l.license_key,
|
||||
c.name as customer_name,
|
||||
c.email as customer_email,
|
||||
l.license_type,
|
||||
l.valid_from,
|
||||
l.valid_until,
|
||||
l.is_active,
|
||||
l.device_limit,
|
||||
l.created_at,
|
||||
l.is_fake,
|
||||
CASE
|
||||
WHEN l.valid_until < CURRENT_DATE THEN 'Abgelaufen'
|
||||
WHEN l.is_active = false THEN 'Deaktiviert'
|
||||
ELSE 'Aktiv'
|
||||
END as status,
|
||||
(SELECT COUNT(*) FROM sessions s WHERE s.license_key = l.license_key AND s.is_active = true) as active_sessions,
|
||||
(SELECT COUNT(DISTINCT hardware_id) FROM sessions s WHERE s.license_key = l.license_key) as registered_devices
|
||||
FROM licenses l
|
||||
LEFT JOIN customers c ON l.customer_id = c.id
|
||||
WHERE l.is_fake = false
|
||||
ORDER BY l.created_at DESC
|
||||
"""
|
||||
# Nur reale Daten exportieren - keine Fake-Daten
|
||||
query = """
|
||||
SELECT
|
||||
l.id,
|
||||
l.license_key,
|
||||
c.name as customer_name,
|
||||
c.email as customer_email,
|
||||
l.license_type,
|
||||
l.valid_from,
|
||||
l.valid_until,
|
||||
l.is_active,
|
||||
l.device_limit,
|
||||
l.created_at,
|
||||
l.is_fake,
|
||||
CASE
|
||||
WHEN l.valid_until < CURRENT_DATE THEN 'Abgelaufen'
|
||||
WHEN l.is_active = false THEN 'Deaktiviert'
|
||||
ELSE 'Aktiv'
|
||||
END as status,
|
||||
(SELECT COUNT(*) FROM sessions s WHERE s.license_key = l.license_key AND s.is_active = true) as active_sessions,
|
||||
(SELECT COUNT(DISTINCT hardware_id) FROM sessions s WHERE s.license_key = l.license_key) as registered_devices
|
||||
FROM licenses l
|
||||
LEFT JOIN customers c ON l.customer_id = c.id
|
||||
WHERE l.is_fake = false
|
||||
ORDER BY l.created_at DESC
|
||||
"""
|
||||
|
||||
cur.execute(query)
|
||||
|
||||
@@ -85,19 +56,25 @@ def export_licenses():
|
||||
'Status', 'Aktive Sessions', 'Registrierte Geräte']
|
||||
|
||||
for row in cur.fetchall():
|
||||
data.append(list(row))
|
||||
row_data = list(row)
|
||||
# Format datetime fields
|
||||
if row_data[5]: # valid_from
|
||||
row_data[5] = format_datetime_for_export(row_data[5])
|
||||
if row_data[6]: # valid_until
|
||||
row_data[6] = format_datetime_for_export(row_data[6])
|
||||
if row_data[9]: # created_at
|
||||
row_data[9] = format_datetime_for_export(row_data[9])
|
||||
data.append(row_data)
|
||||
|
||||
# Excel-Datei erstellen
|
||||
excel_file = create_excel_export(data, columns, 'Lizenzen')
|
||||
# Format prüfen
|
||||
format_type = request.args.get('format', 'excel').lower()
|
||||
|
||||
# Datei senden
|
||||
filename = f"lizenzen_export_{datetime.now().strftime('%Y%m%d_%H%M%S')}.xlsx"
|
||||
return send_file(
|
||||
excel_file,
|
||||
mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
as_attachment=True,
|
||||
download_name=filename
|
||||
)
|
||||
if format_type == 'csv':
|
||||
# CSV-Datei erstellen
|
||||
return create_csv_export(data, columns, 'lizenzen')
|
||||
else:
|
||||
# Excel-Datei erstellen
|
||||
return create_excel_export(data, columns, 'lizenzen')
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"Fehler beim Export: {str(e)}")
|
||||
@@ -120,23 +97,61 @@ def export_audit():
|
||||
action_filter = request.args.get('action', '')
|
||||
entity_type_filter = request.args.get('entity_type', '')
|
||||
|
||||
# Query aufbauen
|
||||
query = """
|
||||
SELECT
|
||||
id, timestamp, username, action, entity_type, entity_id,
|
||||
ip_address, user_agent, old_values, new_values, additional_info
|
||||
FROM audit_log
|
||||
WHERE timestamp >= CURRENT_TIMESTAMP - INTERVAL '%s days'
|
||||
"""
|
||||
params = [days]
|
||||
|
||||
if action_filter:
|
||||
query += " AND action = %s"
|
||||
params.append(action_filter)
|
||||
|
||||
if entity_type_filter:
|
||||
query += " AND entity_type = %s"
|
||||
params.append(entity_type_filter)
|
||||
|
||||
query += " ORDER BY timestamp DESC"
|
||||
|
||||
cur.execute(query, params)
|
||||
|
||||
# Daten in Dictionary-Format umwandeln
|
||||
audit_logs = []
|
||||
for row in cur.fetchall():
|
||||
audit_logs.append({
|
||||
'id': row[0],
|
||||
'timestamp': row[1],
|
||||
'username': row[2],
|
||||
'action': row[3],
|
||||
'entity_type': row[4],
|
||||
'entity_id': row[5],
|
||||
'ip_address': row[6],
|
||||
'user_agent': row[7],
|
||||
'old_values': row[8],
|
||||
'new_values': row[9],
|
||||
'additional_info': row[10]
|
||||
})
|
||||
|
||||
# Daten für Export vorbereiten
|
||||
data = prepare_audit_export_data(days, action_filter, entity_type_filter)
|
||||
data = prepare_audit_export_data(audit_logs)
|
||||
|
||||
# Excel-Datei erstellen
|
||||
columns = ['Zeitstempel', 'Benutzer', 'Aktion', 'Entität', 'Entität ID',
|
||||
'IP-Adresse', 'Alte Werte', 'Neue Werte', 'Zusatzinfo']
|
||||
columns = ['ID', 'Zeitstempel', 'Benutzer', 'Aktion', 'Entität', 'Entität ID',
|
||||
'IP-Adresse', 'User Agent', 'Alte Werte', 'Neue Werte', 'Zusatzinfo']
|
||||
|
||||
excel_file = create_excel_export(data, columns, 'Audit-Log')
|
||||
# Format prüfen
|
||||
format_type = request.args.get('format', 'excel').lower()
|
||||
|
||||
# Datei senden
|
||||
filename = f"audit_log_export_{datetime.now().strftime('%Y%m%d_%H%M%S')}.xlsx"
|
||||
return send_file(
|
||||
excel_file,
|
||||
mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
as_attachment=True,
|
||||
download_name=filename
|
||||
)
|
||||
if format_type == 'csv':
|
||||
# CSV-Datei erstellen
|
||||
return create_csv_export(data, columns, 'audit_log')
|
||||
else:
|
||||
# Excel-Datei erstellen
|
||||
return create_excel_export(data, columns, 'audit_log')
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"Fehler beim Export: {str(e)}")
|
||||
@@ -154,7 +169,7 @@ def export_customers():
|
||||
cur = conn.cursor()
|
||||
|
||||
try:
|
||||
# SQL Query
|
||||
# SQL Query - nur reale Kunden exportieren
|
||||
cur.execute("""
|
||||
SELECT
|
||||
c.id,
|
||||
@@ -169,6 +184,7 @@ def export_customers():
|
||||
COUNT(CASE WHEN l.valid_until < CURRENT_DATE THEN 1 END) as expired_licenses
|
||||
FROM customers c
|
||||
LEFT JOIN licenses l ON c.id = l.customer_id
|
||||
WHERE c.is_fake = false
|
||||
GROUP BY c.id, c.name, c.email, c.phone, c.address, c.created_at, c.is_fake
|
||||
ORDER BY c.name
|
||||
""")
|
||||
@@ -179,19 +195,21 @@ def export_customers():
|
||||
'Test-Kunde', 'Anzahl Lizenzen', 'Aktive Lizenzen', 'Abgelaufene Lizenzen']
|
||||
|
||||
for row in cur.fetchall():
|
||||
data.append(list(row))
|
||||
# Format datetime fields (created_at ist Spalte 5)
|
||||
row_data = list(row)
|
||||
if row_data[5]: # created_at
|
||||
row_data[5] = format_datetime_for_export(row_data[5])
|
||||
data.append(row_data)
|
||||
|
||||
# Excel-Datei erstellen
|
||||
excel_file = create_excel_export(data, columns, 'Kunden')
|
||||
# Format prüfen
|
||||
format_type = request.args.get('format', 'excel').lower()
|
||||
|
||||
# Datei senden
|
||||
filename = f"kunden_export_{datetime.now().strftime('%Y%m%d_%H%M%S')}.xlsx"
|
||||
return send_file(
|
||||
excel_file,
|
||||
mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
as_attachment=True,
|
||||
download_name=filename
|
||||
)
|
||||
if format_type == 'csv':
|
||||
# CSV-Datei erstellen
|
||||
return create_csv_export(data, columns, 'kunden')
|
||||
else:
|
||||
# Excel-Datei erstellen
|
||||
return create_excel_export(data, columns, 'kunden')
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"Fehler beim Export: {str(e)}")
|
||||
@@ -230,7 +248,7 @@ def export_sessions():
|
||||
l.is_fake
|
||||
FROM sessions s
|
||||
LEFT JOIN licenses l ON s.license_key = l.license_key
|
||||
WHERE s.is_active = true
|
||||
WHERE s.is_active = true AND l.is_fake = false
|
||||
ORDER BY s.started_at DESC
|
||||
"""
|
||||
cur.execute(query)
|
||||
@@ -250,7 +268,7 @@ def export_sessions():
|
||||
l.is_fake
|
||||
FROM sessions s
|
||||
LEFT JOIN licenses l ON s.license_key = l.license_key
|
||||
WHERE s.started_at >= CURRENT_TIMESTAMP - INTERVAL '%s days'
|
||||
WHERE s.started_at >= CURRENT_TIMESTAMP - INTERVAL '%s days' AND l.is_fake = false
|
||||
ORDER BY s.started_at DESC
|
||||
"""
|
||||
cur.execute(query, (days,))
|
||||
@@ -262,19 +280,25 @@ def export_sessions():
|
||||
'Lizenztyp', 'Fake-Lizenz']
|
||||
|
||||
for row in cur.fetchall():
|
||||
data.append(list(row))
|
||||
row_data = list(row)
|
||||
# Format datetime fields
|
||||
if row_data[5]: # started_at
|
||||
row_data[5] = format_datetime_for_export(row_data[5])
|
||||
if row_data[6]: # ended_at
|
||||
row_data[6] = format_datetime_for_export(row_data[6])
|
||||
if row_data[7]: # last_heartbeat
|
||||
row_data[7] = format_datetime_for_export(row_data[7])
|
||||
data.append(row_data)
|
||||
|
||||
# Excel-Datei erstellen
|
||||
excel_file = create_excel_export(data, columns, 'Sessions')
|
||||
# Format prüfen
|
||||
format_type = request.args.get('format', 'excel').lower()
|
||||
|
||||
# Datei senden
|
||||
filename = f"sessions_export_{datetime.now().strftime('%Y%m%d_%H%M%S')}.xlsx"
|
||||
return send_file(
|
||||
excel_file,
|
||||
mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
as_attachment=True,
|
||||
download_name=filename
|
||||
)
|
||||
if format_type == 'csv':
|
||||
# CSV-Datei erstellen
|
||||
return create_csv_export(data, columns, 'sessions')
|
||||
else:
|
||||
# Excel-Datei erstellen
|
||||
return create_excel_export(data, columns, 'sessions')
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"Fehler beim Export: {str(e)}")
|
||||
@@ -295,7 +319,6 @@ def export_resources():
|
||||
# Filter aus Request
|
||||
resource_type = request.args.get('type', 'all')
|
||||
status_filter = request.args.get('status', 'all')
|
||||
show_fake = request.args.get('show_fake', 'false') == 'true'
|
||||
|
||||
# SQL Query aufbauen
|
||||
query = """
|
||||
@@ -328,8 +351,8 @@ def export_resources():
|
||||
query += " AND rp.status = %s"
|
||||
params.append(status_filter)
|
||||
|
||||
if not show_fake:
|
||||
query += " AND rp.is_fake = false"
|
||||
# Immer nur reale Ressourcen exportieren
|
||||
query += " AND rp.is_fake = false"
|
||||
|
||||
query += " ORDER BY rp.resource_type, rp.resource_value"
|
||||
|
||||
@@ -342,23 +365,131 @@ def export_resources():
|
||||
'Status geändert von', 'Quarantäne-Grund']
|
||||
|
||||
for row in cur.fetchall():
|
||||
data.append(list(row))
|
||||
row_data = list(row)
|
||||
# Format datetime fields
|
||||
if row_data[7]: # created_at
|
||||
row_data[7] = format_datetime_for_export(row_data[7])
|
||||
if row_data[9]: # status_changed_at
|
||||
row_data[9] = format_datetime_for_export(row_data[9])
|
||||
data.append(row_data)
|
||||
|
||||
# Excel-Datei erstellen
|
||||
excel_file = create_excel_export(data, columns, 'Ressourcen')
|
||||
# Format prüfen
|
||||
format_type = request.args.get('format', 'excel').lower()
|
||||
|
||||
# Datei senden
|
||||
filename = f"ressourcen_export_{datetime.now().strftime('%Y%m%d_%H%M%S')}.xlsx"
|
||||
return send_file(
|
||||
excel_file,
|
||||
mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
as_attachment=True,
|
||||
download_name=filename
|
||||
)
|
||||
if format_type == 'csv':
|
||||
# CSV-Datei erstellen
|
||||
return create_csv_export(data, columns, 'ressourcen')
|
||||
else:
|
||||
# Excel-Datei erstellen
|
||||
return create_excel_export(data, columns, 'ressourcen')
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"Fehler beim Export: {str(e)}")
|
||||
return "Fehler beim Exportieren der Ressourcen", 500
|
||||
finally:
|
||||
cur.close()
|
||||
conn.close()
|
||||
|
||||
|
||||
@export_bp.route("/monitoring")
|
||||
@login_required
|
||||
def export_monitoring():
|
||||
"""Exportiert Monitoring-Daten als Excel/CSV-Datei"""
|
||||
conn = get_connection()
|
||||
cur = conn.cursor()
|
||||
|
||||
try:
|
||||
# Zeitraum aus Request
|
||||
hours = int(request.args.get('hours', 24))
|
||||
|
||||
# Monitoring-Daten sammeln
|
||||
data = []
|
||||
columns = ['Zeitstempel', 'Lizenz-ID', 'Lizenzschlüssel', 'Kunde', 'Hardware-ID',
|
||||
'IP-Adresse', 'Ereignis-Typ', 'Schweregrad', 'Beschreibung']
|
||||
|
||||
# Query für Heartbeats und optionale Anomalien
|
||||
query = """
|
||||
WITH monitoring_data AS (
|
||||
-- Lizenz-Heartbeats
|
||||
SELECT
|
||||
lh.timestamp,
|
||||
lh.license_id,
|
||||
l.license_key,
|
||||
c.name as customer_name,
|
||||
lh.hardware_id,
|
||||
lh.ip_address,
|
||||
'Heartbeat' as event_type,
|
||||
'Normal' as severity,
|
||||
'License validation' as description
|
||||
FROM license_heartbeats lh
|
||||
JOIN licenses l ON l.id = lh.license_id
|
||||
JOIN customers c ON c.id = l.customer_id
|
||||
WHERE lh.timestamp > CURRENT_TIMESTAMP - INTERVAL '%s hours'
|
||||
AND l.is_fake = false
|
||||
"""
|
||||
|
||||
# Check if anomaly_detections table exists
|
||||
cur.execute("""
|
||||
SELECT EXISTS (
|
||||
SELECT FROM information_schema.tables
|
||||
WHERE table_name = 'anomaly_detections'
|
||||
)
|
||||
""")
|
||||
has_anomalies = cur.fetchone()[0]
|
||||
|
||||
if has_anomalies:
|
||||
query += """
|
||||
UNION ALL
|
||||
|
||||
-- Anomalien
|
||||
SELECT
|
||||
ad.detected_at as timestamp,
|
||||
ad.license_id,
|
||||
l.license_key,
|
||||
c.name as customer_name,
|
||||
ad.hardware_id,
|
||||
ad.ip_address,
|
||||
ad.anomaly_type as event_type,
|
||||
ad.severity,
|
||||
ad.description
|
||||
FROM anomaly_detections ad
|
||||
LEFT JOIN licenses l ON l.id = ad.license_id
|
||||
LEFT JOIN customers c ON c.id = l.customer_id
|
||||
WHERE ad.detected_at > CURRENT_TIMESTAMP - INTERVAL '%s hours'
|
||||
AND (l.is_fake = false OR l.is_fake IS NULL)
|
||||
"""
|
||||
params = [hours, hours]
|
||||
else:
|
||||
params = [hours]
|
||||
|
||||
query += """
|
||||
)
|
||||
SELECT * FROM monitoring_data
|
||||
ORDER BY timestamp DESC
|
||||
"""
|
||||
|
||||
cur.execute(query, params)
|
||||
|
||||
for row in cur.fetchall():
|
||||
row_data = list(row)
|
||||
# Format datetime field (timestamp ist Spalte 0)
|
||||
if row_data[0]: # timestamp
|
||||
row_data[0] = format_datetime_for_export(row_data[0])
|
||||
data.append(row_data)
|
||||
|
||||
# Format prüfen
|
||||
format_type = request.args.get('format', 'excel').lower()
|
||||
|
||||
if format_type == 'csv':
|
||||
# CSV-Datei erstellen
|
||||
return create_csv_export(data, columns, 'monitoring')
|
||||
else:
|
||||
# Excel-Datei erstellen
|
||||
return create_excel_export(data, columns, 'monitoring')
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"Fehler beim Export: {str(e)}")
|
||||
return "Fehler beim Exportieren der Monitoring-Daten", 500
|
||||
finally:
|
||||
cur.close()
|
||||
conn.close()
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren