diff --git a/backend/scripts/create_admin.py b/backend/scripts/create_admin.py new file mode 100644 index 0000000..7ae0aa0 --- /dev/null +++ b/backend/scripts/create_admin.py @@ -0,0 +1,49 @@ +"""Einmaliges Anlegen des ersten Administration-Benutzers (idempotent). + +Deployment-Regel (Prompt 19): nur Skript-Datei hier, Ausführung auf Zielsystem. + +Aufruf (im aktivierten venv auf dem Server): + + python -m scripts.create_admin --login admin --name "Administrator" --password "..." +""" + +from __future__ import annotations + +import argparse +import asyncio + +from sqlalchemy import select + +from app.core.security import hash_password +from app.db.session import SessionLocal +from app.models.auth import Benutzer, BenutzerRolle, RolleTyp + + +async def erstelle_admin(login: str, name: str, password: str, email: str | None) -> None: + async with SessionLocal() as db: + bestehender = (await db.execute(select(Benutzer).where(Benutzer.login == login))).scalar_one_or_none() + if bestehender is not None: + print(f"Übersprungen (Login existiert bereits): {login}") + return + + benutzer = Benutzer(name=name, login=login, passwort_hash=hash_password(password), email=email) + db.add(benutzer) + await db.flush() + db.add(BenutzerRolle(benutzer_id=benutzer.id, rolle=RolleTyp.administration)) + await db.commit() + print(f"Angelegt: {login} (id={benutzer.id}, Rolle administration)") + + +def main() -> None: + parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) + parser.add_argument("--login", required=True) + parser.add_argument("--name", required=True) + parser.add_argument("--password", required=True) + parser.add_argument("--email", default=None) + argumente = parser.parse_args() + + asyncio.run(erstelle_admin(argumente.login, argumente.name, argumente.password, argumente.email)) + + +if __name__ == "__main__": + main()