"""`login`: sign in with the passphrase, and remember the session.""" import contextlib import json import sys from ..client.account import Account from ..client.groups import my_groups from ..client.store import FILE_KEY_NOTICE, KEY_FILE from ..errors import USAGE, CliError from ..output import err, safe, sentence, terminal from .context import Context from .logout import sign_out_stored HELP = "sign in, and remember the session so later runs need no passphrase" def add_parser(sub, parent) -> None: p = sub.add_parser("login", parents=[parent], help=HELP, description=sentence(HELP) + ".") p.add_argument("--no-remember", action="store_true", help="check the credentials and store nothing") async def run(ctx: Context) -> int: username = ctx.username or ctx.stored_username if not username: if not terminal(sys.stdin): raise CliError(USAGE, "Name the account with --user.") username = input("Username: ").strip() ctx.username = username if not username: raise CliError(USAGE, "No username given.") ctx.username = username notice = await ctx.hub.check_version() remember = not ctx.args.no_remember # Signing in again as the same account keeps its device key, its node # identities and its pins; another account replaces the store. previous = ctx.store.peek() account = Account(ctx.hub, username, ctx.passphrase) if previous.get("hub") == ctx.hub.url and previous.get("username") == username: with contextlib.suppress(CliError): ctx.store.load() account.state, account.secrets = ctx.store.state, ctx.store.secrets elif remember and previous: await sign_out_stored(ctx) await account.sign_in(remember=remember) groups = await my_groups(account) if remember: kind = await account.remember(ctx.store) if kind == KEY_FILE: err(FILE_KEY_NOTICE) else: await account.close() n = len(groups) if ctx.args.json: print(json.dumps({"username": username, "hub": ctx.hub.url, "groups": n, "remembered": remember, "key_store": ctx.store.peek().get("key_store") if remember else None})) else: verb = "Signed in" if remember else "Credentials accepted" print(f"{verb}: {safe(username)} on {ctx.hub.url} — " f"{n} group{'s' if n != 1 else ''}.") if notice: err(notice) return 0