67 lines
2.5 KiB
Python
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()
|