From: Josh Roesslein Date: Thu, 13 Aug 2009 04:06:52 +0000 (-0500) Subject: Merge upstream 1.0a patch into oauth module. X-Git-Url: https://vcs.fsf.org/?a=commitdiff_plain;h=c2c3d9973e028ff676447b0510c03c4bbc3746e9;p=tweepy.git Merge upstream 1.0a patch into oauth module. --- diff --git a/tweepy/auth.py b/tweepy/auth.py index 49826ee..59d502d 100644 --- a/tweepy/auth.py +++ b/tweepy/auth.py @@ -45,9 +45,8 @@ class OAuthHandler(AuthHandler): def _get_request_token(self): try: - request = oauth.OAuthRequest.from_consumer_and_token(self._consumer, http_url = self.REQUEST_TOKEN_URL) - if self.callback: - request.set_parameter('oauth_callback', self.callback) + request = oauth.OAuthRequest.from_consumer_and_token(self._consumer, + http_url = self.REQUEST_TOKEN_URL, callback=self.callback) request.sign_request(self._sigmethod, self._consumer, None) resp = urlopen(Request(self.REQUEST_TOKEN_URL, headers=request.to_header())) return oauth.OAuthToken.from_string(resp.read()) @@ -77,8 +76,7 @@ class OAuthHandler(AuthHandler): try: # build request request = oauth.OAuthRequest.from_consumer_and_token(self._consumer, - token=self.request_token, http_url=self.ACCESS_TOKEN_URL) - request.set_parameter('oauth_verifier', str(verifier)) + token=self.request_token, http_url=self.ACCESS_TOKEN_URL, verifier=str(verifier)) request.sign_request(self._sigmethod, self._consumer, self.request_token) # send request diff --git a/tweepy/oauth.py b/tweepy/oauth.py index 9a14d5f..3a42e20 100644 --- a/tweepy/oauth.py +++ b/tweepy/oauth.py @@ -64,6 +64,10 @@ def generate_nonce(length=8): """Generate pseudorandom number.""" return ''.join([str(random.randint(0, 9)) for i in range(length)]) +def generate_verifier(length=8): + """Generate pseudorandom number.""" + return ''.join([str(random.randint(0, 9)) for i in range(length)]) + class OAuthConsumer(object): """Consumer of OAuth authentication. @@ -79,7 +83,7 @@ class OAuthConsumer(object): self.key = key self.secret = secret - + class OAuthToken(object): """OAuthToken is a data type that represents an End User via either an access or request token. @@ -90,14 +94,45 @@ class OAuthToken(object): """ key = None secret = None + callback = None + callback_confirmed = None + verifier = None def __init__(self, key, secret): self.key = key self.secret = secret + def set_callback(self, callback): + self.callback = callback + self.callback_confirmed = 'true' + + def set_verifier(self, verifier=None): + if verifier is not None: + self.verifier = verifier + else: + self.verifier = generate_verifier() + + def get_callback_url(self): + if self.callback and self.verifier: + # Append the oauth_verifier. + parts = urlparse.urlparse(self.callback) + scheme, netloc, path, params, query, fragment = parts[:6] + if query: + query = '%s&oauth_verifier=%s' % (query, self.verifier) + else: + query = 'oauth_verifier=%s' % self.verifier + return urlparse.urlunparse((scheme, netloc, path, params, + query, fragment)) + return self.callback + def to_string(self): - return urllib.urlencode({'oauth_token': self.key, - 'oauth_token_secret': self.secret}) + data = { + 'oauth_token': self.key, + 'oauth_token_secret': self.secret, + } + if self.callback_confirmed is not None: + data['oauth_callback_confirmed'] = self.callback_confirmed + return urllib.urlencode(data) def from_string(s): """ Returns a token from something like: @@ -106,7 +141,12 @@ class OAuthToken(object): params = cgi.parse_qs(s, keep_blank_values=False) key = params['oauth_token'][0] secret = params['oauth_token_secret'][0] - return OAuthToken(key, secret) + token = OAuthToken(key, secret) + try: + token.callback_confirmed = params['oauth_callback_confirmed'][0] + except KeyError: + pass # 1.0, no callback confirmed. + return token from_string = staticmethod(from_string) def __str__(self): @@ -124,6 +164,7 @@ class OAuthRequest(object): - oauth_timestamp - oauth_nonce - oauth_version + - oauth_verifier ... any additional parameters, as defined by the Service Provider. """ parameters = None # OAuth parameters. @@ -258,7 +299,8 @@ class OAuthRequest(object): from_request = staticmethod(from_request) def from_consumer_and_token(oauth_consumer, token=None, - http_method=HTTP_METHOD, http_url=None, parameters=None): + callback=None, verifier=None, http_method=HTTP_METHOD, + http_url=None, parameters=None): if not parameters: parameters = {} @@ -274,6 +316,12 @@ class OAuthRequest(object): if token: parameters['oauth_token'] = token.key + parameters['oauth_callback'] = token.callback + # 1.0a support for verifier. + parameters['oauth_verifier'] = verifier + elif callback: + # 1.0a support for callback in the request token request. + parameters['oauth_callback'] = callback return OAuthRequest(http_method, http_url, parameters) from_consumer_and_token = staticmethod(from_consumer_and_token) @@ -348,9 +396,13 @@ class OAuthServer(object): # No token required for the initial token request. version = self._get_version(oauth_request) consumer = self._get_consumer(oauth_request) + try: + callback = self.get_callback(oauth_request) + except OAuthError: + callback = None # 1.0, no callback specified. self._check_signature(oauth_request, consumer, None) # Fetch a new token. - token = self.data_store.fetch_request_token(consumer) + token = self.data_store.fetch_request_token(consumer, callback) return token def fetch_access_token(self, oauth_request): @@ -359,10 +411,11 @@ class OAuthServer(object): """ version = self._get_version(oauth_request) consumer = self._get_consumer(oauth_request) + verifier = self._get_verifier(oauth_request) # Get the request token. token = self._get_token(oauth_request, 'request') self._check_signature(oauth_request, consumer, token) - new_token = self.data_store.fetch_access_token(consumer, token) + new_token = self.data_store.fetch_access_token(consumer, token, verifier) return new_token def verify_request(self, oauth_request): @@ -429,6 +482,9 @@ class OAuthServer(object): if not token: raise OAuthError('Invalid %s token: %s' % (token_type, token_field)) return token + + def _get_verifier(self, oauth_request): + return oauth_request.get_parameter('oauth_verifier') def _check_signature(self, oauth_request, consumer, token): timestamp, nonce = oauth_request._get_timestamp_nonce() @@ -509,11 +565,11 @@ class OAuthDataStore(object): """-> OAuthToken.""" raise NotImplementedError - def fetch_request_token(self, oauth_consumer): + def fetch_request_token(self, oauth_consumer, oauth_callback): """-> OAuthToken.""" raise NotImplementedError - def fetch_access_token(self, oauth_consumer, oauth_token): + def fetch_access_token(self, oauth_consumer, oauth_token, oauth_verifier): """-> OAuthToken.""" raise NotImplementedError