Skip to content
This repository was archived by the owner on Aug 20, 2025. It is now read-only.

Commit aaf8386

Browse files
committed
Adding demo CLI for fetching tokens using the device auth flow
1 parent f959091 commit aaf8386

File tree

2 files changed

+110
-0
lines changed

2 files changed

+110
-0
lines changed

oidc-device-flow/helpers.py

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import os
2+
import requests
3+
import jwt
4+
import time
5+
import json
6+
import webbrowser
7+
import http.server
8+
from urllib.parse import urlencode, parse_qs
9+
10+
def get_discovery_document(url):
11+
response = requests.get(url)
12+
return response.json()
13+
14+
15+
def request_device_code(discovery_doc, client_credentials):
16+
data={}
17+
data.update(client_credentials)
18+
data.update({'scope': 'offline_access' })
19+
response = requests.post(
20+
discovery_doc["device_authorization_endpoint"], data=data
21+
)
22+
if response.status_code == 200:
23+
return response.json()
24+
else:
25+
print(f"Failed to obtain device code. Status code: {response.status_code}")
26+
print(f"Response content: {response.content}")
27+
return None
28+
29+
30+
31+
def poll_for_access_token(
32+
discovery_doc, client_credentials, device_code, interval, timeout
33+
):
34+
payload = {
35+
"grant_type": "urn:ietf:params:oauth:grant-type:device_code",
36+
"device_code": device_code,
37+
"client_id": client_credentials["client_id"]
38+
}
39+
start_time = time.time()
40+
print("\nWaiting for device to be authorized ...")
41+
while time.time() - start_time < timeout:
42+
response = requests.post(discovery_doc["token_endpoint"], data=payload)
43+
if response.status_code == 200:
44+
return response.json()
45+
elif response.status_code == 400:
46+
error = response.json().get("error", "")
47+
if error == "authorization_pending":
48+
print("Waiting for device to be authorized ...")
49+
time.sleep(interval)
50+
else:
51+
return None
52+
else:
53+
return None
54+
55+
56+
def device_login(discovery_doc, client_credentials):
57+
device_code_response = request_device_code(discovery_doc, client_credentials)
58+
if device_code_response:
59+
verification_uri_complete = device_code_response.get("verification_uri_complete", None)
60+
webbrowser.open(verification_uri_complete)
61+
if verification_uri_complete:
62+
print(
63+
f"The following URL has been opened in your browser: {verification_uri_complete}"
64+
)
65+
else:
66+
print(f"Something went wrong")
67+
68+
69+
interval = device_code_response["interval"]
70+
timeout = device_code_response["expires_in"]
71+
device_login = poll_for_access_token(
72+
discovery_doc,
73+
client_credentials,
74+
device_code_response["device_code"],
75+
interval,
76+
timeout,
77+
)
78+
if device_login:
79+
print("Device login successfull")
80+
return device_login
81+
else:
82+
print("Failed to obtain an device login")
83+
return None
84+
else:
85+
print("Failed to obtain device code")
86+
return None
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
from pprint import pprint
2+
3+
from helpers import (
4+
get_discovery_document,
5+
device_login,
6+
)
7+
8+
discovery_doc = get_discovery_document("https://auth.apex.esa.int/realms/apex/.well-known/openid-configuration")
9+
10+
client_credentials ={
11+
"client_id": "project-a-catalogue-dev-browser"
12+
}
13+
14+
response = device_login(discovery_doc, client_credentials)
15+
16+
print("\n\nScopes: %s" % response["scope"])
17+
18+
print("\naccess token ( Expires after %s seconds ):\n-------------------------------------------------------------------------------------------------------------------" % response["expires_in"])
19+
print(response["access_token"])
20+
print("-------------------------------------------------------------------------------------------------------------------")
21+
22+
print("\nRefresh token ( Expires after %s seconds ):\n-------------------------------------------------------------------------------------------------------------------" % response["refresh_expires_in"])
23+
print(response["refresh_token"])
24+
print("-------------------------------------------------------------------------------------------------------------------\n")

0 commit comments

Comments
 (0)