HEX
Server: LiteSpeed
System: Linux houston.panomity.com 6.8.0-100-generic #100-Ubuntu SMP PREEMPT_DYNAMIC Tue Jan 13 16:40:06 UTC 2026 x86_64
User: nudepix (1011)
PHP: 7.4.33
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
File: //opt/kw-schueler.bak.21032025/update_teacher_passwords.py
#!/usr/bin/env python3
"""
Dieses Skript aktualisiert die Passwörter für bestehende Lehrer in der Datenbank.
Es kann verwendet werden, um Passwörter manuell zurückzusetzen oder neue Lehrer hinzuzufügen.
"""

import mysql.connector
import bcrypt
import argparse
import sys
import csv
import os
from getpass import getpass

def hash_password(password):
    """Hasht ein Passwort mit bcrypt."""
    salt = bcrypt.gensalt(12)
    hashed = bcrypt.hashpw(password.encode('utf-8'), salt)
    return hashed.decode('utf-8')

def get_db_connection(host, user, password, database):
    """Stellt eine Verbindung zur MySQL-Datenbank her."""
    try:
        conn = mysql.connector.connect(
            host=host,
            user=user,
            password=password,
            database=database
        )
        return conn
    except Exception as e:
        print(f"Datenbankverbindungsfehler: {e}")
        return None

def update_teacher_password(conn, username, new_password):
    """Aktualisiert das Passwort eines Lehrers."""
    try:
        cursor = conn.cursor()
        hashed_password = hash_password(new_password)
        
        # Überprüfe, ob der Lehrer existiert
        cursor.execute("SELECT id FROM teachers WHERE username = %s", (username,))
        teacher = cursor.fetchone()
        
        if not teacher:
            print(f"Lehrer mit Benutzername '{username}' nicht gefunden.")
            return False
        
        # Aktualisiere das Passwort
        cursor.execute(
            "UPDATE teachers SET password_hash = %s WHERE username = %s",
            (hashed_password, username)
        )
        conn.commit()
        print(f"Passwort für Lehrer '{username}' erfolgreich aktualisiert.")
        return True
    except Exception as e:
        print(f"Fehler beim Aktualisieren des Passworts: {e}")
        return False
    finally:
        if cursor:
            cursor.close()

def add_teacher(conn, username, email, password, school_code, teacher_code):
    """Fügt einen neuen Lehrer hinzu."""
    try:
        cursor = conn.cursor()
        hashed_password = hash_password(password)
        
        # Überprüfe, ob der Lehrer bereits existiert
        cursor.execute("SELECT id FROM teachers WHERE username = %s OR email = %s", (username, email))
        teacher = cursor.fetchone()
        
        if teacher:
            print(f"Lehrer mit Benutzername '{username}' oder E-Mail '{email}' existiert bereits.")
            return False
        
        # Füge den Lehrer hinzu
        cursor.execute(
            "INSERT INTO teachers (username, email, password_hash, school_code, teacher_code) VALUES (%s, %s, %s, %s, %s)",
            (username, email, hashed_password, school_code, teacher_code)
        )
        conn.commit()
        print(f"Lehrer '{username}' erfolgreich hinzugefügt.")
        return True
    except Exception as e:
        print(f"Fehler beim Hinzufügen des Lehrers: {e}")
        return False
    finally:
        if cursor:
            cursor.close()

def list_teachers(conn):
    """Listet alle Lehrer auf."""
    try:
        cursor = conn.cursor(dictionary=True)
        cursor.execute("SELECT id, username, email, school_code, teacher_code, is_active FROM teachers")
        teachers = cursor.fetchall()
        
        if not teachers:
            print("Keine Lehrer gefunden.")
            return
        
        print("\nLehrerliste:")
        print("-" * 80)
        print(f"{'ID':<5} {'Benutzername':<15} {'E-Mail':<30} {'Schule':<10} {'Kürzel':<10} {'Aktiv':<5}")
        print("-" * 80)
        
        for teacher in teachers:
            print(f"{teacher['id']:<5} {teacher['username']:<15} {teacher['email']:<30} {teacher['school_code']:<10} {teacher['teacher_code']:<10} {'Ja' if teacher['is_active'] else 'Nein'}")
        
        print("-" * 80)
    except Exception as e:
        print(f"Fehler beim Auflisten der Lehrer: {e}")
    finally:
        if cursor:
            cursor.close()

