kundenplattform/scripts/create_user.py
Thomas Stallinger c4825acd61 feat: initiale Kundenplattform (Login + Auftragskatalog-Auswahl)
Neuer, von provisioning-server (anode) getrennter Dienst, siehe ADR-0011:
FastAPI + Jinja2, eigene Postgres-DB (benutzer-Tabelle), eigenes
Service-Token (TUXFLOTTE_KUNDENPLATTFORM_TOKEN) für die Kommunikation mit
anode. Org-Zugehörigkeits-Prüfung passiert hier in der Anwendung vor jedem
Aufruf gegen anode.

Umfang v1: Login, Geräteliste, Auftragskatalog geräteweise aus-/abwählen
(inkl. der standardbrowser-Option für Brave). systemd-Unit läuft unter
eigenem unprivilegiertem System-User statt root.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-04 17:00:03 +02:00

54 lines
1.5 KiB
Python

"""
Manuelle Konto-Anlage für die Kundenplattform (kein Self-Service in v1, siehe
ADR-0011). Beispiel:
KUNDENPLATTFORM_DATABASE_URL=... .venv/bin/python scripts/create_user.py \\
--organization-id 11111111-1111-4111-8111-111111111111 \\
--email admin@schule-beispiel.de
"""
import argparse
import getpass
import os
import sys
from uuid import uuid4
import bcrypt
import psycopg
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--organization-id", required=True)
parser.add_argument("--email", required=True)
args = parser.parse_args()
database_url = os.environ.get("KUNDENPLATTFORM_DATABASE_URL")
if not database_url:
sys.exit("KUNDENPLATTFORM_DATABASE_URL ist nicht gesetzt.")
password = getpass.getpass("Passwort: ")
password_confirm = getpass.getpass("Passwort (Wiederholung): ")
if password != password_confirm:
sys.exit("Passwörter stimmen nicht überein.")
password_hash = bcrypt.hashpw(password.encode("utf-8"), bcrypt.gensalt()).decode("utf-8")
with psycopg.connect(database_url) as conn:
with conn.cursor() as cur:
cur.execute(
"""
INSERT INTO benutzer (id, organization_id, email, password_hash)
VALUES (%s, %s, %s, %s)
""",
(uuid4(), args.organization_id, args.email, password_hash),
)
print(f"Konto für {args.email} angelegt.")
if __name__ == "__main__":
main()