Skip to content

Instantly share code, notes, and snippets.

@therealcmj
Created May 9, 2024 19:31
Show Gist options
  • Select an option

  • Save therealcmj/04d1a9f1c7ed2fabf021f347d772e411 to your computer and use it in GitHub Desktop.

Select an option

Save therealcmj/04d1a9f1c7ed2fabf021f347d772e411 to your computer and use it in GitHub Desktop.
An example python script to use Device Code grant type with OCI IAM identity domains
#!/usr/bin/env python3
# these are all you need to change:
idcs_url = 'https://idcs-XXX.identity.oraclecloud.com'
oauth_clientID = 'YYY'
oauth_clientSecret = 'ZZZ'
# the rest of these variables can be left alone for now
user_agent = 'devicetest.py'
printRequests=True
printResponses=True
printResponsesPretty=True
sleepFor=1
# import urllib2
import urllib
import urllib.error
import urllib.request
import json
import time
def makeIDCSRequest( uri, postdata, ignore400=False ):
req = urllib.request.Request( idcs_url + uri)
req.add_header('User-Agent', user_agent)
req.add_header('Accept', "application/json")
if printRequests:
print("URL: %s" % req.get_full_url())
print ("Request payload:")
print (json.dumps( postdata,
sort_keys=True,
indent=4,
separators=(',', ': ')
))
try:
response = urllib.request.urlopen(req, data=urllib.parse.urlencode(postdata).encode('ascii'))
responseData = response.read()
responseDataDict = json.loads( responseData )
except urllib.error.HTTPError as e:
if ignore400 and ( e.code == 400):
responseData = e.read()
responseDataDict = json.loads( responseData )
else:
print ("Exception caught")
print ("Error code: %s" % e.code)
print ("Reason : %s" % e.reason)
print (e.read())
# raise the error again so we bomb out
raise e
if printResponses:
if printResponsesPretty:
print ("Response payload:")
print (json.dumps( responseDataDict,
sort_keys=True,
indent=4,
separators=(',', ': ')
)
)
else:
print (responseData)
return responseDataDict
postdata = {
"response_type": "device_code",
"scope": "openid offline_access",
"client_id": oauth_clientID
}
print ("Making initial OAuth call to acquire device code...")
responseDataDict = makeIDCSRequest( '/oauth2/v1/device', postdata );
# it's always good practice to check that you got back what you expected
if ( "device_code" not in responseDataDict ) or \
( "expires_in" not in responseDataDict ) or \
( "user_code" not in responseDataDict ) or \
( "verification_uri" not in responseDataDict ):
# it's generally bad form to raise an Exception as a plain old Exception
# but this is a (dumb) example app so I'm going to pretend it's OK
raise Exception("Missing data in response from IDCS")
# save the device code away in a local variable
device_code = responseDataDict["device_code"]
# tell the user to go to that URL
print ("")
print ("Open a browser, go to:")
print (responseDataDict["verification_uri"])
print ("and enter the code " + responseDataDict["user_code"])
# then poll
waiting = True
postdata = {
"grant_type": "urn:ietf:params:oauth:grant-type:device_code",
"client_id": oauth_clientID,
"device_code": device_code,
"client_secret" : oauth_clientSecret
}
# print json.dumps( postdata );
while waiting:
time.sleep(sleepFor)
responseDataDict = makeIDCSRequest( '/oauth2/v1/token', postdata, True );
if "error" in responseDataDict and \
responseDataDict["error"] == "authorization_pending":
print ("Waiting")
elif "access_token" in responseDataDict:
waiting = False
access_token = responseDataDict["access_token"]
print ("Acquired Access Token:")
print (access_token)
else:
print ("Unexpected return data:")
print (json.dumps( responseDataDict,
sort_keys=True,
indent=4,
separators=(',', ': ')
)
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment