app.py auf APIRouter-Module umgestellt (db.py, templating.py, anode_client.py, auth.py, routers/geraete.py + vier Admin-Router als Platzhalter). benutzer.ist_admin (Migration 0002) + require_admin- Dependency (403 ohne Admin-Flag). Admin-Nav-Link im Header nur für Admin-Konten sichtbar. create_user.py um --admin-Flag erweitert. Die vier Admin-Bereiche (Technik/Datenbank, Geräte, Flows, Kunden) sind als Platzhalterseiten unter /admin/... verdrahtet und bekommen in den nächsten Schritten echte Funktionalität. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
58 lines
1.7 KiB
Python
58 lines
1.7 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)
|
|
parser.add_argument(
|
|
"--admin", action="store_true",
|
|
help="Konto bekommt organisationsübergreifenden Admin-Zugriff (/admin/...).",
|
|
)
|
|
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, ist_admin)
|
|
VALUES (%s, %s, %s, %s, %s)
|
|
""",
|
|
(uuid4(), args.organization_id, args.email, password_hash, args.admin),
|
|
)
|
|
|
|
print(f"Konto für {args.email} angelegt{' (Admin)' if args.admin else ''}.")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|