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

Add auth support via command #108

Closed
MartinKolarik opened this issue Jun 25, 2024 · 3 comments · Fixed by #129
Closed

Add auth support via command #108

MartinKolarik opened this issue Jun 25, 2024 · 3 comments · Fixed by #129

Comments

@MartinKolarik
Copy link
Member

MartinKolarik commented Jun 25, 2024

  1. auth login - prints a link to open the web browser; the user signs in there and doesn't have to do anything else; then token is created and stored automatically
  2. auth login --with-token - reads and stores a token manually provided by the user via stdin
  3. auth status shows if there is a token stored or not
  4. auth logout removes the stored token (+ deletes from DB if it was created directly by the cli)

Implementation details

  • Pick a suitable OAuth2 client library:
    • Must support PKCE.
    • Must support authorization_code and refresh_token grants.
    • You'll also need to make introspection and revocation requests, but these are very simple to make even with a regular HTTP library, so it's ok if the oauth client doesn't support them directly.
  • We have a server at https://auth.globalping.io/
  • There's also a metadata endpoint that the client may support for endpoint discovery at https://auth.globalping.io/.well-known/oauth-authorization-server
  • Use the following client configuration:
    • Client ID: be231712-03f4-45bf-9f15-023506ce0b72
    • Client Secret: not provided/empty if possible; if the library requires it, use public as the value
    • Requested scopes: measurements
    • Redirect URL (pick the first port which is available):
["http://localhost:60000/callback","http://localhost:60010/callback","http://localhost:60020/callback","http://localhost:60030/callback","http://localhost:60040/callback","http://localhost:60100/callback","http://localhost:60110/callback","http://localhost:60120/callback","http://localhost:60130/callback","http://localhost:60140/callback"]
  1. Login:

    • Start a local server on one of the ports above. If none is available, print an error.
    • Use the authorization_code flow; print a message with a URL to the console and also attempt to automatically open it in the default browser.
    • When the user approves the app, he'll be redirected to localhost callback URL. Read the access code from there, request a token, and store it in ~/.globalping-cli. Redirect the user to https://dash.globalping.io/authorize/success if everything worked or https://dash.globalping.io/authorize/error if the token response failed. Shut down the local server.
  2. Login with token:

    • Read whatever the user provides. Use the introspection endpoint to validate that the token works (active: true). Store the token or print an error.
  3. Auth status:

    • If there's a token stored, use the introspection endpoint to validate it, then print a message "Logged in as {username}." This works regardless of how the token was obtained.
  4. Logout:

    • If the stored token was user-provided, just delete it. If it was requested via oauth, call the revocation endpoint with the refresh token (this will automatically revoke all access tokens too).

Notes on token handling

The oauth tokens will have an expiration of 30 days for the access token and 180 days for the refresh token. The refresh_token grant can be used to get a new pair of tokens. Store the expiration locally, and:

  • when the access token expires, and the refresh token is still valid, refresh both tokens before any API requests are made,
  • when the access token seems valid, but you got a 401 or 403 error from the API, and the refresh token is still valid, try refreshing the tokens
    • if this fails as well, delete the stored tokens
    • if this works, print a message for the user like "Access token successfully refreshed. Try repeating the measurement."

Make sure auth status works when the token is set via the ENV var too.

@jimaek
Copy link
Member

jimaek commented Jun 25, 2024

How about we remove --with-token? And just keep login. If there's nothing after it then browser flow, if there's a string after it then save token.

@MartinKolarik
Copy link
Member Author

The token will be read from stdin, not as an argument, that's why there is the flag. Passing tokens directly as arguments is a bad practice for security reasons, that's why virtually any CLI does it this way.

@MartinKolarik
Copy link
Member Author

@radulucut I added details to my original post, and everything you need should be ready now. You should also be able to log in with your GitHub account at https://dash.globalping.io/ and test all parts of the functionality.

@MartinKolarik MartinKolarik changed the title Add auth support via command (draft) Add auth support via command Sep 4, 2024
@MartinKolarik MartinKolarik linked a pull request Sep 22, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants