modelbeast/scripts/users.py
type-two 532294b7a5 users.py: 'token <name>' subcommand — mint named API keys from the CLI
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 22:29:51 +10:00

67 lines
2.5 KiB
Python

#!/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")
t = sub.add_parser("token", help="mint a named API token (printed ONCE — store it in a .env)")
t.add_argument("name", help="what this key is for, e.g. m1ultra, deadstock-agent")
t.add_argument("--user", default=None, help="username to bind to (default: the owner)")
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")
elif args.cmd == "token":
if args.user:
u = auth.get_user_by_name(con, args.user)
else:
u = next((x for x in auth.list_users(con) if x["role"] == "owner"), None)
if not u:
sys.exit("no such user")
raw = auth.create_token(con, u["id"], name=args.name)
print(f"# token '{args.name}' for {u['username']} — shown once, goes in a .env:")
print(f"MB_TOKEN={raw}")
if __name__ == "__main__":
main()