def get_access_token(self, request, redirect=None): code = request.GET.get('code') request_url = self.code_base + "client_id={0}&redirect_uri={1}&client_secret={2}&code={3}".format( self.consumer_key, redirect, self.consumer_secret, code ) rcontent = urllib2.urlopen(request_url).read() params = rcontent.split('&') access_token = params[0].split('=')[1] # "expires" parameter is seconds from now. expires_in = timedelta(seconds=int(params[1].split('=')[1])) expires = localize_datetime(datetime.now() + expires_in) # Debug token to get user id, other metadata. app_token = self.consumer_key + "|" + self.consumer_secret request_url = self.dbg_base + "input_token={0}&access_token={1}".format( access_token, app_token ) response = urllib2.urlopen(request_url) # GET rdata = json.load(response)['data'] # Parse JSON response. user_id = rdata['user_id'] platform = SocialPlatform.objects.get(name='Facebook') ptoken = OAuthAccessToken( oauth_access_token=access_token, platform=platform, user_id=user_id, expires=expires ) ptoken.save() self.cleanup() return ptoken.id
def post(self, api_method, http_method='POST', expected_status=(200,), **extra_params): if not (api_method.startswith('http://') or api_method.startswith('https://')): api_method = '%s%s%s' % ( self.service_info['default_api_prefix'], api_method, self.service_info['default_api_suffix'] ) if self.token is None: self.token = OAuthAccessToken.get_by_key_name(self.get_cookie()) logging.info(self.get_signed_body( api_method, self.token, http_method, **extra_params )) fetch = urlfetch(url=api_method, payload=self.get_signed_body( api_method, self.token, http_method, **extra_params ), method=http_method) if fetch.status_code not in expected_status: raise ValueError( "Error calling... Got return status: %i [%r]" % (fetch.status_code, fetch.content) ) return decode_json(fetch.content)
def callback(self, return_to='/'): oauth_token = self.handler.request.get("oauth_token") if not oauth_token: return get_request_token() oauth_token = OAuthRequestToken.all().filter( 'oauth_token =', oauth_token).filter( 'service =', self.service).fetch(1)[0] token_info = self.get_data_from_signed_url( self.service_info['access_token_url'], oauth_token ) key_name = create_uuid() #logging.info('callback...') #logging.info('key: %s, service: %s', key_name, self.service) logging.info(token_info) logging.info(type(token_info)) self.token = OAuthAccessToken( key_name=key_name, service=self.service, **dict(token.split('=') for token in token_info.split('&')) ) if 'specifier_handler' in self.service_info: specifier = self.token.specifier = self.service_info['specifier_handler'](self) old = OAuthAccessToken.all().filter( 'specifier =', specifier).filter( 'service =', self.service) db.delete(old) logging.info(return_to) logging.info('specifier %s' % specifier) self.token.put() self.set_cookie(key_name) self.handler.redirect(return_to)
def get_access_url(self, callback): """ Generates an access URL to which the user should be redirected in order to authorize Dolon. Parameters ---------- callback : str Callback URL to which the user should be redirected after authorizing Dolon. That view will receive a verifier, which is then used to obtain an access token. Returns ------- redirect_url : str The URL to which the user should be redirected in order to authorize Dolon. ptoken.id : int ID of a :class:`.OAuthAccessToken` containing the original request token. """ redirect_url = self.auth.get_authorization_url() logger.debug('Redirect URL: {0}'.format(redirect_url)) # We must create an OAuthAccessToken here because we need the request # tokens used when the authorization URL was generated. platform = SocialPlatform.objects.get(name='Twitter') ptoken = OAuthAccessToken( oauth_token = self.auth.request_token.key, oauth_token_secret = self.auth.request_token.secret, platform=platform, ) ptoken.save() return redirect_url
class OAuthClient(object): __public__ = ('callback', 'cleanup', 'login', 'logout') def __init__(self, service, handler, oauth_callback=None, **request_params): self.service = service self.service_info = OAUTH_APP_SETTINGS[service] self.service_key = None self.handler = handler self.request_params = request_params self.oauth_callback = oauth_callback self.token = None # public methods def get(self, api_method, http_method='GET', expected_status=(200,), **extra_params): logging.info('API method: %s', api_method) if not (api_method.startswith('http://') or api_method.startswith('https://')): api_method = '%s%s%s' % ( self.service_info['default_api_prefix'], api_method, self.service_info['default_api_suffix'] ) if self.token is None: self.token = OAuthAccessToken.get_by_key_name(self.get_cookie()) fetch = urlfetch(self.get_signed_url( api_method, self.token, http_method, **extra_params )) if fetch.status_code not in expected_status: raise ValueError( "Error calling... Got return status: %i [%r]" % (fetch.status_code, fetch.content) ) return decode_json(fetch.content) def post(self, api_method, http_method='POST', expected_status=(200,), **extra_params): if not (api_method.startswith('http://') or api_method.startswith('https://')): api_method = '%s%s%s' % ( self.service_info['default_api_prefix'], api_method, self.service_info['default_api_suffix'] ) if self.token is None: self.token = OAuthAccessToken.get_by_key_name(self.get_cookie()) logging.info(self.get_signed_body( api_method, self.token, http_method, **extra_params )) fetch = urlfetch(url=api_method, payload=self.get_signed_body( api_method, self.token, http_method, **extra_params ), method=http_method) if fetch.status_code not in expected_status: raise ValueError( "Error calling... Got return status: %i [%r]" % (fetch.status_code, fetch.content) ) return decode_json(fetch.content) def login(self): proxy_id = self.get_cookie() if proxy_id: return "FOO%rFF" % proxy_id self.expire_cookie() return self.get_request_token() def logout(self, return_to='/'): self.expire_cookie() self.handler.redirect(self.handler.request.get("return_to", return_to)) # oauth workflow def get_request_token(self): token_info = self.get_data_from_signed_url( self.service_info['request_token_url'], **self.request_params ) logging.info('get_Request_token.......') logging.warning(token_info) logging.warning(self.service_info) logging.warning(self.request_params) token = OAuthRequestToken( service=self.service, **dict(token.split('=') for token in token_info.split('&')) ) token.put() if self.oauth_callback: oauth_callback = {'oauth_callback': self.oauth_callback} else: oauth_callback = {} self.handler.redirect(self.get_signed_url( self.service_info['user_auth_url'], token, **oauth_callback )) def callback(self, return_to='/'): oauth_token = self.handler.request.get("oauth_token") if not oauth_token: return get_request_token() oauth_token = OAuthRequestToken.all().filter( 'oauth_token =', oauth_token).filter( 'service =', self.service).fetch(1)[0] token_info = self.get_data_from_signed_url( self.service_info['access_token_url'], oauth_token ) key_name = create_uuid() #logging.info('callback...') #logging.info('key: %s, service: %s', key_name, self.service) logging.info(token_info) logging.info(type(token_info)) self.token = OAuthAccessToken( key_name=key_name, service=self.service, **dict(token.split('=') for token in token_info.split('&')) ) if 'specifier_handler' in self.service_info: specifier = self.token.specifier = self.service_info['specifier_handler'](self) old = OAuthAccessToken.all().filter( 'specifier =', specifier).filter( 'service =', self.service) db.delete(old) logging.info(return_to) logging.info('specifier %s' % specifier) self.token.put() self.set_cookie(key_name) self.handler.redirect(return_to) def cleanup(self): query = OAuthRequestToken.all().filter( 'created <', datetime.now() - EXPIRATION_WINDOW ) count = query.count(CLEANUP_BATCH_SIZE) db.delete(query.fetch(CLEANUP_BATCH_SIZE)) return "Cleaned %i entries" % count # request marshalling def get_data_from_signed_url(self, __url, __token=None, __meth='GET', **extra_params): return urlfetch(self.get_signed_url( __url, __token, __meth, **extra_params )).content def get_signed_url(self, __url, __token=None, __meth='GET',**extra_params): return '%s?%s'%(__url, self.get_signed_body(__url, __token, __meth, **extra_params)) def get_signed_body(self, __url, __token=None, __meth='GET',**extra_params): service_info = self.service_info kwargs = { 'oauth_consumer_key': service_info['consumer_key'], 'oauth_signature_method': 'HMAC-SHA1', 'oauth_version': '1.0', 'oauth_timestamp': int(time()), 'oauth_nonce': getrandbits(64), } kwargs.update(extra_params) if self.service_key is None: self.service_key = get_service_key(self.service) if __token is not None: kwargs['oauth_token'] = __token.oauth_token key = self.service_key + encode(__token.oauth_token_secret) else: key = self.service_key message = '&'.join(map(encode, [ __meth.upper(), __url, '&'.join( '%s=%s' % (encode(k), encode(kwargs[k])) for k in sorted(kwargs) ) ])) kwargs['oauth_signature'] = hmac( key, message, sha1 ).digest().encode('base64')[:-1] return urlencode(kwargs) # who stole the cookie from the cookie jar? def get_cookie(self): return self.handler.request.cookies.get( 'oauth.%s' % self.service, '' ) def set_cookie(self, value, path='/'): self.handler.response.headers.add_header( 'Set-Cookie', '%s=%s; path=%s; expires="Fri, 31-Dec-2021 23:59:59 GMT"' % ('oauth.%s' % self.service, value, path) ) def expire_cookie(self, path='/'): self.handler.response.headers.add_header( 'Set-Cookie', '%s=; path=%s; expires="Fri, 31-Dec-1999 23:59:59 GMT"' % ('oauth.%s' % self.service, path) )