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
72
|
"""
`browser-access`: whether this machine leaves, on each node, a copy of its keys
a browser can open with the passphrase — the application's Profile → Browser
access, kept by this machine (docs/MESHBAY_DESIGN.md §3.7).
`on`: each group opened here leaves a copy sealed under the passphrase-derived
key, when its node holds none or an outdated one. `off`: the copy a node holds
is withdrawn. Never set: nothing is written or withdrawn, so a CLI nobody
configured never undoes what the application of another computer does.
Set here and nowhere else. The hub keeps a mirror of it, written here as the
application writes it, but a mirror anyone with a hub session can write must
never make this machine upload keys: read, it only produces a message.
"""
import json
from ..client.hub import HubError
from ..errors import AUTH, CliError
from ..output import err, sentence
from .context import Context
HELP = "whether a browser may open your groups: leave a copy of your keys on nodes, or not"
EFFECT = {
"on": "Each group opened here from now on leaves a copy of your keys on its node, "
"sealed under your passphrase, so that a browser can open it.",
"off": "Each group opened here from now on withdraws the copy of your keys its node "
"holds; a browser will no longer open it with your passphrase.",
}
def add_parser(sub, parent) -> None:
p = sub.add_parser("browser-access", parents=[parent], help=HELP,
description=sentence(HELP) + ". As the application's Browser "
"access, for this machine. With no argument, shows the setting.")
p.add_argument("state", nargs="?", choices=("on", "off"))
async def run(ctx: Context) -> int:
a = ctx.args
account = ctx.account()
if not account.remembered:
raise CliError(AUTH, "This setting is kept with the saved session; run "
"`meshbay-cli login` first.")
if a.state is None:
try:
mirror = (await account.call(account.hub.preferences)).get("browser_access")
except (HubError, CliError):
mirror = None
mine = account.browser_access
if a.json:
print(json.dumps({"this_machine": mine, "hub": mirror}))
else:
print(f"This machine: {mine or 'not set (leaves the nodes as they are)'}")
print(f"The hub's copy: {mirror or 'none'} (informative: it sets nothing here)")
return 0
def put(state: dict, secrets: dict) -> None:
state["browser_access"] = a.state
await account.update(put)
try:
await account.call(account.hub.set_preference, "browser_access", a.state)
except (HubError, CliError) as e:
err(f"meshbay-cli: warning: the hub's copy of the setting was not updated "
f"({getattr(e, 'detail', None) or getattr(e, 'message', e)}); a browser may "
"explain a closed group less well.")
if a.json:
print(json.dumps({"this_machine": a.state}))
else:
print(f"Browser access: {a.state}. {EFFECT[a.state]}")
return 0
|