# 2013-03-06 johnpfeiffer
# http://oauth.net/code/ (python oauth v1 library as a reference)
# base_string http://googlecodesamples.com/oauth_playground/
# signature http://oauth.googlecode.com/svn/code/javascript/example/signature.html
class OAuth_Signature():
method = 'GET' # must be uppercase
base_url = 'https://www.google.com/accounts/OAuthGetRequestToken'
signature_method = 'HMAC-SHA1'
oauth_version = '1.0'
# SCOPE = 'https://www.google.com/calendar/feeds/'
consumer_secret = 'anonymous'
oauth_nonce = ''
oauth_timestamp = ''
base_string = ''
signature = ''
# TODO: xoauth_displayname parameter to improve google login prompt
def __init__( self , parameters ):
"""generalized method for signing an oauth request"""
self.oauth_nonce = self.generate_nonce( 16 )
self.oauth_timestamp = self.generate_timestamp()
self.parameters = parameters
unencoded_parameters = list()
unencoded_parameters.append( 'oauth_consumer_key=' + self.consumer_secret )
unencoded_parameters.append( 'oauth_nonce=' + self.oauth_nonce )
unencoded_parameters.append( 'oauth_signature_method=' + self.signature_method )
unencoded_parameters.append( 'oauth_timestamp=' + self.oauth_timestamp )
unencoded_parameters.append( 'oauth_version=' + self.oauth_version )
for key, value in parameters.iteritems():
unencoded_parameters.append( key + '=' + self.encoded( value ) ) # double encoding required?
unencoded_parameters_sorted = sorted( unencoded_parameters )
unencoded_parameters_sorted_string = '&'.join( unencoded_parameters_sorted )
encoded_parameters_string = self.encoded( unencoded_parameters_sorted_string )
self.base_string = self.method.upper() + '&' + self.encoded( self.base_url ) + '&' + encoded_parameters_string
self.signature = self.generate_signature()
def display_status( self ):
print 'consumer key: %s' % self.consumer_secret
print 'nonce: %s' % self.oauth_nonce
print 'signature_method: %s' % self.signature_method
print 'timestamp: %s' % self.oauth_timestamp
print 'base_string: %s' % self.base_string
print 'signature: %s' % self.signature
def generate_signature( self ):
import hmac
import hashlib
import base64
key = self.consumer_secret + '&'
hashed = hmac.new( key, self.base_string , hashlib.sha1 )
return str( base64.b64encode( hashed.digest() ) )
@staticmethod
def generate_nonce( nonce_length ):
import random
oauth_nonce = ''.join( [str( random.randint( 0, nonce_length ) ) for i in range( nonce_length )] )
return oauth_nonce
@staticmethod
def generate_timestamp():
import time
return str( int( time.time() ) )
@staticmethod
def encode_parameter( parameter_key , parameter_value ):
return OAuth_Signature.encoded( parameter_key + '=' + parameter_value + '&' )
@staticmethod
def encoded( s ):
import urllib
return urllib.quote( s, safe = '~' ) # Escape a URL including any /
"""
# The added ampersand is also encoded!
encoded_oauth_consumer_key_value_pair = encoded( 'oauth_consumer_key' + '=' + self.CONSUMER_SECRET + '&' )
encoded_oauth_nonce_key_value_pair = encoded( 'oauth_nonce' + '=' + self.oauth_nonce + '&' )
encoded_oauth_signature_method_key_value_pair = encoded( 'oauth_signature_method' + '=' + SIGNATURE_METHOD + '&' )
encoded_oauth_timestamp_key_value_pair = encoded( 'oauth_timestamp' + '=' + str( self.oauth_timestamp ) + '&' )
encoded_oauth_version_key_value_pair = encoded( 'oauth_version' + '=' + OAUTH_VERSION + '&' )
encoded_scope_key_value_pair = encoded( 'scope' + '=' + encoded( SCOPE ) )
# manually sorted alphabetically by key, this is essentially concatenating 3 parts: METHOD, URL, ENCODED_PARAMETERS
base_string = METHOD.upper() + '&' + encoded( BASE_URL ) + '&'
base_string = base_string + encoded_oauth_consumer_key_value_pair
base_string = base_string + encoded_oauth_nonce_key_value_pair
base_string = base_string + encoded_oauth_signature_method_key_value_pair
base_string = base_string + encoded_oauth_timestamp_key_value_pair
base_string = base_string + encoded_oauth_version_key_value_pair
base_string = base_string + encoded_scope_key_value_pair
print 'GOOD base_string: %s' % base_string
key = '%s&' % CONSUMER_SECRET
import hmac
import hashlib
import base64
hashed = hmac.new( key, base_string , hashlib.sha1 )
signature = base64.b64encode( hashed.digest() )
print 'GOOD SIGNATURE: %s' % signature
TARGET = BASE_URL + "?scope=" + encoded( SCOPE )
parameters_as_headers = dict()
authorization = dict()
authorization[ 'Authorization'] = 'OAuth realm="", oauth_nonce="%s", oauth_timestamp="%s", ' \
'oauth_consumer_key="%s", oauth_signature_method="%s", oauth_version="%s", oauth_signature="%s"' \
% ( oauth_nonce , oauth_timestamp , CONSUMER_SECRET , SIGNATURE_METHOD , OAUTH_VERSION , signature )
print 'AUTHORIZATION HEADERS: %s' % authorization
# http://docs.python-requests.org/en/latest/
import requests
http = requests.Session()
response = http.get( TARGET , headers = authorization )
# print response.headers
token_parameter = ''
token_secret_parameter = ''
if response.status_code != 200:
print '%s' % response.content
else:
token_and_secret = response.content
token_and_secret_list = token_and_secret.split( '&' )
token_parameter = token_and_secret_list[0]
token_secret_parameter = token_and_secret_list[-1]
print 'TOKEN PARAMETER = %s' % token_parameter
print 'SECRET PARAMETER = %s' % token_secret_parameter
# Authorization of the Token
# GET https://www.google.com/accounts/OAuthAuthorizeToken?oauth_token=ab3cd9j4ks73hf7g&hd=mycollege.edu&hl=en&btmpl=mobile
AUTHORIZATION_URL = 'https://www.google.com/accounts/OAuthAuthorizeToken'
#response = http.get( AUTHORIZATION_URL + '?' + token_parameter )
#print '%s' % response.content
import webbrowser
webbrowser.open( AUTHORIZATION_URL + '?' + token_parameter )
ACCESS_TOKEN_URL = 'https://www.google.com/accounts/OAuthGetAccessToken'
authorization_access = dict()
authorization_access[ 'Authorization'] = 'OAuth realm="", oauth_nonce="%s", oauth_timestamp="%s", '\
'oauth_consumer_key="%s", oauth_signature_method="%s", oauth_version="%s", oauth_signature="%s"'\
% ( oauth_nonce , oauth_timestamp , CONSUMER_SECRET , SIGNATURE_METHOD , OAUTH_VERSION , signature )
print 'AUTHORIZATION HEADERS: %s' % authorization
payload = { 'oauth_consumer_key': CONSUMER_SECRET , 'oauth_token' : }
http.get( ACCESS_TOKEN_URL , )
"""
def main():
SCOPE = 'https://www.google.com/calendar/feeds/'
parameters = { 'scope': SCOPE }
signature = OAuth_Signature( parameters )
signature.display_status()
if __name__ == '__main__':
main()
# 2013-05-17 alternate but similar to oauth digital signature system
import time
import hmac
import base64
import hashlib
def create_signature( method , path , timestamp, appSecret, queryParams=None ):
queryString = '' # Prepare Base String for Signature
if queryParams:
for key in sorted( queryParams.keys() ):
queryString += key.strip( )
queryString += ' '
queryString += queryParams[ key ]
queryString += ' '
base_string = method
base_string += ' '
base_string += path
base_string += ' '
base_string += queryString.strip()
base_string += ' '
base_string += str( timestamp )
hashed = hmac.new( appSecret , base_string , hashlib.sha1 )
expectedSignature = base64.b64encode( hashed.digest( ) )
return expectedSignature
def create_headers( method, path, timestamp, appKey, appSecret, queryParams=None ):
signature = create_signature( method, path, timestamp, appSecret, queryParams )
headers = { 'X-Signature': signature , 'X-Timestamp': str( timestamp ) , 'X-App-Key': appKey }
return headers
if __name__ == '__main__':
queryParams = { 'email': 'john@example.com', 'password': 'MyPassword' } # TODO: password in the header, not a param
method = 'POST'
timestamp = 1368825184 # int( time.time() )
appKey = 'yourKey'
appSecret = 'secret'
result = create_signature( method, '/rest/account/login', timestamp, appSecret ) # no params
print result
result = create_headers( method, '/rest/account/login', timestamp, appKey, appSecret, queryParams )
print result
result = create_signature( method, '/rest/account/login', timestamp, appSecret, queryParams )
print result