57 lines
1.7 KiB
Python
57 lines
1.7 KiB
Python
#!/usr/bin/env python3
|
|
"""Legt einmalig den ersten Admin-User an (interaktive Passwortabfrage).
|
|
|
|
Aufruf (nach Deployment, siehe ansible/roles/sqlite_init):
|
|
<venv>/bin/python scripts/create_admin.py --username admin
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import asyncio
|
|
import getpass
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
|
|
|
|
from app.db import close_db, get_db, init_db # noqa: E402
|
|
from app.security.passwords import hash_password # noqa: E402
|
|
|
|
|
|
async def main(username: str) -> None:
|
|
await init_db()
|
|
conn = get_db()
|
|
|
|
cursor = await conn.execute("SELECT 1 FROM users WHERE username = ?", (username,))
|
|
if await cursor.fetchone() is not None:
|
|
print(f"Benutzer '{username}' existiert bereits.", file=sys.stderr)
|
|
await close_db()
|
|
sys.exit(1)
|
|
|
|
password = getpass.getpass("Initiales Passwort (min. 12 Zeichen): ")
|
|
if len(password) < 12:
|
|
print("Passwort zu kurz.", file=sys.stderr)
|
|
await close_db()
|
|
sys.exit(1)
|
|
confirm = getpass.getpass("Passwort wiederholen: ")
|
|
if password != confirm:
|
|
print("Passwoerter stimmen nicht ueberein.", file=sys.stderr)
|
|
await close_db()
|
|
sys.exit(1)
|
|
|
|
await conn.execute(
|
|
"INSERT INTO users (username, password_hash, is_admin, must_change_password) "
|
|
"VALUES (?, ?, 1, 1)",
|
|
(username, hash_password(password)),
|
|
)
|
|
await conn.commit()
|
|
await close_db()
|
|
print(f"Admin-User '{username}' angelegt. TOTP-Einrichtung erfolgt beim ersten Login.")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("--username", required=True)
|
|
args = parser.parse_args()
|
|
asyncio.run(main(args.username))
|