示例#1
0
 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)
示例#4
0
 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)
            )