mirror of
https://github.com/trustgraph-ai/trustgraph.git
synced 2026-07-03 06:51:00 +02:00
Users are global entities, not scoped to workspaces. This change: Track A — Global usernames: - Change iam_users_by_username to PRIMARY KEY (username), removing workspace from the lookup key - Login looks up username globally, no workspace required - Username uniqueness is enforced globally, not per-workspace - Login -w now overrides the JWT workspace (session workspace) rather than selecting which user registry to search Track B — Rename workspace to default_workspace: - UserRecord.workspace → UserRecord.default_workspace - Identity.workspace → Identity.default_workspace - JWT claim "workspace" → "default_workspace" - IamResponse.resolved_workspace → resolved_default_workspace - WebSocket auth-ok frame field → default_workspace - Socket clients read default_workspace from auth-ok - _user_record_to_dict wire key → default_workspace - CLI help text and output updated throughout - Test files updated for renamed fields
62 lines
1.5 KiB
Python
62 lines
1.5 KiB
Python
"""
|
|
Log in with username / password. Prints the resulting JWT to
|
|
stdout so it can be captured for subsequent CLI use.
|
|
"""
|
|
|
|
import argparse
|
|
import getpass
|
|
import sys
|
|
|
|
from ._iam import DEFAULT_URL, call_auth, run_main
|
|
|
|
|
|
def do_login(args):
|
|
password = args.password
|
|
if not password:
|
|
password = getpass.getpass(f"Password for {args.username}: ")
|
|
|
|
body = {
|
|
"username": args.username,
|
|
"password": password,
|
|
}
|
|
if args.workspace:
|
|
body["workspace"] = args.workspace
|
|
|
|
resp = call_auth(args.api_url, "/api/v1/auth/login", None, body)
|
|
|
|
jwt = resp.get("jwt", "")
|
|
expires = resp.get("jwt_expires", "")
|
|
|
|
if expires:
|
|
print(f"JWT expires: {expires}", file=sys.stderr)
|
|
# Machine-readable on stdout.
|
|
print(jwt)
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(
|
|
prog="tg-login", description=__doc__,
|
|
)
|
|
parser.add_argument(
|
|
"-u", "--api-url", default=DEFAULT_URL,
|
|
help=f"API URL (default: {DEFAULT_URL})",
|
|
)
|
|
parser.add_argument(
|
|
"--username", required=True, help="Username",
|
|
)
|
|
parser.add_argument(
|
|
"--password", default=None,
|
|
help="Password (prompted if omitted)",
|
|
)
|
|
parser.add_argument(
|
|
"-w", "--workspace", default=None,
|
|
help=(
|
|
"Override the default workspace for this session's JWT. "
|
|
"If omitted, uses the user's stored default workspace."
|
|
),
|
|
)
|
|
run_main(do_login, parser)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|