1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
"""`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
|