#!/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=(',', ': ') ) )