Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Initial checkin of device oauth implementation.

  • Loading branch information...
commit 2118434613eca891b2eb8873158c4294d1a2506e 1 parent 91f65a0
@guyc authored
View
5 .gitignore
@@ -0,0 +1,5 @@
+tmp/
+*~
+\#*\#
+.#*
+*.pyc
View
0  README.md 100644 → 100755
File mode changed
View
0  __init__.py
No changes.
View
125 oauth.py
@@ -0,0 +1,125 @@
+# https://developers.google.com/accounts/docs/OAuth2ForDevices
+
+import sys
+import urllib
+import httplib
+import os.path
+import json
+import time
+import gdata.spreadsheet.service
+
+class OAuth:
+
+ def __init__(self, client_id, client_secret):
+ self.client_id = client_id
+ self.client_secret = client_secret
+ self.token = None
+ self.device_code = None
+ self.verfication_url = None
+ self.token_file = 'oauth_token.json'
+ self.scope = [
+ 'https://spreadsheets.google.com/feeds', # scope information for the Google Spreadsheets API
+ 'https://docs.google.com/feeds', # if an application needs to create spreadsheets, or otherwise manipulate their metadata,
+ ]
+ self.host = 'accounts.google.com'
+ self.conn = httplib.HTTPSConnection(self.host)
+ self.load_token()
+
+ def load_token(self):
+ token = None
+ if os.path.isfile(self.token_file):
+ f = open(self.token_file)
+ json_token = f.read()
+ self.token = json.loads(json_token)
+ f.close()
+
+ def save_token(self):
+ f = open(self.token_file, 'w')
+ f.write(json.dumps(self.token))
+ f.close()
+
+ def has_token(self):
+ return self.token != None
+
+ def get_user_code(self):
+ self.conn.request(
+ "POST",
+ "/o/oauth2/device/code",
+ urllib.urlencode({
+ 'client_id': self.client_id,
+ 'scope' : ' '.join(self.scope)
+ }),
+ {"Content-type": "application/x-www-form-urlencoded"}
+ )
+ response = self.conn.getresponse()
+ if (response.status == 200):
+ data = json.loads(response.read())
+ self.device_code = data['device_code']
+ self.user_code = data['user_code']
+ self.verification_url = data['verification_url']
+ self.retry_interval = data['interval']
+ else:
+ print response.status
+ print response.read()
+ sys.exit()
+ return self.user_code
+
+ def get_new_token(self):
+ # call get_device_code if not already set
+ if not self.user_code:
+ self.get_user_code()
+
+ while self.token == None:
+ self.conn.request(
+ "POST",
+ "/o/oauth2/token",
+ urllib.urlencode({
+ 'client_id' : self.client_id,
+ 'client_secret' : self.client_secret,
+ 'code' : self.device_code,
+ 'grant_type' : 'http://oauth.net/grant_type/device/1.0'
+ }),
+ {"Content-type": "application/x-www-form-urlencoded"}
+ )
+
+ response = self.conn.getresponse()
+ if (response.status == 200):
+ data = json.loads(response.read())
+ print data
+ if 'access_token' in data:
+ self.token = data
+ self.save_token()
+ else:
+ time.sleep(self.retry_interval + 2)
+
+ def refresh_token():
+ self.conn.request(
+ "POST"
+ "/o/auth2/token",
+ urllib.urlencode({
+ 'client_id' : self.client_id,
+ 'client_secret' : self.client_secret,
+ 'refresh_token' : self.token['refresh_token'],
+ 'grant_type' : 'refresh_token'
+ }),
+ {"Content-type": "application/x-www-form-urlencoded"}
+ )
+
+ response = self.conn.getresponse()
+ if (response.status == 200):
+ data = json.loads(response.read())
+ if 'access_token' in data:
+ self.token = data
+ # appears we do not get a NEW refresh token at this point
+ if not 'refresh_token' in token:
+ self.token['refresh_token'] = refresh_token
+ self.save_token()
+ return True
+ return False
+
+ def spreadsheet_service(self):
+ headers = {
+ "Authorization": "%s %s" % (self.token['token_type'], self.token['access_token'])
+ }
+ client = gdata.spreadsheet.service.SpreadsheetsService(additional_headers=headers)
+ return client
Please sign in to comment.
Something went wrong with that request. Please try again.