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_school_admin.py
#!/usr/bin/env python3
import bcrypt
import mysql.connector
import logging
import argparse
from mysql.connector import Error
import streamlit as st

# Konfiguriere Logging
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s'
)

def hash_password(password):
    """Hasht ein Passwort mit bcrypt."""
    # Generiere einen Salt und hashe das Passwort
    salt = bcrypt.gensalt(12)  # 12 Runden für die Sicherheit
    hashed = bcrypt.hashpw(password.encode('utf-8'), salt)
    return hashed.decode('utf-8')  # Speichere den Hash als String

def get_db_connection():
    """Stellt eine Verbindung zur MySQL-Datenbank her."""
    try:
        # Verbindungsdaten aus den Streamlit-Secrets
        connection = mysql.connector.connect(
            host=st.secrets["mysql"]["host"],
            user=st.secrets["mysql"]["user"],
            password=st.secrets["mysql"]["password"],
            database=st.secrets["mysql"]["database"]
        )
        if connection.is_connected():
            return connection
    except Error as e:
        logging.error(f"Fehler bei der Datenbankverbindung: {e}")
    return None

def update_school_admin_password(username, new_password):
    """Aktualisiert das Passwort eines Schuladministrators."""
    conn = get_db_connection()
    if not conn:
        logging.error("Keine Datenbankverbindung möglich")
        return False
    
    try:
        cursor = conn.cursor(dictionary=True)
        
        # Prüfe, ob der Schuladmin existiert
        cursor.execute("SELECT id FROM school_admins WHERE username = %s", (username,))
        admin = cursor.fetchone()
        
        if not admin:
            logging.error(f"Schuladmin mit Benutzername '{username}' nicht gefunden")
            return False
        
        # Hashe das neue Passwort
        hashed_password = hash_password(new_password)
        
        # Aktualisiere das Passwort
        cursor.execute(
            "UPDATE school_admins SET password_hash = %s WHERE username = %s",
            (hashed_password, username)
        )
        
        conn.commit()
        logging.info(f"Passwort für Schuladmin '{username}' erfolgreich aktualisiert")
        return True
    except Exception as e:
        logging.error(f"Fehler beim Aktualisieren des Passworts: {e}")
        return False
    finally:
        if conn.is_connected():
            cursor.close()
            conn.close()

def list_school_admins():
    """Listet alle Schuladministratoren auf."""
    conn = get_db_connection()
    if not conn:
        logging.error("Keine Datenbankverbindung möglich")
        return
    
    try:
        cursor = conn.cursor(dictionary=True)
        cursor.execute(
            """
            SELECT sa.id, sa.username, sa.email, s.name as school_name
            FROM school_admins sa
            JOIN schools s ON sa.school_id = s.id
            """
        )
        admins = cursor.fetchall()
        
        if not admins:
            logging.info("Keine Schuladministratoren gefunden")
            return
        
        logging.info("Vorhandene Schuladministratoren:")
        for admin in admins:
            logging.info(f"ID: {admin['id']}, Benutzername: {admin['username']}, E-Mail: {admin['email']}, Schule: {admin['school_name']}")
    except Exception as e:
        logging.error(f"Fehler beim Auflisten der Schuladministratoren: {e}")
    finally:
        if conn.is_connected():
            cursor.close()
            conn.close()

def create_school_admin(username, email, password, school_code):
    """Erstellt einen neuen Schuladministrator."""
    conn = get_db_connection()
    if not conn:
        logging.error("Keine Datenbankverbindung möglich")
        return False
    
    try:
        cursor = conn.cursor(dictionary=True)
        
        # Prüfe, ob die Schule existiert
        cursor.execute("SELECT id FROM schools WHERE code = %s", (school_code,))
        school = cursor.fetchone()
        
        if not school:
            logging.error(f"Schule mit Code '{school_code}' nicht gefunden")
            return False
        
        # Prüfe, ob Benutzername oder E-Mail bereits existieren
        cursor.execute("SELECT id FROM school_admins WHERE username = %s OR email = %s", (username, email))
        existing = cursor.fetchone()
        
        if existing:
            logging.error(f"Ein Schuladmin mit diesem Benutzernamen oder dieser E-Mail existiert bereits")
            return False
        
        # Hashe das Passwort
        hashed_password = hash_password(password)
        
        # Erstelle den neuen Schuladmin
        cursor.execute(
            """
            INSERT INTO school_admins (username, email, password_hash, school_id)
            VALUES (%s, %s, %s, %s)
            """,
            (username, email, hashed_password, school['id'])
        )
        
        conn.commit()
        logging.info(f"Schuladmin '{username}' für Schule mit Code '{school_code}' erfolgreich erstellt")
        return True
    except Exception as e:
        logging.error(f"Fehler beim Erstellen des Schuladministrators: {e}")
        return False
    finally:
        if conn.is_connected():
            cursor.close()
            conn.close()

def main():
    parser = argparse.ArgumentParser(description='Verwaltung von Schuladministratoren')
    subparsers = parser.add_subparsers(dest='command', help='Befehl')
    
    # Befehl zum Auflisten von Schuladmins
    list_parser = subparsers.add_parser('list', help='Schuladministratoren auflisten')
    
    # Befehl zum Aktualisieren eines Passworts
    update_parser = subparsers.add_parser('update', help='Passwort eines Schuladministrators aktualisieren')
    update_parser.add_argument('username', help='Benutzername des Schuladministrators')
    update_parser.add_argument('password', help='Neues Passwort')
    
    # Befehl zum Erstellen eines neuen Schuladmins
    create_parser = subparsers.add_parser('create', help='Neuen Schuladministrator erstellen')
    create_parser.add_argument('username', help='Benutzername')
    create_parser.add_argument('email', help='E-Mail-Adresse')
    create_parser.add_argument('password', help='Passwort')
    create_parser.add_argument('school_code', help='Schulcode')
    
    args = parser.parse_args()
    
    if args.command == 'list':
        list_school_admins()
    elif args.command == 'update':
        update_school_admin_password(args.username, args.password)
    elif args.command == 'create':
        create_school_admin(args.username, args.email, args.password, args.school_code)
    else:
        parser.print_help()

if __name__ == "__main__":
    main()