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