Skip to content

Commit

Permalink
[ASP-4053] Enhance user experience on jobbergate login (#402)
Browse files Browse the repository at this point in the history
* Try to open login url on browser
* Try to copy it to clipboard
  • Loading branch information
fschuch authored Nov 5, 2023
1 parent f7c28bd commit 8c242a3
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 45 deletions.
77 changes: 39 additions & 38 deletions jobbergate-cli/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,48 +4,49 @@ This file keeps track of all notable changes to jobbergate-cli

## Unreleased

- Added ability to open the login url on browser or copy it to clipboard

## 4.1.0a3 -- 2023-11-03

- Added --cluster-name, --execution-directory and --download parameters to create-job-script command on submit mode
- Change application-id, job-script-id and job-submission-id to have alias when displaying the id on the CLI


## 4.1.0a2 -- 2023-10-10

- Added a `create` for Job Scripts to to create without Template. (former `create` renamed to `render`)
- Fixed help information for id on `get-job-script`, `download-job-script`, and `get-job-submission` commands
- Added short arguments for backward compatiblity
- Added short arguments for backward compatibility
- Ignored username and password arguments if provided, aiming to keep backward compatibility
- Added support to select applications by identifier in update and delete commands
- Added show-files command to compat mode
- Added support to select all and deselect all options in checkboxes using Ctrl+A and Ctrl+R as shortcuts


## 4.1.0a1 -- 2023-10-02


## 4.1.0a0 -- 2023-09-25
- Added an alternative way to present to login url on narrow terminals

- Added an alternative way to present to login url on narrow terminals

## 4.0.0 -- 2023-09-14

- Modified internal details to address the new data model on Jobbergate API
- Drop support for Python 3.6
- Fixed refresh token not being updated on cache after token refresh


## 3.4.3 -- 2023-01-30
- Keep version in sync with the API.

- Keep version in sync with the API.

## 3.4.2 -- 2023-01-25
- Keep version in sync with the API.

- Keep version in sync with the API.

## 3.4.1 -- 2023-01-16
- Keep version in sync with the API.

- Keep version in sync with the API.

## 3.4.0 -- 2023-01-03

- Added support for `execution_parameters` in job submission at the CLI
- Added new command to download application files to the current working directory
- Added new command to download job script files to the current working directory
Expand All @@ -54,138 +55,138 @@ This file keeps track of all notable changes to jobbergate-cli
- Added parameters `from_job_script_id` to filter job submissions on the list command
- Fixed missing user defined fields when loading jobbergate.yaml


## 3.3.4 -- 2022-12-05

- Make the name optional when creating a new job script on the CLI
- Fixed `report_message` not showing on the detailed view of a job submissions


## 3.3.3 -- 2022-10-17
- Fixed issue with optional output directory

- Fixed issue with optional output directory

## 3.3.2 -- 2022-10-13

- Fixed `output_directory` on JobbergateConfig making it optional, as it is at the API level
- Fixed issues with `CRLF` end of lines when uploading application files


## 3.3.1 -- 2022-10-10

- Fixed refresh (invalid paths for refresh endpoints)
- Added DEFAULT_CLUSTER_NAME (fast-mode broken due to invalid cluster)


## 3.3.0 -- 2022-10-04

- Added error details to configuration error report
- Added ``OIDC_USE_HTTPS`` setting to allow non-https OIDC hosts
- Removed cluster validation from job-submission due to reliance on external cluster registry
- Added a `show-files` subcommand to `job-scripts` to show job script files
- Modified cache dir and dotenv path in order to avoid conflicts when installed alongside legacy jobbergate


## 3.2.4 -- 2022-09-12

- Refactor the logic to upload application files to the API.
- Remove file validation from the CLI.
- Remove compression of the upload files into tarballs.


## 3.2.3 -- 2022-08-01

- Patch cli authentication configurations.
- Added support to release on PyPI.


## 3.2.2 -- 2022-07-28
- Keep version in sync with the API.

- Keep version in sync with the API.

## 3.2.1 -- 2022-06-24
- Keep version in sync with the API.

- Keep version in sync with the API.

## 3.2.0 -- 2022-06-24

- Set ``environment`` variable for Sentry based on settings parameter.
- Adjusted variables and data structures for keycloak migration


## 3.1.1 -- 2022-06-01
- Added warning and handling for empty access tokens in the cache.

- Added warning and handling for empty access tokens in the cache.

## 3.1.0 -- 2022-04-20

- Added execution_directory to job submissions
- Added checks for empty cached token files


## 3.0.4 -- 2022-04-11

- Made supplying param_dict optional in API job-scripts create.
- Included some example scripts for working with API directly.


## 3.0.3 -- 2022-04-08
- Restored jobberappslib (with deprecation warnings as appropriate)

- Restored jobberappslib (with deprecation warnings as appropriate)

## 3.0.2 -- 2022-04-08
- Fixed compatiblity issues with python 3.6

- Fixed compatiblity issues with python 3.6

## 3.0.1 -- 2022-04-08
- Fixed publish github action

- Fixed publish github action

## 3.0.0 -- 2022-04-04

- Complete re-write of the Jobbergate CLI
- Used typer to implement the application
- Styled user output with Rich formatting
- Broke the code up into modules and functions for easier maintenance and reading
- Refactored the question asking system in applications
- Added over 100 unit tests


## 2.2.9 -- 2022-02-16

- Added AUTH0_LOGIN_DOMAIN setting
- Adjusted auth workflow to prefer AUTH0_LOGIN_DOMAIN over AUTH0_DOMAIN


## 2.2.8 -- 2022-02-15
- Fixed job submission data format for creation POST request

- Fixed job submission data format for creation POST request

## 2.2.7 -- 2022-02-15
- Applied fix for requests and added more debug logging

- Applied fix for requests and added more debug logging

## 2.2.6 -- 2022-02-14
- Added search and sort capability to the list endpoints to the API

- Added search and sort capability to the list endpoints to the API

## 2.2.5 -- 2022-02-14
- Removed job_script_data_as_string from create parameters for job_script create in API

- Removed job_script_data_as_string from create parameters for job_script create in API

## 2.2.4 -- 2022-02-14
- Fixed urls in the CLI again

- Fixed urls in the CLI again

## 2.2.3 -- 2022-02-14
- Improved error messages for users and captured error info

- Improved error messages for users and captured error info

## 2.2.2 -- 2022-02-07
- Fixed applicaiton creation

- Fixed applicaiton creation

## 2.2.1 -- 2022-02-03
- Fixed issue with SENTRY_DSN shadowing API initialization

- Fixed issue with SENTRY_DSN shadowing API initialization

## 2.2.0 -- 2022-02-03
- Removed trailing slashes from api endpoints

- Removed trailing slashes from api endpoints

## 2.1.2 -- 2022-02-02

- Revised login workflow to use client-credentials auth workflow
- Fixed IDENTITY_CLAIMS_KEY to be overrideable by environment


## 2.0.0 -- 2021-12-08

- Migrated from legacy jobbegate-cli project
32 changes: 26 additions & 6 deletions jobbergate-cli/jobbergate_cli/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Utilities for handling auth in jobbergate-cli.
"""

import webbrowser
from time import sleep
from typing import Dict, Optional, cast

Expand All @@ -16,7 +17,7 @@
from jobbergate_cli.render import terminal_message
from jobbergate_cli.requests import make_request
from jobbergate_cli.schemas import DeviceCodeData, IdentityData, JobbergateContext, Persona, TokenSet
from jobbergate_cli.text_tools import unwrap
from jobbergate_cli.text_tools import copy_to_clipboard, unwrap
from jobbergate_cli.time_loop import TimeLoop


Expand Down Expand Up @@ -242,18 +243,36 @@ def refresh_access_token(ctx: JobbergateContext, token_set: TokenSet):
token_set.refresh_token = refreshed_token_set.refresh_token


def open_on_browser(url: str) -> bool:
"""Open the url on the browser using webbrowser."""
try:
browser = webbrowser.get()
browser.open(url)
return True
except Exception as e:
logger.warning(f"Couldn't open login url on browser due to -- {str(e)}")
return False


def show_login_message(verification_uri: str):
"""Show a message to the user with a link to the auth provider to login."""
console = Console()
EXTRA_CHARS = 7 # for indentation and panel borders

kwargs = {}

if open_on_browser(verification_uri):
kwargs["footer"] = "The output was opened on your browser"
elif copy_to_clipboard(verification_uri):
kwargs["footer"] = "The output was copied to your clipboard"

if console.width >= len(verification_uri) + EXTRA_CHARS:
_show_login_standard_screen(verification_uri)
_show_login_standard_screen(verification_uri, **kwargs)
else:
_show_login_narrow_screen(verification_uri, console)
_show_login_narrow_screen(verification_uri, console, **kwargs)


def _show_login_narrow_screen(verification_uri: str, console: Console):
def _show_login_narrow_screen(verification_uri: str, console: Console, **kwargs):
"""Print the link out of the panel to make it easier to copy."""
terminal_message(
f"""
Expand All @@ -262,12 +281,13 @@ def _show_login_narrow_screen(verification_uri: str, console: Console):
Waiting up to {settings.OIDC_MAX_POLL_TIME / 60} minutes for you to complete the process...
""",
subject="Waiting for login",
**kwargs,
)
console.print(verification_uri, overflow="ignore", no_wrap=True, crop=False)
console.print()


def _show_login_standard_screen(verification_uri: str):
def _show_login_standard_screen(verification_uri: str, **kwargs):
"""Print a rich panel with a link to the auth provider to login."""
terminal_message(
f"""
Expand All @@ -278,6 +298,7 @@ def _show_login_standard_screen(verification_uri: str):
Waiting up to {settings.OIDC_MAX_POLL_TIME / 60} minutes for you to complete the process...
""",
subject="Waiting for login",
**kwargs,
)


Expand Down Expand Up @@ -309,7 +330,6 @@ def fetch_auth_tokens(ctx: JobbergateContext) -> TokenSet:
),
),
)

show_login_message(device_code_data.verification_uri_complete)

for tick in TimeLoop(
Expand Down
4 changes: 3 additions & 1 deletion jobbergate-cli/jobbergate_cli/text_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import textwrap

import pyperclip
from loguru import logger


def dedent(text: str) -> str:
Expand Down Expand Up @@ -55,5 +56,6 @@ def copy_to_clipboard(text: str) -> bool:
try:
pyperclip.copy(text)
return True
except Exception:
except Exception as e:
logger.warning(f"Couldn't copy to clipboard doe to -- {str(e)}")
return False
10 changes: 10 additions & 0 deletions jobbergate-cli/tests/test_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,16 @@ def dummy_context():
)


@pytest.fixture(autouse=True)
def mocked_open_on_browser(mocker):
"""
Provide a fixture that mocks the ``open_on_browser()`` function.
"""
mocked = mocker.patch("jobbergate_cli.auth.open_on_browser")
mocked.return_value = True
return mocked


@pytest.fixture
def make_token():
"""
Expand Down

0 comments on commit 8c242a3

Please sign in to comment.