#!/usr/bin/env python """Manage MODELBEAST users directly against the DB — for bootstrapping or when you're locked out of the UI. Run from the repo root: uv run python scripts/users.py ... """ import argparse import getpass import sys from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) from server import auth, db # noqa: E402 def main(): con = db.connect() ap = argparse.ArgumentParser() sub = ap.add_subparsers(dest="cmd", required=True) a = sub.add_parser("add") a.add_argument("username") a.add_argument("--owner", action="store_true") a.add_argument("--max-jobs", type=int, default=4) sub.add_parser("list") p = sub.add_parser("passwd") p.add_argument("username") d = sub.add_parser("delete") d.add_argument("username") args = ap.parse_args() if args.cmd == "add": pw = getpass.getpass("password: ") u = auth.create_user(con, args.username, pw, role="owner" if args.owner else "guest", max_active_jobs=args.max_jobs) print(f"created {u['username']} ({u['role']})") elif args.cmd == "list": for u in auth.list_users(con): print(f"{u['username']:<20} {u['role']:<7} max_jobs={u['max_active_jobs']}") elif args.cmd == "passwd": u = auth.get_user_by_name(con, args.username) if not u: sys.exit("no such user") auth.set_password(con, u["id"], getpass.getpass("new password: ")) print("updated") elif args.cmd == "delete": u = auth.get_user_by_name(con, args.username) if not u: sys.exit("no such user") auth.delete_user(con, u["id"]) print("deleted") if __name__ == "__main__": main()