def import_teachers_from_csv(conn, csv_file):
    """Importiert Lehrer aus einer CSV-Datei."""
    if not os.path.exists(csv_file):
        print(f"Datei '{csv_file}' nicht gefunden.")
        return
    
    try:
        with open(csv_file, 'r', newline='', encoding='utf-8') as f:
            reader = csv.DictReader(f)
            
            if not all(field in reader.fieldnames for field in ['username', 'email', 'password', 'school_code', 'teacher_code']):
                print("CSV-Datei hat nicht die erforderlichen Spalten: username, email, password, school_code, teacher_code")
                return
            
            success_count = 0
            error_count = 0
            
            for row in reader:
                if add_teacher(
                    conn,
                    row['username'],
                    row['email'],
                    row['password'],
                    row['school_code'],
                    row['teacher_code']
                ):
                    success_count += 1
                else:
                    error_count += 1
            
            print(f"\nImport abgeschlossen: {success_count} Lehrer erfolgreich importiert, {error_count} Fehler.")
    except Exception as e:
        print(f"Fehler beim Importieren der Lehrer: {e}")

def main():
    parser = argparse.ArgumentParser(description='Verwalte Lehrerkonten in der Datenbank.')
    parser.add_argument('--host', default='houston.ezoshosting.com', help='MySQL-Host')
    parser.add_argument('--user', default='klausurenweb_db', help='MySQL-Benutzer')
    parser.add_argument('--database', default='klausurenweb_db', help='MySQL-Datenbank')
    
    subparsers = parser.add_subparsers(dest='command', help='Befehle')
    
    # Befehl: update-password
    update_parser = subparsers.add_parser('update-password', help='Aktualisiere das Passwort eines Lehrers')
    update_parser.add_argument('username', help='Benutzername des Lehrers')
    update_parser.add_argument('--password', help='Neues Passwort (wenn nicht angegeben, wird nachgefragt)')
    
    # Befehl: add-teacher
    add_parser = subparsers.add_parser('add-teacher', help='Füge einen neuen Lehrer hinzu')
    add_parser.add_argument('username', help='Benutzername des Lehrers')
    add_parser.add_argument('email', help='E-Mail-Adresse des Lehrers')
    add_parser.add_argument('--password', help='Passwort (wenn nicht angegeben, wird nachgefragt)')
    add_parser.add_argument('--school', required=True, help='Schulcode (z.B. "mos")')
    add_parser.add_argument('--teacher', required=True, help='Lehrerkürzel (z.B. "end")')
    
    # Befehl: list-teachers
    subparsers.add_parser('list-teachers', help='Liste alle Lehrer auf')
    
    # Befehl: import-csv
    import_parser = subparsers.add_parser('import-csv', help='Importiere Lehrer aus einer CSV-Datei')
    import_parser.add_argument('csv_file', help='Pfad zur CSV-Datei')
    
    args = parser.parse_args()
    
    if not args.command:
        parser.print_help()
        return
    
    # Frage nach dem Datenbankpasswort
    db_password = getpass("MySQL-Passwort: ")
    
    # Stelle eine Verbindung zur Datenbank her
    conn = get_db_connection(args.host, args.user, db_password, args.database)
    if not conn:
        return
    
    try:
        if args.command == 'update-password':
            password = args.password
            if not password:
                password = getpass("Neues Passwort: ")
                confirm_password = getpass("Passwort bestätigen: ")
                if password != confirm_password:
                    print("Passwörter stimmen nicht überein.")
                    return
            
            update_teacher_password(conn, args.username, password)
        
        elif args.command == 'add-teacher':
            password = args.password
            if not password:
                password = getpass("Passwort: ")
                confirm_password = getpass("Passwort bestätigen: ")
                if password != confirm_password:
                    print("Passwörter stimmen nicht überein.")
                    return
            
            add_teacher(conn, args.username, args.email, password, args.school, args.teacher)
        
        elif args.command == 'list-teachers':
            list_teachers(conn)
        
        elif args.command == 'import-csv':
            import_teachers_from_csv(conn, args.csv_file)
    
    finally:
        if conn.is_connected():
            conn.close()

if __name__ == '__main__':
    main()