Lizenzkey Generator

Dieser Commit ist enthalten in:
2025-06-07 22:58:11 +02:00
Ursprung b0c8e8efc0
Commit 0379391736
6 geänderte Dateien mit 281 neuen und 5 gelöschten Zeilen

Datei anzeigen

@@ -18,6 +18,9 @@ import logging
import random
import hashlib
import requests
import secrets
import string
import re
load_dotenv()
@@ -548,6 +551,50 @@ def verify_recaptcha(response):
logging.error(f"Unerwarteter Fehler bei reCAPTCHA: {str(e)}")
return False
def generate_license_key(license_type='full'):
"""
Generiert einen Lizenzschlüssel im Format: AF-YYYYMMFT-XXXX-YYYY-ZZZZ
AF = Account Factory (Produktkennung)
YYYY = Jahr
MM = Monat
FT = F für Fullversion, T für Testversion
XXXX-YYYY-ZZZZ = Zufällige alphanumerische Zeichen
"""
# Erlaubte Zeichen (ohne verwirrende wie 0/O, 1/I/l)
chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789'
# Datum-Teil
now = datetime.now()
date_part = now.strftime('%Y%m')
type_char = 'F' if license_type == 'full' else 'T'
# Zufällige Teile generieren (3 Blöcke à 4 Zeichen)
parts = []
for _ in range(3):
part = ''.join(secrets.choice(chars) for _ in range(4))
parts.append(part)
# Key zusammensetzen
key = f"AF-{date_part}{type_char}-{parts[0]}-{parts[1]}-{parts[2]}"
return key
def validate_license_key(key):
"""
Validiert das License Key Format
Erwartet: AF-YYYYMMFT-XXXX-YYYY-ZZZZ
"""
if not key:
return False
# Pattern für das spezifische Format
# AF- (fest) + 6 Ziffern (YYYYMM) + F oder T + - + 4 Zeichen + - + 4 Zeichen + - + 4 Zeichen
pattern = r'^AF-\d{6}[FT]-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}$'
# Großbuchstaben für Vergleich
return bool(re.match(pattern, key.upper()))
@app.route("/login", methods=["GET", "POST"])
def login():
# Timing-Attack Schutz - Start Zeit merken
@@ -672,6 +719,51 @@ def heartbeat():
'username': session.get('username')
})
@app.route("/api/generate-license-key", methods=['POST'])
@login_required
def api_generate_key():
"""API Endpoint zur Generierung eines neuen Lizenzschlüssels"""
try:
# Lizenztyp aus Request holen (default: full)
data = request.get_json() or {}
license_type = data.get('type', 'full')
# Key generieren
key = generate_license_key(license_type)
# Prüfen ob Key bereits existiert (sehr unwahrscheinlich aber sicher ist sicher)
conn = get_connection()
cur = conn.cursor()
# Wiederhole bis eindeutiger Key gefunden
attempts = 0
while attempts < 10: # Max 10 Versuche
cur.execute("SELECT 1 FROM licenses WHERE license_key = %s", (key,))
if not cur.fetchone():
break # Key ist eindeutig
key = generate_license_key(license_type)
attempts += 1
cur.close()
conn.close()
# Log für Audit
log_audit('GENERATE_KEY', 'license',
additional_info={'type': license_type, 'key': key})
return jsonify({
'success': True,
'key': key,
'type': license_type
})
except Exception as e:
logging.error(f"Fehler bei Key-Generierung: {str(e)}")
return jsonify({
'success': False,
'error': 'Fehler bei der Key-Generierung'
}), 500
@app.route("/")
@login_required
def dashboard():
@@ -841,11 +933,16 @@ def create_license():
if request.method == "POST":
name = request.form["customer_name"]
email = request.form["email"]
license_key = request.form["license_key"]
license_key = request.form["license_key"].upper() # Immer Großbuchstaben
license_type = request.form["license_type"]
valid_from = request.form["valid_from"]
valid_until = request.form["valid_until"]
# Validiere License Key Format
if not validate_license_key(license_key):
flash('Ungültiges License Key Format! Erwartet: AF-YYYYMMFT-XXXX-YYYY-ZZZZ', 'error')
return redirect(url_for('create_license'))
conn = get_connection()
cur = conn.cursor()