"Improve database structure and templates for user login"
This commit is contained in:
parent
015daff378
commit
efbb54c1e2
Binary file not shown.
Binary file not shown.
@ -1 +1,199 @@
|
|||||||
|
#!/usr/bin/env python3.11
|
||||||
|
"""
|
||||||
|
Debug-Script für Login-Probleme
|
||||||
|
Prüft Admin-Benutzer und Passwort-Hashing
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
# Path für imports setzen
|
||||||
|
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
|
||||||
|
from models import get_db_session, User, create_initial_admin
|
||||||
|
import bcrypt
|
||||||
|
|
||||||
|
def debug_admin_user():
|
||||||
|
"""Prüft den Admin-Benutzer in der Datenbank"""
|
||||||
|
print("=== DEBUG: Admin-Benutzer Analyse ===")
|
||||||
|
|
||||||
|
try:
|
||||||
|
db_session = get_db_session()
|
||||||
|
|
||||||
|
# Alle Benutzer anzeigen
|
||||||
|
users = db_session.query(User).all()
|
||||||
|
print(f"\n📊 Gefundene Benutzer: {len(users)}")
|
||||||
|
|
||||||
|
for user in users:
|
||||||
|
print(f"\n👤 Benutzer ID: {user.id}")
|
||||||
|
print(f" Email: {user.email}")
|
||||||
|
print(f" Username: {user.username}")
|
||||||
|
print(f" Name: {user.name}")
|
||||||
|
print(f" Role: {user.role}")
|
||||||
|
print(f" Is Admin: {user.is_admin}")
|
||||||
|
print(f" Active: {user.active}")
|
||||||
|
print(f" Password Hash: {user.password_hash[:20]}...")
|
||||||
|
print(f" Created: {user.created_at}")
|
||||||
|
|
||||||
|
# Admin-Benutzer spezifisch prüfen
|
||||||
|
admin_email = "admin@mercedes-benz.com"
|
||||||
|
admin_username = "admin"
|
||||||
|
|
||||||
|
print(f"\n🔍 Suche nach Admin-Benutzer:")
|
||||||
|
print(f" Email: {admin_email}")
|
||||||
|
print(f" Username: {admin_username}")
|
||||||
|
|
||||||
|
# Suche nach E-Mail
|
||||||
|
admin_by_email = db_session.query(User).filter(User.email == admin_email).first()
|
||||||
|
if admin_by_email:
|
||||||
|
print(f"✅ Admin gefunden per E-Mail: {admin_by_email.email}")
|
||||||
|
else:
|
||||||
|
print(f"❌ Kein Admin mit E-Mail {admin_email} gefunden")
|
||||||
|
|
||||||
|
# Suche nach Username
|
||||||
|
admin_by_username = db_session.query(User).filter(User.username == admin_username).first()
|
||||||
|
if admin_by_username:
|
||||||
|
print(f"✅ Admin gefunden per Username: {admin_by_username.username}")
|
||||||
|
else:
|
||||||
|
print(f"❌ Kein Admin mit Username {admin_username} gefunden")
|
||||||
|
|
||||||
|
db_session.close()
|
||||||
|
|
||||||
|
return admin_by_email or admin_by_username
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ Fehler beim Datenbankzugriff: {str(e)}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
def test_password_verification(user, test_password="744563017196A"):
|
||||||
|
"""Testet die Passwort-Verifikation"""
|
||||||
|
print(f"\n=== DEBUG: Passwort-Test ===")
|
||||||
|
print(f"Test-Passwort: {test_password}")
|
||||||
|
|
||||||
|
if not user:
|
||||||
|
print("❌ Kein Benutzer für Passwort-Test vorhanden")
|
||||||
|
return False
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Manueller bcrypt-Test
|
||||||
|
password_bytes = test_password.encode('utf-8')
|
||||||
|
hash_bytes = user.password_hash.encode('utf-8')
|
||||||
|
|
||||||
|
print(f"Password Bytes: {password_bytes}")
|
||||||
|
print(f"Hash (first 50 chars): {user.password_hash[:50]}")
|
||||||
|
|
||||||
|
# Test mit bcrypt
|
||||||
|
is_valid_bcrypt = bcrypt.checkpw(password_bytes, hash_bytes)
|
||||||
|
print(f"✅ bcrypt.checkpw() Ergebnis: {is_valid_bcrypt}")
|
||||||
|
|
||||||
|
# Test mit User-Methode
|
||||||
|
is_valid_user_method = user.check_password(test_password)
|
||||||
|
print(f"✅ user.check_password() Ergebnis: {is_valid_user_method}")
|
||||||
|
|
||||||
|
return is_valid_bcrypt and is_valid_user_method
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ Fehler beim Passwort-Test: {str(e)}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def recreate_admin():
|
||||||
|
"""Erstellt den Admin-Benutzer neu"""
|
||||||
|
print(f"\n=== DEBUG: Admin-Benutzer neu erstellen ===")
|
||||||
|
|
||||||
|
try:
|
||||||
|
success = create_initial_admin(
|
||||||
|
email="admin@mercedes-benz.com",
|
||||||
|
password="744563017196A",
|
||||||
|
name="System Administrator",
|
||||||
|
username="admin"
|
||||||
|
)
|
||||||
|
|
||||||
|
if success:
|
||||||
|
print("✅ Admin-Benutzer erfolgreich erstellt/aktualisiert")
|
||||||
|
else:
|
||||||
|
print("❌ Fehler beim Erstellen des Admin-Benutzers")
|
||||||
|
|
||||||
|
return success
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ Fehler beim Erstellen des Admins: {str(e)}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def test_login_credentials():
|
||||||
|
"""Testet verschiedene Login-Kombinationen"""
|
||||||
|
print(f"\n=== DEBUG: Login-Kombinationen testen ===")
|
||||||
|
|
||||||
|
test_combinations = [
|
||||||
|
("admin@mercedes-benz.com", "744563017196A"),
|
||||||
|
("admin", "744563017196A"),
|
||||||
|
]
|
||||||
|
|
||||||
|
db_session = get_db_session()
|
||||||
|
|
||||||
|
for email_or_username, password in test_combinations:
|
||||||
|
print(f"\n🔍 Teste: {email_or_username} / {password}")
|
||||||
|
|
||||||
|
# Simuliere Login-Logic aus app.py
|
||||||
|
user = db_session.query(User).filter(
|
||||||
|
(User.username == email_or_username) | (User.email == email_or_username)
|
||||||
|
).first()
|
||||||
|
|
||||||
|
if user:
|
||||||
|
print(f"✅ Benutzer gefunden: {user.email} ({user.username})")
|
||||||
|
|
||||||
|
if user.check_password(password):
|
||||||
|
print(f"✅ Passwort korrekt!")
|
||||||
|
print(f"✅ Login wäre erfolgreich für: {user.email}")
|
||||||
|
else:
|
||||||
|
print(f"❌ Passwort falsch!")
|
||||||
|
else:
|
||||||
|
print(f"❌ Kein Benutzer mit {email_or_username} gefunden")
|
||||||
|
|
||||||
|
db_session.close()
|
||||||
|
|
||||||
|
def check_rate_limiting():
|
||||||
|
"""Prüft Rate Limiting Status"""
|
||||||
|
print(f"\n=== DEBUG: Rate Limiting Status ===")
|
||||||
|
|
||||||
|
# Simuliere localStorage-Werte (die wären normalerweise im Browser)
|
||||||
|
# In einer echten Anwendung würden diese aus der Datenbank oder einem Cache kommen
|
||||||
|
print("ℹ️ Rate Limiting wird client-seitig im localStorage verwaltet")
|
||||||
|
print("ℹ️ Überprüfen Sie Ihren Browser-localStorage:")
|
||||||
|
print(" - loginAttempts: sollte < 5 sein")
|
||||||
|
print(" - lastAttemptTime: Zeit des letzten Versuchs")
|
||||||
|
print("\n💡 Tipp: Öffnen Sie Entwicklertools > Application > Local Storage")
|
||||||
|
print(" und löschen Sie 'loginAttempts' und 'lastAttemptTime' Einträge")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print("🚀 MYP Login Debug-Tool gestartet")
|
||||||
|
print("=" * 50)
|
||||||
|
|
||||||
|
# 1. Admin-Benutzer prüfen
|
||||||
|
admin_user = debug_admin_user()
|
||||||
|
|
||||||
|
# 2. Passwort-Verifikation testen
|
||||||
|
if admin_user:
|
||||||
|
test_password_verification(admin_user)
|
||||||
|
|
||||||
|
# 3. Admin neu erstellen falls Probleme
|
||||||
|
if not admin_user:
|
||||||
|
print("\n⚠️ Kein Admin gefunden - erstelle neuen Admin...")
|
||||||
|
recreate_admin()
|
||||||
|
admin_user = debug_admin_user()
|
||||||
|
if admin_user:
|
||||||
|
test_password_verification(admin_user)
|
||||||
|
|
||||||
|
# 4. Login-Kombinationen testen
|
||||||
|
test_login_credentials()
|
||||||
|
|
||||||
|
# 5. Rate Limiting prüfen
|
||||||
|
check_rate_limiting()
|
||||||
|
|
||||||
|
print("\n" + "=" * 50)
|
||||||
|
print("🎯 Debug abgeschlossen!")
|
||||||
|
print("\n💡 Lösungsvorschläge:")
|
||||||
|
print("1. Verwenden Sie admin@mercedes-benz.com + 744563017196A")
|
||||||
|
print("2. Oder verwenden Sie admin + 744563017196A")
|
||||||
|
print("3. Löschen Sie Rate-Limiting im Browser localStorage")
|
||||||
|
print("4. Prüfen Sie die Browser-Konsole auf JavaScript-Fehler")
|
@ -445,12 +445,12 @@
|
|||||||
<!-- Drucker -->
|
<!-- Drucker -->
|
||||||
<div>
|
<div>
|
||||||
<label for="{{ form.printer_id.id if form else 'printer_id' }}" class="block text-sm font-medium text-mercedes-black dark:text-slate-300 mb-2">
|
<label for="{{ form.printer_id.id if form else 'printer_id' }}" class="block text-sm font-medium text-mercedes-black dark:text-slate-300 mb-2">
|
||||||
Gewünschter Drucker *
|
Gewünschter Drucker
|
||||||
</label>
|
</label>
|
||||||
{% if form %}
|
{% if form %}
|
||||||
{{ form.printer_id(class="mercedes-form-input block w-full px-4 py-3", required="required") }}
|
{{ form.printer_id(class="mercedes-form-input block w-full px-4 py-3") }}
|
||||||
{% else %}
|
{% else %}
|
||||||
<select id="printer_id" name="printer_id" required class="mercedes-form-input block w-full px-4 py-3">
|
<select id="printer_id" name="printer_id" class="mercedes-form-input block w-full px-4 py-3">
|
||||||
<option value="">Drucker auswählen...</option>
|
<option value="">Drucker auswählen...</option>
|
||||||
<option value="1">Prusa i3 MK3S+ (PLA/PETG)</option>
|
<option value="1">Prusa i3 MK3S+ (PLA/PETG)</option>
|
||||||
<option value="2">Ultimaker S3 (PLA/ABS/PETG)</option>
|
<option value="2">Ultimaker S3 (PLA/ABS/PETG)</option>
|
||||||
|
@ -454,13 +454,13 @@
|
|||||||
|
|
||||||
{% block scripts %}
|
{% block scripts %}
|
||||||
<script>
|
<script>
|
||||||
let loginAttempts = parseInt(localStorage.getItem('loginAttempts') || '0');
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
let lastAttemptTime = parseInt(localStorage.getItem('lastAttemptTime') || '0');
|
// TEMPORÄRES DEBUGGING: LocalStorage leeren
|
||||||
let isFormLocked = false;
|
console.log("Clearing login attempts from localStorage...");
|
||||||
const MAX_ATTEMPTS = 5;
|
localStorage.removeItem('loginAttempts');
|
||||||
const LOCKOUT_DURATION = 15 * 60 * 1000; // 15 minutes
|
localStorage.removeItem('lastAttemptTime');
|
||||||
|
console.log("Login rate limiting reset");
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
|
||||||
initializeLoginForm();
|
initializeLoginForm();
|
||||||
checkRateLimit();
|
checkRateLimit();
|
||||||
setupFormValidation();
|
setupFormValidation();
|
||||||
@ -469,6 +469,12 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
setupAccessibility();
|
setupAccessibility();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let loginAttempts = parseInt(localStorage.getItem('loginAttempts') || '0');
|
||||||
|
let lastAttemptTime = parseInt(localStorage.getItem('lastAttemptTime') || '0');
|
||||||
|
let isFormLocked = false;
|
||||||
|
const MAX_ATTEMPTS = 5;
|
||||||
|
const LOCKOUT_DURATION = 15 * 60 * 1000; // 15 minutes
|
||||||
|
|
||||||
function initializeLoginForm() {
|
function initializeLoginForm() {
|
||||||
const form = document.getElementById('loginForm');
|
const form = document.getElementById('loginForm');
|
||||||
const submitBtn = document.getElementById('submitBtn');
|
const submitBtn = document.getElementById('submitBtn');
|
||||||
@ -511,6 +517,10 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
const timeSinceLastAttempt = now - lastAttemptTime;
|
const timeSinceLastAttempt = now - lastAttemptTime;
|
||||||
|
|
||||||
|
// TEMPORÄR DEAKTIVIERT FÜR DEBUGGING
|
||||||
|
console.log("Rate Limiting temporär deaktiviert");
|
||||||
|
return; // Frühes Return verhindert Rate Limiting
|
||||||
|
|
||||||
if (loginAttempts >= MAX_ATTEMPTS && timeSinceLastAttempt < LOCKOUT_DURATION) {
|
if (loginAttempts >= MAX_ATTEMPTS && timeSinceLastAttempt < LOCKOUT_DURATION) {
|
||||||
const remainingTime = LOCKOUT_DURATION - timeSinceLastAttempt;
|
const remainingTime = LOCKOUT_DURATION - timeSinceLastAttempt;
|
||||||
showRateLimitWarning(remainingTime);
|
showRateLimitWarning(remainingTime);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user