Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support other nextstrain.org-like remotes #333

Merged
merged 4 commits into from
Jan 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 34 additions & 4 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,45 @@ This release drops support for Python versions 3.6 and 3.7 and adds support for

## Improvements

* The `nextstrain remote` family of commands now support alternative
nextstrain.org-like remotes such as internal Nextstrain Groups Server
instances and development instances of nextstrain.org. Authentication with
these remotes is supported via `nextstrain login` and related commands.
Remotes maintain their authentication alongside each other, e.g. you can be
logged into nextstrain.org as well as an alternative nextstrain.org-like
instance.

As an example, a Nextstrain Groups Server instance accessible at
nextstrain.example.com could now be logged into and interacted with like so:

nextstrain login nextstrain.example.com
nextstrain whoami nextstrain.example.com
nextstrain remote ls nextstrain.example.com/groups/bedford-lab/

The default remote is still nextstrain.org.
([#333](https://github.com/nextstrain/cli/pull/333))

* `nextstrain login` now performs authentication via a web browser by default
(using OpenID Connect 1.0 and OAuth 2.0). The previously method of direct
password entry is still used when a username is provided (e.g. with
`--username` or `-u`). See `nextstrain login --help` for more information.
([#333](https://github.com/nextstrain/cli/pull/333))

* With the new support for being logged into multiple remotes, `nextstrain
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the use case for being logged into multiple remotes simultaneously?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CDC will be running a Nextstrain Groups Server internally but also has Groups on nextstrain.org they use, so they'll be accessing two remotes: nextstrain.org and nextstrain.biotech.cdc.gov.

And other organizations have also expressed interest in having a Groups server they can use internally while still maintaining public Groups on nextstrain.org.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For development, it's also useful to be able to be manipulate authn with localhost:5000 without disrupting your normal nextstrain.org authn status.

logout` now also supports an `--all` flag to remove all locally-saved
credentials without having to logout of each remote separately.
([#333](https://github.com/nextstrain/cli/pull/333))

* `nextstrain remote upload` now skips gzip compression when uploading
zstandard-compressed (`.zst`) files, matching its behaviour for other types
of compressed files.
([#330](https://github.com/nextstrain/cli/pull/330))

* Commands that may automatically open a web browser, e.g. `nextstrain view`,
now respect the semi-conventional `NOBROWSER` environment variable to disable
opening a browser. Set `NOBROWSER` to a non-empty value to disable automatic
opening.
* Commands that may automatically open a web browser, e.g. `nextstrain view` or
`nextstrain login`, now respect the semi-conventional `NOBROWSER` environment
variable to disable opening a browser. Set `NOBROWSER` to a non-empty value
to disable automatic opening. When disabled, the URL to manually open will
be shown.
([#332](https://github.com/nextstrain/cli/pull/332))

* The error message emitted by the `nextstrain remote` family of commands when
Expand Down
22 changes: 18 additions & 4 deletions doc/commands/authorization.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,35 @@ nextstrain authorization

.. code-block:: none

usage: nextstrain authorization [-h]
usage: nextstrain authorization [-h] [<remote-url>]


Produce an Authorization header appropriate for nextstrain.org's web API.
Produce an Authorization header appropriate for the web API of nextstrain.org
(and other remotes).

This is a development tool unnecessary for normal usage. It's useful for
directly making API requests to nextstrain.org with `curl` or similar
commands. For example::
directly making API requests to nextstrain.org (and other remotes) with `curl`
or similar commands. For example::

curl -si https://nextstrain.org/whoami \
--header "Accept: application/json" \
--header @<(nextstrain authorization)

Exits with an error if no one is logged in.

positional arguments
====================



.. option:: <remote-url>

Remote URL for which to produce an Authorization header. Expects
URLs like the remote source/destination URLs used by the
`nextstrain remote` family of commands. Only the domain name
(technically, the origin) of the URL is required/used, but a full
URL may be specified.

options
=======

Expand Down
4 changes: 2 additions & 2 deletions doc/commands/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,11 @@ commands

.. option:: login

Log into Nextstrain.org. See :doc:`/commands/login`.
Log into Nextstrain.org (and other remotes). See :doc:`/commands/login`.

.. option:: logout

Log out of Nextstrain.org. See :doc:`/commands/logout`.
Log out of Nextstrain.org (and other remotes). See :doc:`/commands/logout`.

.. option:: whoami

Expand Down
45 changes: 31 additions & 14 deletions doc/commands/login.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,37 @@ nextstrain login

.. code-block:: none

usage: nextstrain login [-h] [--username <name>] [--no-prompt] [--renew]
usage: nextstrain login [-h] [--username <name>] [--no-prompt] [--renew] [<remote-url>]


Log into Nextstrain.org and save credentials for later use.
Log into Nextstrain.org (and other remotes) and save credentials for later use.

The first time you log in, you'll be prompted for your Nextstrain.org username
and password. After that, locally-saved authentication tokens will be used and
automatically renewed as needed when you run other `nextstrain` commands
requiring log in. You can also re-run this `nextstrain login` command to force
renewal if you want. You'll only be prompted for your username and password if
the locally-saved tokens are unable to be renewed or missing entirely.
The first time you log in to a remote you'll be prompted to authenticate via
your web browser or, if you provide a username (e.g. with --username), for your
Nextstrain.org password. After that, locally-saved authentication tokens will
be used and automatically renewed as needed when you run other `nextstrain`
commands requiring log in. You can also re-run this `nextstrain login` command
to force renewal if you want. You'll only be prompted to reauthenticate (via
your web browser or username/password) if the locally-saved tokens are unable
to be renewed or missing entirely.

If you log out of Nextstrain.org on other devices/clients (like your web
browser), you may be prompted to re-enter your username and password by this
command sooner than usual.
If you log out of Nextstrain.org (or other remotes) on other devices/clients
(like your web browser), you may be prompted to reauthenticate by this command
sooner than usual.

Your password itself is never saved locally.
Your username and password themselves are never saved locally.

positional arguments
====================



.. option:: <remote-url>

Remote URL to log in to, like the remote source/destination URLs
used by the `nextstrain remote` family of commands. Only the
domain name (technically, the origin) of the URL is required/used,
but a full URL may be specified.

options
=======
Expand All @@ -45,7 +59,7 @@ options

.. option:: --no-prompt

Never prompt for a username/password; succeed only if there are login credentials in the environment or existing valid/renewable tokens saved locally, otherwise error. Useful for scripting.
Never prompt for authentication (via web browser or username/password); succeed only if there are login credentials in the environment or existing valid/renewable tokens saved locally, otherwise error. Useful for scripting.

.. option:: --renew

Expand All @@ -62,4 +76,7 @@ of interactive input and/or command-line options:
.. envvar:: NEXTSTRAIN_PASSWORD

Password for nextstrain.org user. Required if :option:`--no-prompt` is
used without existing valid/renewable tokens.
used without existing valid/renewable tokens.

If you want to suppress ever opening a web browser automatically, you
may set the environment variable ``NOBROWSER=1``.
25 changes: 22 additions & 3 deletions doc/commands/logout.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,31 @@ nextstrain logout

.. code-block:: none

usage: nextstrain logout [-h]
usage: nextstrain logout [<remote-url>]
nextstrain logout --all
nextstrain logout --help


Log out of Nextstrain.org by deleting locally-saved credentials.
Log out of Nextstrain.org (and other remotes) by deleting locally-saved
credentials.

The authentication tokens are removed but not invalidated, so if you used them
outside of the `nextstrain` command, they will remain valid until they expire.

Other devices/clients (like your web browser) are not logged out of
Nextstrain.org.
Nextstrain.org (or other remotes).

positional arguments
====================



.. option:: <remote-url>

Remote URL to log out of, like the remote source/destination URLs
used by the `nextstrain remote` family of commands. Only the
domain name (technically, the origin) of the URL is required/used,
but a full URL may be specified.

options
=======
Expand All @@ -32,3 +47,7 @@ options

show this help message and exit

.. option:: --all

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

21 changes: 17 additions & 4 deletions doc/commands/whoami.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,29 @@ nextstrain whoami

.. code-block:: none

usage: nextstrain whoami [-h]
usage: nextstrain whoami [-h] [<remote-url>]


Show information about the logged-in user.
Show information about the logged-in user for Nextstrain.org (and other
remotes).

The username, email address, and Nextstrain Groups memberships of the currently
logged-in user are shown.
The username, email address (if available), and Nextstrain Groups memberships
of the currently logged-in user are shown.
victorlin marked this conversation as resolved.
Show resolved Hide resolved

Exits with an error if no one is logged in.

positional arguments
====================



.. option:: <remote-url>

Remote URL for which to show the logged-in user. Expects URLs like
the remote source/destination URLs used by the `nextstrain remote`
family of commands. Only the domain name (technically, the origin)
of the URL is required/used, but a full URL may be specified.

options
=======

Expand Down
14 changes: 12 additions & 2 deletions doc/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,23 @@ resources from our ["testing" configuration][], you can configure `nextstrain`
with the same, e.g.:

export NEXTSTRAIN_DOT_ORG=http://localhost:5000
export NEXTSTRAIN_COGNITO_USER_POOL_ID="$(jq -r .COGNITO_USER_POOL_ID ../nextstrain.org/env/testing/config.json)"
export NEXTSTRAIN_COGNITO_CLI_CLIENT_ID="$(jq -r .OAUTH2_CLI_CLIENT_ID ../nextstrain.org/env/testing/config.json)"

nextstrain login
nextstrain whoami
nextstrain remote ls groups/test-private

Most of the times the above is not necessary, however, as you can specify the
local remote explicitly instead of pretending it's nextstrain.org, e.g.:
Copy link
Member

@jameshadfield jameshadfield Jan 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I interpret this section as saying the following are equivalent:

  1. Set default remote via env variable, e.g. NEXTSTRAIN_DOT_ORG=http://localhost:5000 nextstrain login and NEXTSTRAIN_DOT_ORG=http://localhost:5000 nextstrain remote ls groups/test.
  2. Specify remote in command, e.g. nextstrain login localhost:5000, nextstrain remote ls http://localhost:5000/groups/test

And that neither will access https://nextstrain.org. Is this correct?

Copy link
Member

@jameshadfield jameshadfield Jan 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have only a cursory understanding of how the CLI, nextstrain.org server (perhaps localhost) and cognito are interacting here.

When we login with nextstrain login localhost:5000 with the nextstrain.org server running at localhost:5000, is this remote the authz server as far as the CLI is concerned? And thus everything to do with cognito (user pools etc) has been lifted out of the CLI and into the remote? And thus any tokens the CLI receives are only ever interacting with the provided remote?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I interpret this section as saying the following are equivalent: […] And that neither will access https://nextstrain.org/. Is this correct?

They're equivalent except for the short code path before NEXTSTRAIN_DOT_ORG is used to potentially override what "nextstrain.org" means (in nextstrain.cli.remote.parse_remote_path()). That is, once the remote is parsed, they're equivalent.

Neither will access https://nextstrain.org itself.

When we login with nextstrain login localhost:5000 with the nextstrain.org server running at localhost:5000, is this remote the authz server as far as the CLI is concerned? And thus everything to do with cognito (user pools etc) has been lifted out of the CLI and into the remote? And thus any tokens the CLI receives are only ever interacting with the provided remote?

No, the CLI still interacts with the OIDC/OAuth2 authorization server (aka the IdP), which in our case is Cognito but in CDC's case is Entra ID (née Azure AD). It obtains the IdP information from the remote, so it doesn't have to be hardcoded. I do have a rough WIP of docs for this interaction to help folks understand, but it's not up yet.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. At least this way the identity provider configuration has been lifted out of the CLI and into the remote.


nextstrain remote ls http://localhost:5000/groups/test

nextstrain login http://localhost:5000
nextstrain whoami http://localhost:5000
nextstrain remote ls http://localhost:5000/groups/test-private

Setting `NEXTSTRAIN_DOT_ORG` is mostly useful when testing the default-remote
code paths themselves.

## Releasing

New releases are made frequently and tagged in git using a [_signed_ tag][].
Expand Down
Loading
Loading