API Key Config ist fertig
Dieser Commit ist enthalten in:
@@ -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()
|
||||
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren