Skip to content

Commit

Permalink
chore: encode uri
Browse files Browse the repository at this point in the history
  • Loading branch information
xianml committed Jun 20, 2024
1 parent f6d023f commit 80ef5d7
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 20 deletions.
18 changes: 6 additions & 12 deletions src/bentoml_cli/auth_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ def do_POST(self) -> None:

class AuthCallbackHttpServer(HTTPServer):
"""
Simplistic HTTP Server to provide local callback URL for oauth2 provider
Simplistic HTTP Server to provide local callback URL for token provider
"""

def __init__(self, port):
Expand All @@ -120,7 +120,7 @@ def callback_url(self) -> str:

def wait_for_code(self, attempts: int = 3, timeout_per_attempt=10) -> Optional[str]:
"""
Wait for the server to open the callback page containing the code query parameter.
Wait for the server to callback from token provider.
It tries for #attempts with a timeout of #timeout_per_attempts for each attempt.
This prevents the CLI from getting stuck by unsolved callback URls
Expand All @@ -143,14 +143,8 @@ def wait_for_code(self, attempts: int = 3, timeout_per_attempt=10) -> Optional[s

def wait_indefinitely_for_code(self) -> Optional[str]:
"""
Wait indefinitely for the server to open the callback page containing the code query parameter.
Wait indefinitely for ther server to callback from token provider.
"""
while True:
try:
_method_with_timeout(self.handle_request, timeout_seconds=None)
except TimeoutException:
continue
if self.get_code() is not None:
return self.get_code()

return None
self.handle_request()
return self.get_code()

21 changes: 13 additions & 8 deletions src/bentoml_cli/cloud.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import contextlib
import json
import typing as t
import urllib.parse
import webbrowser
from os import environ

Expand Down Expand Up @@ -68,20 +69,24 @@ def login(shared_options: SharedOptions, endpoint: str, api_token: str) -> None:
reserve_free_port(enable_so_reuseport=True)
)
callback_server = AuthCallbackHttpServer(port)
authURL = (
f"{endpoint}/api-tokens/new?callback={callback_server.callback_url}"
)
baseURL = f'{endpoint}/api-tokens/new'
encodedURI = urllib.parse.quote(f'callback={callback_server.callback_url}')
authURL = f'{baseURL}?{encodedURI}'
input(f"Press Enter to open {authURL} in your browser...")
if webbrowser.open_new_tab(authURL):
click.echo(f"✅ Opened {authURL} in your web browser.")
else:
click.echo(
f"🚨 Failed to open browser. Try create a new API token at {endpoint}/api_tokens/new"
f"🚨 Failed to open browser. Try create a new API token at {baseURL}"
)
code = callback_server.wait_indefinitely_for_code()
if code is None:
raise ValueError("No code could be obtained from browser callback page")
api_token = code
try:
code = callback_server.wait_indefinitely_for_code()
if code is None:
raise ValueError("No code could be obtained from browser callback page")
api_token = code
except Exception:
click.echo("🚨 Error accquiring token from web browser")
return
elif choice == "paste":
api_token = click.prompt(
"? Paste your authentication token", type=str, hide_input=True
Expand Down

0 comments on commit 80ef5d7

Please sign in to comment.