API Key Config ist fertig

Dieser Commit ist enthalten in:
2025-06-22 12:03:49 +02:00
Ursprung b420452551
Commit 1b5b7d0381
7 geänderte Dateien mit 398 neuen und 40 gelöschten Zeilen

Datei anzeigen

@@ -6,6 +6,7 @@ from flask import Blueprint, render_template, request, redirect, session, url_fo
import requests
import config
from config import DATABASE_CONFIG
from auth.decorators import login_required
from utils.audit import log_audit
from utils.backup import create_backup, restore_backup
@@ -934,50 +935,55 @@ def license_config():
# Get client configuration
cur.execute("""
SELECT id, client_name, api_key, heartbeat_interval, session_timeout,
current_version, minimum_version, download_url, whats_new,
created_at, updated_at
current_version, minimum_version, created_at, updated_at
FROM client_configs
WHERE client_name = 'Account Forger'
""")
client_config = cur.fetchone()
# Get active sessions
cur.execute("""
SELECT ls.id, ls.session_token, l.license_key, c.name as customer_name,
ls.hardware_id, ls.ip_address, ls.client_version,
ls.started_at AT TIME ZONE 'Europe/Berlin' as started_at,
ls.last_heartbeat AT TIME ZONE 'Europe/Berlin' as last_heartbeat,
EXTRACT(EPOCH FROM (CURRENT_TIMESTAMP - ls.last_heartbeat)) as seconds_since_heartbeat
FROM license_sessions ls
JOIN licenses l ON ls.license_id = l.id
LEFT JOIN customers c ON l.customer_id = c.id
ORDER BY ls.last_heartbeat DESC
LIMIT 5
""")
active_sessions = cur.fetchall()
# Get active sessions - table doesn't exist, use empty list
active_sessions = []
# Get feature flags
cur.execute("""
SELECT * FROM feature_flags
ORDER BY feature_name
""")
feature_flags = cur.fetchall()
# Get feature flags - table doesn't exist, use empty list
feature_flags = []
# Get rate limits
# Get rate limits - table doesn't exist, use empty list
rate_limits = []
# Get system API key
cur.execute("""
SELECT * FROM api_rate_limits
ORDER BY api_key
SELECT api_key, created_at, regenerated_at, last_used_at,
usage_count, created_by, regenerated_by
FROM system_api_key
WHERE id = 1
""")
rate_limits = cur.fetchall()
api_key_data = cur.fetchone()
if api_key_data:
system_api_key = {
'api_key': api_key_data[0],
'created_at': api_key_data[1],
'regenerated_at': api_key_data[2],
'last_used_at': api_key_data[3],
'usage_count': api_key_data[4],
'created_by': api_key_data[5],
'regenerated_by': api_key_data[6]
}
else:
system_api_key = None
return render_template('license_config.html',
client_config=client_config,
active_sessions=active_sessions,
feature_flags=feature_flags,
rate_limits=rate_limits
rate_limits=rate_limits,
system_api_key=system_api_key
)
except Exception as e:
import traceback
current_app.logger.error(f"Error in license_config: {str(e)}")
current_app.logger.error(traceback.format_exc())
flash(f'Fehler beim Laden der Konfiguration: {str(e)}', 'error')
return render_template('license_config.html')
finally:
@@ -1042,8 +1048,6 @@ def update_client_config():
UPDATE client_configs
SET current_version = %s,
minimum_version = %s,
download_url = %s,
whats_new = %s,
heartbeat_interval = %s,
session_timeout = %s,
updated_at = CURRENT_TIMESTAMP
@@ -1051,8 +1055,6 @@ def update_client_config():
""", (
request.form.get('current_version'),
request.form.get('minimum_version'),
'', # download_url - no longer used
'', # whats_new - no longer used
30, # heartbeat_interval - fixed
60 # session_timeout - fixed
))
@@ -1272,3 +1274,92 @@ def get_analytics_token():
token = jwt.encode(payload, jwt_secret, algorithm='HS256')
return jsonify({'token': token})
# ===================== API KEY MANAGEMENT =====================
@admin_bp.route("/api-key/regenerate", methods=["POST"])
@login_required
def regenerate_api_key():
"""Regenerate the system API key"""
import string
import random
conn = get_connection()
cur = conn.cursor()
try:
# Generate new API key
year_part = datetime.now().strftime('%Y')
random_part = ''.join(random.choices(string.ascii_uppercase + string.digits, k=32))
new_api_key = f"AF-{year_part}-{random_part}"
# Update the API key
cur.execute("""
UPDATE system_api_key
SET api_key = %s,
regenerated_at = CURRENT_TIMESTAMP,
regenerated_by = %s
WHERE id = 1
""", (new_api_key, session.get('username')))
conn.commit()
flash('API Key wurde erfolgreich regeneriert', 'success')
# Log action
log_audit('API_KEY_REGENERATED', 'system_api_key', 1,
additional_info="API Key regenerated")
except Exception as e:
conn.rollback()
flash(f'Fehler beim Regenerieren des API Keys: {str(e)}', 'error')
finally:
cur.close()
conn.close()
return redirect(url_for('admin.license_config'))
@admin_bp.route("/test-api-key")
@login_required
def test_api_key():
"""Test route to check API key in database"""
try:
conn = get_connection()
cur = conn.cursor()
# Test if table exists
cur.execute("""
SELECT EXISTS (
SELECT FROM information_schema.tables
WHERE table_name = 'system_api_key'
);
""")
table_exists = cur.fetchone()[0]
# Get API key if table exists
api_key = None
if table_exists:
cur.execute("SELECT api_key FROM system_api_key WHERE id = 1;")
result = cur.fetchone()
if result:
api_key = result[0]
return jsonify({
'table_exists': table_exists,
'api_key': api_key,
'database': DATABASE_CONFIG['dbname']
})
except Exception as e:
return jsonify({
'error': str(e),
'database': DATABASE_CONFIG.get('dbname', 'unknown')
})
finally:
if 'cur' in locals():
cur.close()
if 'conn' in locals():
conn.close()