Skip to content

Commit

Permalink
logout: Add --all flag remove all locally-saved credentials
Browse files Browse the repository at this point in the history
It's handy and reassuring to be able to clear all login credentials
without remembering what remotes you're logged into.
  • Loading branch information
tsibley committed Jan 12, 2024
1 parent e74ee80 commit a229ead
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 6 deletions.
8 changes: 7 additions & 1 deletion doc/commands/logout.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ nextstrain logout

.. code-block:: none
usage: nextstrain logout [-h] [<remote-url>]
usage: nextstrain logout [<remote-url>]
nextstrain logout --all
nextstrain logout --help
Log out of Nextstrain.org (and other remotes) by deleting locally-saved
Expand Down Expand Up @@ -45,3 +47,7 @@ options

show this help message and exit

.. option:: --all

Log out of all remotes for which there are locally-saved credentials

32 changes: 32 additions & 0 deletions nextstrain/cli/authn/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,29 @@ def logout(origin: Origin):
print(f"Not logged in to {origin}.", file = stderr)


def logout_all():
"""
Remove **all** locally-saved credentials.
Equivalent to calling :func:`logout` on all origins found in the secrets
file.
"""
with config.write_lock():
secrets = config.load(config.SECRETS)

sections = [
(section, _parse_section(section))
for section in secrets
if _parse_section(section) ]

for section, origin in sections:
del secrets[section]
print(f"Credentials for {origin} removed from {config.SECRETS}.", file = stderr)
print(f"Logged out of {origin}.", file = stderr)

config.save(secrets, config.SECRETS)


def current_user(origin: Origin) -> Optional[User]:
"""
Information about the currently logged in user for *origin*, if any.
Expand Down Expand Up @@ -237,3 +260,12 @@ def _config_section(origin: Origin) -> str:
if origin == "https://nextstrain.org":
return CONFIG_SECTION
return f"{CONFIG_SECTION} {origin}"


def _parse_section(section: str) -> Optional[Origin]:
if section == CONFIG_SECTION:
return Origin("https://nextstrain.org")
elif section.startswith(CONFIG_SECTION + " "):
return Origin(section.split(" ", 1)[1])
else:
return None
22 changes: 17 additions & 5 deletions nextstrain/cli/command/logout.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,16 @@
Nextstrain.org (or other remotes).
"""
from inspect import cleandoc
from .. import authn
from ..remote import parse_remote_path


def register_parser(subparser):
"""
%(prog)s [<remote-url>]
%(prog)s --all
%(prog)s --help
"""
parser = subparser.add_parser("logout", help = "Log out of Nextstrain.org (and other remotes)")

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

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

return parser


def run(opts):
remote, url = parse_remote_path(opts.remote)
assert url.origin
if opts.all:
authn.logout_all()

else:
remote, url = parse_remote_path(opts.remote)
assert url.origin

remote.logout(url.origin)
remote.logout(url.origin)

0 comments on commit a229ead

Please sign in to comment.