Skip to content

Commit a229ead

Browse files
committed
logout: Add --all flag remove all locally-saved credentials
It's handy and reassuring to be able to clear all login credentials without remembering what remotes you're logged into.
1 parent e74ee80 commit a229ead

File tree

3 files changed

+56
-6
lines changed

3 files changed

+56
-6
lines changed

doc/commands/logout.rst

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ nextstrain logout
1212

1313
.. code-block:: none
1414
15-
usage: nextstrain logout [-h] [<remote-url>]
15+
usage: nextstrain logout [<remote-url>]
16+
nextstrain logout --all
17+
nextstrain logout --help
1618
1719
1820
Log out of Nextstrain.org (and other remotes) by deleting locally-saved
@@ -45,3 +47,7 @@ options
4547

4648
show this help message and exit
4749

50+
.. option:: --all
51+
52+
Log out of all remotes for which there are locally-saved credentials
53+

nextstrain/cli/authn/__init__.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,29 @@ def logout(origin: Origin):
145145
print(f"Not logged in to {origin}.", file = stderr)
146146

147147

148+
def logout_all():
149+
"""
150+
Remove **all** locally-saved credentials.
151+
152+
Equivalent to calling :func:`logout` on all origins found in the secrets
153+
file.
154+
"""
155+
with config.write_lock():
156+
secrets = config.load(config.SECRETS)
157+
158+
sections = [
159+
(section, _parse_section(section))
160+
for section in secrets
161+
if _parse_section(section) ]
162+
163+
for section, origin in sections:
164+
del secrets[section]
165+
print(f"Credentials for {origin} removed from {config.SECRETS}.", file = stderr)
166+
print(f"Logged out of {origin}.", file = stderr)
167+
168+
config.save(secrets, config.SECRETS)
169+
170+
148171
def current_user(origin: Origin) -> Optional[User]:
149172
"""
150173
Information about the currently logged in user for *origin*, if any.
@@ -237,3 +260,12 @@ def _config_section(origin: Origin) -> str:
237260
if origin == "https://nextstrain.org":
238261
return CONFIG_SECTION
239262
return f"{CONFIG_SECTION} {origin}"
263+
264+
265+
def _parse_section(section: str) -> Optional[Origin]:
266+
if section == CONFIG_SECTION:
267+
return Origin("https://nextstrain.org")
268+
elif section.startswith(CONFIG_SECTION + " "):
269+
return Origin(section.split(" ", 1)[1])
270+
else:
271+
return None

nextstrain/cli/command/logout.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,16 @@
99
Nextstrain.org (or other remotes).
1010
"""
1111
from inspect import cleandoc
12+
from .. import authn
1213
from ..remote import parse_remote_path
1314

1415

1516
def register_parser(subparser):
17+
"""
18+
%(prog)s [<remote-url>]
19+
%(prog)s --all
20+
%(prog)s --help
21+
"""
1622
parser = subparser.add_parser("logout", help = "Log out of Nextstrain.org (and other remotes)")
1723

1824
parser.add_argument(
@@ -27,14 +33,20 @@ def register_parser(subparser):
2733
nargs = "?",
2834
default = "nextstrain.org")
2935

30-
# XXX TODO: Supporting `nextstrain logout --all` would be nice.
31-
# -trs, 15 Nov 2023
36+
parser.add_argument(
37+
"--all",
38+
help = "Log out of all remotes for which there are locally-saved credentials",
39+
action = "store_true")
3240

3341
return parser
3442

3543

3644
def run(opts):
37-
remote, url = parse_remote_path(opts.remote)
38-
assert url.origin
45+
if opts.all:
46+
authn.logout_all()
47+
48+
else:
49+
remote, url = parse_remote_path(opts.remote)
50+
assert url.origin
3951

40-
remote.logout(url.origin)
52+
remote.logout(url.origin)

0 commit comments

Comments
 (0)