mirror of
https://github.com/stack-auth/stack.git
synced 2026-06-04 21:04:37 +08:00
57 lines
1.8 KiB
Python
57 lines
1.8 KiB
Python
import time
|
|
import requests
|
|
import webbrowser
|
|
import urllib.parse
|
|
|
|
def prompt_cli_login(
|
|
*,
|
|
base_url: str = "https://api.stack-auth.com",
|
|
app_url: str,
|
|
project_id: str,
|
|
publishable_client_key: str,
|
|
):
|
|
if not app_url:
|
|
raise Exception("app_url is required and must be set to the URL of the app you're authenticating with")
|
|
if not project_id:
|
|
raise Exception("project_id is required")
|
|
if not publishable_client_key:
|
|
raise Exception("publishable_client_key is required")
|
|
|
|
def post(endpoint, json):
|
|
return requests.request(
|
|
'POST',
|
|
f'{base_url}{endpoint}',
|
|
headers={
|
|
'Content-Type': 'application/json',
|
|
'x-stack-project-id': project_id,
|
|
'x-stack-access-type': 'client',
|
|
'x-stack-publishable-client-key': publishable_client_key,
|
|
},
|
|
json=json,
|
|
)
|
|
|
|
# Step 1: Initiate the CLI auth process
|
|
init = post('/api/v1/auth/cli', {
|
|
'expires_in_millis': 10 * 60 * 1000,
|
|
})
|
|
if init.status_code != 200:
|
|
raise Exception(f"Failed to initiate CLI auth: {init.status_code} {init.text}")
|
|
polling_code = init.json()['polling_code']
|
|
login_code = init.json()['login_code']
|
|
|
|
# Step 2: Open the browser for the user to authenticate
|
|
url = f'{app_url}/handler/cli-auth-confirm?login_code={urllib.parse.quote(login_code)}'
|
|
print(f"Opening browser to authenticate. If it doesn't open automatically, please visit:\n{url}")
|
|
webbrowser.open(url)
|
|
|
|
# Step 3: Retrieve the token
|
|
while True:
|
|
status = post('/api/v1/auth/cli/poll', {
|
|
'polling_code': polling_code,
|
|
})
|
|
if status.status_code != 200 and status.status_code != 201:
|
|
raise Exception(f"Failed to get CLI auth status: {status.status_code} {status.text}")
|
|
if status.json()['status'] == 'success':
|
|
return status.json()['refresh_token']
|
|
time.sleep(2)
|