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()