From 3896f6bcab36ade5c92f8a4821dc898d770a5d12 Mon Sep 17 00:00:00 2001 From: Edward Hades Date: Thu, 10 Feb 2011 11:16:14 +0100 Subject: [PATCH 1/3] 2to3 --- example/appengine_oauth.py | 4 +- example/client.py | 64 +++++++++++----------- example/server.py | 16 +++--- oauth2/__init__.py | 78 +++++++++++++-------------- setup.py | 2 +- tests/test_oauth.py | 108 ++++++++++++++++++------------------- 6 files changed, 136 insertions(+), 136 deletions(-) diff --git a/example/appengine_oauth.py b/example/appengine_oauth.py index 814f9b6f..c14da764 100644 --- a/example/appengine_oauth.py +++ b/example/appengine_oauth.py @@ -86,7 +86,7 @@ def is_valid(self): request = self.get_oauth_request() client = self.get_client(request) params = self._server.verify_request(request, client, None) - except Exception, e: + except Exception as e: raise e return client @@ -95,7 +95,7 @@ class SampleHandler(OAuthHandler): def get(self): try: client = self.is_valid() - except Exception, e: + except Exception as e: self.error(500) self.response.out.write(e) diff --git a/example/client.py b/example/client.py index 34f7dcb9..a55bb4ac 100644 --- a/example/client.py +++ b/example/client.py @@ -26,7 +26,7 @@ or find one that works with your web framework. """ -import httplib +import http.client import time import oauth.oauth as oauth @@ -48,13 +48,13 @@ # example client using httplib with headers class SimpleOAuthClient(oauth.OAuthClient): - def __init__(self, server, port=httplib.HTTP_PORT, request_token_url='', access_token_url='', authorization_url=''): + def __init__(self, server, port=http.client.HTTP_PORT, request_token_url='', access_token_url='', authorization_url=''): self.server = server self.port = port self.request_token_url = request_token_url self.access_token_url = access_token_url self.authorization_url = authorization_url - self.connection = httplib.HTTPConnection("%s:%d" % (self.server, self.port)) + self.connection = http.client.HTTPConnection("%s:%d" % (self.server, self.port)) def fetch_request_token(self, oauth_request): # via headers @@ -88,7 +88,7 @@ def access_resource(self, oauth_request): def run_example(): # setup - print '** OAuth Python Library Example **' + print('** OAuth Python Library Example **') client = SimpleOAuthClient(SERVER, PORT, REQUEST_TOKEN_URL, ACCESS_TOKEN_URL, AUTHORIZATION_URL) consumer = oauth.OAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET) signature_method_plaintext = oauth.OAuthSignatureMethod_PLAINTEXT() @@ -96,70 +96,70 @@ def run_example(): pause() # get request token - print '* Obtain a request token ...' + print('* Obtain a request token ...') pause() oauth_request = oauth.OAuthRequest.from_consumer_and_token(consumer, callback=CALLBACK_URL, http_url=client.request_token_url) oauth_request.sign_request(signature_method_plaintext, consumer, None) - print 'REQUEST (via headers)' - print 'parameters: %s' % str(oauth_request.parameters) + print('REQUEST (via headers)') + print('parameters: %s' % str(oauth_request.parameters)) pause() token = client.fetch_request_token(oauth_request) - print 'GOT' - print 'key: %s' % str(token.key) - print 'secret: %s' % str(token.secret) - print 'callback confirmed? %s' % str(token.callback_confirmed) + print('GOT') + print('key: %s' % str(token.key)) + print('secret: %s' % str(token.secret)) + print('callback confirmed? %s' % str(token.callback_confirmed)) pause() - print '* Authorize the request token ...' + print('* Authorize the request token ...') pause() oauth_request = oauth.OAuthRequest.from_token_and_callback(token=token, http_url=client.authorization_url) - print 'REQUEST (via url query string)' - print 'parameters: %s' % str(oauth_request.parameters) + print('REQUEST (via url query string)') + print('parameters: %s' % str(oauth_request.parameters)) pause() # this will actually occur only on some callback response = client.authorize_token(oauth_request) - print 'GOT' - print response + print('GOT') + print(response) # sad way to get the verifier - import urlparse, cgi - query = urlparse.urlparse(response)[4] + import urllib.parse, cgi + query = urllib.parse.urlparse(response)[4] params = cgi.parse_qs(query, keep_blank_values=False) verifier = params['oauth_verifier'][0] - print 'verifier: %s' % verifier + print('verifier: %s' % verifier) pause() # get access token - print '* Obtain an access token ...' + print('* Obtain an access token ...') pause() oauth_request = oauth.OAuthRequest.from_consumer_and_token(consumer, token=token, verifier=verifier, http_url=client.access_token_url) oauth_request.sign_request(signature_method_plaintext, consumer, token) - print 'REQUEST (via headers)' - print 'parameters: %s' % str(oauth_request.parameters) + print('REQUEST (via headers)') + print('parameters: %s' % str(oauth_request.parameters)) pause() token = client.fetch_access_token(oauth_request) - print 'GOT' - print 'key: %s' % str(token.key) - print 'secret: %s' % str(token.secret) + print('GOT') + print('key: %s' % str(token.key)) + print('secret: %s' % str(token.secret)) pause() # access some protected resources - print '* Access protected resources ...' + print('* Access protected resources ...') pause() parameters = {'file': 'vacation.jpg', 'size': 'original'} # resource specific params oauth_request = oauth.OAuthRequest.from_consumer_and_token(consumer, token=token, http_method='POST', http_url=RESOURCE_URL, parameters=parameters) oauth_request.sign_request(signature_method_hmac_sha1, consumer, token) - print 'REQUEST (via post body)' - print 'parameters: %s' % str(oauth_request.parameters) + print('REQUEST (via post body)') + print('parameters: %s' % str(oauth_request.parameters)) pause() params = client.access_resource(oauth_request) - print 'GOT' - print 'non-oauth parameters: %s' % params + print('GOT') + print('non-oauth parameters: %s' % params) pause() def pause(): - print '' + print('') time.sleep(1) if __name__ == '__main__': run_example() - print 'Done.' \ No newline at end of file + print('Done.') \ No newline at end of file diff --git a/example/server.py b/example/server.py index 5986b0e2..c6bca64f 100644 --- a/example/server.py +++ b/example/server.py @@ -22,8 +22,8 @@ THE SOFTWARE. """ -from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer -import urllib +from http.server import BaseHTTPRequestHandler, HTTPServer +import urllib.request, urllib.parse, urllib.error import oauth.oauth as oauth @@ -101,7 +101,7 @@ def send_oauth_error(self, err=None): self.send_error(401, str(err.message)) # return the authenticate header header = oauth.build_authenticate_header(realm=REALM) - for k, v in header.iteritems(): + for k, v in header.items(): self.send_header(k, v) def do_GET(self): @@ -131,7 +131,7 @@ def do_GET(self): self.end_headers() # return the token self.wfile.write(token.to_string()) - except oauth.OAuthError, err: + except oauth.OAuthError as err: self.send_oauth_error(err) return @@ -148,7 +148,7 @@ def do_GET(self): self.end_headers() # return the callback url (to show server has it) self.wfile.write(token.get_callback_url()) - except oauth.OAuthError, err: + except oauth.OAuthError as err: self.send_oauth_error(err) return @@ -162,7 +162,7 @@ def do_GET(self): self.end_headers() # return the token self.wfile.write(token.to_string()) - except oauth.OAuthError, err: + except oauth.OAuthError as err: self.send_oauth_error(err) return @@ -176,7 +176,7 @@ def do_GET(self): self.end_headers() # return the extra parameters - just for something to return self.wfile.write(str(params)) - except oauth.OAuthError, err: + except oauth.OAuthError as err: self.send_oauth_error(err) return @@ -186,7 +186,7 @@ def do_POST(self): def main(): try: server = HTTPServer(('', 8080), RequestHandler) - print 'Test server running...' + print('Test server running...') server.serve_forever() except KeyboardInterrupt: server.socket.close() diff --git a/oauth2/__init__.py b/oauth2/__init__.py index e5bd03de..545995b6 100644 --- a/oauth2/__init__.py +++ b/oauth2/__init__.py @@ -23,16 +23,16 @@ """ import base64 -import urllib +import urllib.request, urllib.parse, urllib.error import time import random -import urlparse +import urllib.parse import hmac import binascii import httplib2 try: - from urlparse import parse_qs + from urllib.parse import parse_qs parse_qs # placate pyflakes except ImportError: # fall back for Python 2.5 @@ -45,7 +45,7 @@ # hashlib was added in Python 2.5 import sha -import _version +from . import _version __version__ = _version.__version__ @@ -87,7 +87,7 @@ def build_xoauth_string(url, consumer, token=None): request.sign_request(signing_method, consumer, token) params = [] - for k, v in sorted(request.iteritems()): + for k, v in sorted(request.items()): if v is not None: params.append('%s="%s"' % (k, escape(v))) @@ -97,12 +97,12 @@ def build_xoauth_string(url, consumer, token=None): def to_unicode(s): """ Convert to unicode, raise exception with instructive error message if s is not unicode, ascii, or utf-8. """ - if not isinstance(s, unicode): + if not isinstance(s, str): if not isinstance(s, str): raise TypeError('You are required to pass either unicode or string here, not: %r (%s)' % (type(s), s)) try: s = s.decode('utf-8') - except UnicodeDecodeError, le: + except UnicodeDecodeError as le: raise TypeError('You are required to pass either a unicode object or a utf-8 string here. You passed a Python string object which contained non-utf-8: %r. The UnicodeDecodeError that resulted from attempting to interpret it as utf-8 was: %s' % (s, le,)) return s @@ -110,13 +110,13 @@ def to_utf8(s): return to_unicode(s).encode('utf-8') def to_unicode_if_string(s): - if isinstance(s, basestring): + if isinstance(s, str): return to_unicode(s) else: return s def to_utf8_if_string(s): - if isinstance(s, basestring): + if isinstance(s, str): return to_utf8(s) else: return s @@ -126,12 +126,12 @@ def to_unicode_optional_iterator(x): Raise TypeError if x is a str containing non-utf8 bytes or if x is an iterable which contains such a str. """ - if isinstance(x, basestring): + if isinstance(x, str): return to_unicode(x) try: l = list(x) - except TypeError, e: + except TypeError as e: assert 'is not iterable' in str(e) return x else: @@ -140,7 +140,7 @@ def to_unicode_optional_iterator(x): def escape(s): """Escape a URL including any /.""" s = to_unicode(s) - return urllib.quote(s.encode('utf-8'), safe='~') + return urllib.parse.quote(s.encode('utf-8'), safe='~') def generate_timestamp(): """Get seconds since epoch (UTC).""" @@ -191,7 +191,7 @@ def __str__(self): data = {'oauth_consumer_key': self.key, 'oauth_consumer_secret': self.secret} - return urllib.urlencode(data) + return urllib.parse.urlencode(data) class Token(object): @@ -235,13 +235,13 @@ def set_verifier(self, verifier=None): def get_callback_url(self): if self.callback and self.verifier: # Append the oauth_verifier. - parts = urlparse.urlparse(self.callback) + parts = urllib.parse.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, + return urllib.parse.urlunparse((scheme, netloc, path, params, query, fragment)) return self.callback @@ -259,7 +259,7 @@ def to_string(self): if self.callback_confirmed is not None: data['oauth_callback_confirmed'] = self.callback_confirmed - return urllib.urlencode(data) + return urllib.parse.urlencode(data) @staticmethod def from_string(s): @@ -330,7 +330,7 @@ def __init__(self, method=HTTP_METHOD, url=None, parameters=None, self.url = to_unicode(url) self.method = method if parameters is not None: - for k, v in parameters.iteritems(): + for k, v in parameters.items(): k = to_unicode(k) v = to_unicode_optional_iterator(v) self[k] = v @@ -342,7 +342,7 @@ def __init__(self, method=HTTP_METHOD, url=None, parameters=None, def url(self, value): self.__dict__['url'] = value if value is not None: - scheme, netloc, path, params, query, fragment = urlparse.urlparse(value) + scheme, netloc, path, params, query, fragment = urllib.parse.urlparse(value) # Exclude default port numbers. if scheme == 'http' and netloc[-3:] == ':80': @@ -353,7 +353,7 @@ def url(self, value): raise ValueError("Unsupported URL %s (%s)." % (value, scheme)) # Normalized URL excludes params, query, and fragment. - self.normalized_url = urlparse.urlunparse((scheme, netloc, path, None, None, None)) + self.normalized_url = urllib.parse.urlunparse((scheme, netloc, path, None, None, None)) else: self.normalized_url = None self.__dict__['url'] = None @@ -367,12 +367,12 @@ def _get_timestamp_nonce(self): def get_nonoauth_parameters(self): """Get any non-OAuth parameters.""" - return dict([(k, v) for k, v in self.iteritems() + return dict([(k, v) for k, v in self.items() if not k.startswith('oauth_')]) def to_header(self, realm=''): """Serialize as a header for an HTTPAuth request.""" - oauth_params = ((k, v) for k, v in self.items() + oauth_params = ((k, v) for k, v in list(self.items()) if k.startswith('oauth_')) stringy_params = ((k, escape(str(v))) for k, v in oauth_params) header_params = ('%s="%s"' % (k, v) for k, v in stringy_params) @@ -389,18 +389,18 @@ def to_postdata(self): # tell urlencode to deal with sequence values and map them correctly # to resulting querystring. for example self["k"] = ["v1", "v2"] will # result in 'k=v1&k=v2' and not k=%5B%27v1%27%2C+%27v2%27%5D - return urllib.urlencode(self, True).replace('+', '%20') + return urllib.parse.urlencode(self, True).replace('+', '%20') def to_url(self): """Serialize as a URL for a GET request.""" - base_url = urlparse.urlparse(self.url) + base_url = urllib.parse.urlparse(self.url) try: query = base_url.query except AttributeError: # must be python <2.5 query = base_url[4] query = parse_qs(query) - for k, v in self.items(): + for k, v in list(self.items()): query.setdefault(k, []).append(v) try: @@ -418,8 +418,8 @@ def to_url(self): fragment = base_url[5] url = (scheme, netloc, path, params, - urllib.urlencode(query, True), fragment) - return urlparse.urlunparse(url) + urllib.parse.urlencode(query, True), fragment) + return urllib.parse.urlunparse(url) def get_parameter(self, parameter): ret = self.get(parameter) @@ -431,31 +431,31 @@ def get_parameter(self, parameter): def get_normalized_parameters(self): """Return a string that contains the parameters that must be signed.""" items = [] - for key, value in self.iteritems(): + for key, value in self.items(): if key == 'oauth_signature': continue # 1.0a/9.1.1 states that kvp must be sorted by key, then by value, # so we unpack sequence values into multiple items for sorting. - if isinstance(value, basestring): + if isinstance(value, str): items.append((to_utf8_if_string(key), to_utf8(value))) else: try: value = list(value) - except TypeError, e: + except TypeError as e: assert 'is not iterable' in str(e) items.append((to_utf8_if_string(key), to_utf8_if_string(value))) else: items.extend((to_utf8_if_string(key), to_utf8_if_string(item)) for item in value) # Include any query string parameters from the provided URL - query = urlparse.urlparse(self.url)[4] + query = urllib.parse.urlparse(self.url)[4] - url_items = self._split_url_string(query).items() + url_items = list(self._split_url_string(query).items()) url_items = [(to_utf8(k), to_utf8(v)) for k, v in url_items if k != 'oauth_signature' ] items.extend(url_items) items.sort() - encoded_str = urllib.urlencode(items) + encoded_str = urllib.parse.urlencode(items) # Encode signature parameters per Oauth Core 1.0 protocol # spec draft 7, section 3.6 # (http://tools.ietf.org/html/draft-hammer-oauth-07#section-3.6) @@ -519,7 +519,7 @@ def from_request(cls, http_method, http_url, headers=None, parameters=None, parameters.update(query_params) # URL parameters. - param_str = urlparse.urlparse(http_url)[4] # query + param_str = urllib.parse.urlparse(http_url)[4] # query url_params = cls._split_url_string(param_str) parameters.update(url_params) @@ -581,15 +581,15 @@ def _split_header(header): # Split key-value. param_parts = param.split('=', 1) # Remove quotes and unescape the value. - params[param_parts[0]] = urllib.unquote(param_parts[1].strip('\"')) + params[param_parts[0]] = urllib.parse.unquote(param_parts[1].strip('\"')) return params @staticmethod def _split_url_string(param_str): """Turn URL string into parameters.""" parameters = parse_qs(param_str.encode('utf-8'), keep_blank_values=True) - for k, v in parameters.iteritems(): - parameters[k] = urllib.unquote(v[0]) + for k, v in parameters.items(): + parameters[k] = urllib.parse.unquote(v[0]) return parameters @@ -642,12 +642,12 @@ def request(self, uri, method="GET", body='', headers=None, req.sign_request(self.method, self.consumer, self.token) - schema, rest = urllib.splittype(uri) + schema, rest = urllib.parse.splittype(uri) if rest.startswith('//'): hierpart = '//' else: hierpart = '' - host, rest = urllib.splithost(rest) + host, rest = urllib.parse.splithost(rest) realm = schema + ':' + hierpart + host @@ -721,7 +721,7 @@ def _get_signature_method(self, request): # Get the signature method object. signature_method = self.signature_methods[signature_method] except: - signature_method_names = ', '.join(self.signature_methods.keys()) + signature_method_names = ', '.join(list(self.signature_methods.keys())) raise Error('Signature method %s not supported try one of the following: %s' % (signature_method, signature_method_names)) return signature_method diff --git a/setup.py b/setup.py index acc41e17..234e9533 100755 --- a/setup.py +++ b/setup.py @@ -15,7 +15,7 @@ if mo: mverstr = mo.group(1) else: - print "unable to find version in %s" % (VERSIONFILE,) + print("unable to find version in %s" % (VERSIONFILE,)) raise RuntimeError("if %s.py exists, it must be well-formed" % (VERSIONFILE,)) AVSRE = r"^auto_build_num *= *['\"]([^'\"]*)['\"]" mo = re.search(AVSRE, verstrline, re.M) diff --git a/tests/test_oauth.py b/tests/test_oauth.py index f95d59d5..8e8f9533 100644 --- a/tests/test_oauth.py +++ b/tests/test_oauth.py @@ -29,15 +29,15 @@ import oauth2 as oauth import random import time -import urllib -import urlparse +import urllib.request, urllib.parse, urllib.error +import urllib.parse from types import ListType import mock import httplib2 # Fix for python2.5 compatibility try: - from urlparse import parse_qs, parse_qsl + from urllib.parse import parse_qs, parse_qsl except ImportError: from cgi import parse_qs, parse_qsl @@ -49,19 +49,19 @@ class TestError(unittest.TestCase): def test_message(self): try: raise oauth.Error - except oauth.Error, e: + except oauth.Error as e: self.assertEqual(e.message, 'OAuth error occurred.') msg = 'OMG THINGS BROKE!!!!' try: raise oauth.Error(msg) - except oauth.Error, e: + except oauth.Error as e: self.assertEqual(e.message, msg) def test_str(self): try: raise oauth.Error - except oauth.Error, e: + except oauth.Error as e: self.assertEquals(str(e), 'OAuth error occurred.') class TestGenerateFunctions(unittest.TestCase): @@ -261,11 +261,11 @@ def test_to_unicode(self): self.failUnlessRaises(TypeError, oauth.to_unicode_optional_iterator, '\xae') self.failUnlessRaises(TypeError, oauth.to_unicode_optional_iterator, ['\xae']) - self.failUnlessEqual(oauth.to_unicode(':-)'), u':-)') - self.failUnlessEqual(oauth.to_unicode(u'\u00ae'), u'\u00ae') - self.failUnlessEqual(oauth.to_unicode('\xc2\xae'), u'\u00ae') - self.failUnlessEqual(oauth.to_unicode_optional_iterator([':-)']), [u':-)']) - self.failUnlessEqual(oauth.to_unicode_optional_iterator([u'\u00ae']), [u'\u00ae']) + self.failUnlessEqual(oauth.to_unicode(':-)'), ':-)') + self.failUnlessEqual(oauth.to_unicode('\u00ae'), '\u00ae') + self.failUnlessEqual(oauth.to_unicode('\xc2\xae'), '\u00ae') + self.failUnlessEqual(oauth.to_unicode_optional_iterator([':-)']), [':-)']) + self.failUnlessEqual(oauth.to_unicode_optional_iterator(['\u00ae']), ['\u00ae']) class TestRequest(unittest.TestCase, ReallyEqualMixin): def test_setter(self): @@ -286,7 +286,7 @@ def test_deleter(self): self.fail("AttributeError should have been raised on empty url.") except AttributeError: pass - except Exception, e: + except Exception as e: self.fail(str(e)) def test_url(self): @@ -338,7 +338,7 @@ def test_no_url_set(self): def test_url_query(self): url = "https://www.google.com/m8/feeds/contacts/default/full/?alt=json&max-contacts=10" - normalized_url = urlparse.urlunparse(urlparse.urlparse(url)[:3] + (None, None, None)) + normalized_url = urllib.parse.urlunparse(urllib.parse.urlparse(url)[:3] + (None, None, None)) method = "GET" req = oauth.Request(method, url) @@ -361,12 +361,12 @@ def test_get_nonoauth_parameters(self): } other_params = { - u'foo': u'baz', - u'bar': u'foo', - u'multi': [u'FOO',u'BAR'], - u'uni_utf8': u'\xae', - u'uni_unicode': u'\u00ae', - u'uni_unicode_2': u'åÅøØ', + 'foo': 'baz', + 'bar': 'foo', + 'multi': ['FOO','BAR'], + 'uni_utf8': '\xae', + 'uni_unicode': '\u00ae', + 'uni_unicode_2': 'åÅøØ', } params = oauth_params @@ -389,7 +389,7 @@ def test_to_header(self): } req = oauth.Request("GET", realm, params) - header, value = req.to_header(realm).items()[0] + header, value = list(req.to_header(realm).items())[0] parts = value.split('OAuth ') vars = parts[1].split(', ') @@ -398,14 +398,14 @@ def test_to_header(self): res = {} for v in vars: var, val = v.split('=') - res[var] = urllib.unquote(val.strip('"')) + res[var] = urllib.parse.unquote(val.strip('"')) self.assertEquals(realm, res['realm']) del res['realm'] self.assertTrue(len(res), len(params)) - for key, val in res.items(): + for key, val in list(res.items()): self.assertEquals(val, params.get(key)) def test_to_postdata(self): @@ -426,7 +426,7 @@ def test_to_postdata(self): flat = [('multi','FOO'),('multi','BAR')] del params['multi'] - flat.extend(params.items()) + flat.extend(list(params.items())) kf = lambda x: x[0] self.assertEquals(sorted(flat, key=kf), sorted(parse_qsl(req.to_postdata()), key=kf)) @@ -444,8 +444,8 @@ def test_to_url(self): } req = oauth.Request("GET", url, params) - exp = urlparse.urlparse("%s?%s" % (url, urllib.urlencode(params))) - res = urlparse.urlparse(req.to_url()) + exp = urllib.parse.urlparse("%s?%s" % (url, urllib.parse.urlencode(params))) + res = urllib.parse.urlparse(req.to_url()) self.assertEquals(exp.scheme, res.scheme) self.assertEquals(exp.netloc, res.netloc) self.assertEquals(exp.path, res.path) @@ -469,8 +469,8 @@ def test_to_url_with_query(self): req = oauth.Request("GET", url, params) # Note: the url above already has query parameters, so append new ones with & - exp = urlparse.urlparse("%s&%s" % (url, urllib.urlencode(params))) - res = urlparse.urlparse(req.to_url()) + exp = urllib.parse.urlparse("%s&%s" % (url, urllib.parse.urlencode(params))) + res = urllib.parse.urlparse(req.to_url()) self.assertEquals(exp.scheme, res.scheme) self.assertEquals(exp.netloc, res.netloc) self.assertEquals(exp.path, res.path) @@ -486,27 +486,27 @@ def test_to_url_with_query(self): def test_signature_base_string_nonascii_nonutf8(self): consumer = oauth.Consumer('consumer_token', 'consumer_secret') - url = u'http://api.simplegeo.com:80/1.0/places/address.json?q=monkeys&category=animal&address=41+Decatur+St,+San+Francisc\u2766,+CA' + url = 'http://api.simplegeo.com:80/1.0/places/address.json?q=monkeys&category=animal&address=41+Decatur+St,+San+Francisc\u2766,+CA' req = oauth.Request("GET", url) - self.failUnlessReallyEqual(req.normalized_url, u'http://api.simplegeo.com/1.0/places/address.json') + self.failUnlessReallyEqual(req.normalized_url, 'http://api.simplegeo.com/1.0/places/address.json') req.sign_request(oauth.SignatureMethod_HMAC_SHA1(), consumer, None) self.failUnlessReallyEqual(req['oauth_signature'], 'WhufgeZKyYpKsI70GZaiDaYwl6g=') url = 'http://api.simplegeo.com:80/1.0/places/address.json?q=monkeys&category=animal&address=41+Decatur+St,+San+Francisc\xe2\x9d\xa6,+CA' req = oauth.Request("GET", url) - self.failUnlessReallyEqual(req.normalized_url, u'http://api.simplegeo.com/1.0/places/address.json') + self.failUnlessReallyEqual(req.normalized_url, 'http://api.simplegeo.com/1.0/places/address.json') req.sign_request(oauth.SignatureMethod_HMAC_SHA1(), consumer, None) self.failUnlessReallyEqual(req['oauth_signature'], 'WhufgeZKyYpKsI70GZaiDaYwl6g=') url = 'http://api.simplegeo.com:80/1.0/places/address.json?q=monkeys&category=animal&address=41+Decatur+St,+San+Francisc%E2%9D%A6,+CA' req = oauth.Request("GET", url) - self.failUnlessReallyEqual(req.normalized_url, u'http://api.simplegeo.com/1.0/places/address.json') + self.failUnlessReallyEqual(req.normalized_url, 'http://api.simplegeo.com/1.0/places/address.json') req.sign_request(oauth.SignatureMethod_HMAC_SHA1(), consumer, None) self.failUnlessReallyEqual(req['oauth_signature'], 'WhufgeZKyYpKsI70GZaiDaYwl6g=') - url = u'http://api.simplegeo.com:80/1.0/places/address.json?q=monkeys&category=animal&address=41+Decatur+St,+San+Francisc%E2%9D%A6,+CA' + url = 'http://api.simplegeo.com:80/1.0/places/address.json?q=monkeys&category=animal&address=41+Decatur+St,+San+Francisc%E2%9D%A6,+CA' req = oauth.Request("GET", url) - self.failUnlessReallyEqual(req.normalized_url, u'http://api.simplegeo.com/1.0/places/address.json') + self.failUnlessReallyEqual(req.normalized_url, 'http://api.simplegeo.com/1.0/places/address.json') req.sign_request(oauth.SignatureMethod_HMAC_SHA1(), consumer, None) self.failUnlessReallyEqual(req['oauth_signature'], 'WhufgeZKyYpKsI70GZaiDaYwl6g=') @@ -527,7 +527,7 @@ def test_signature_base_string_with_query(self): normalized_params = parse_qsl(req.get_normalized_parameters()) self.assertTrue(len(normalized_params), len(params) + 2) normalized_params = dict(normalized_params) - for key, value in params.iteritems(): + for key, value in params.items(): if key == 'oauth_signature': continue self.assertEquals(value, normalized_params[key]) @@ -598,10 +598,10 @@ def test_get_normalized_parameters(self): 'oauth_consumer_key': "0685bd9184jfhq22", 'oauth_signature_method': "HMAC-SHA1", 'oauth_token': "ad180jjd733klru7", - 'multi': ['FOO','BAR', u'\u00ae', '\xc2\xae'], + 'multi': ['FOO','BAR', '\u00ae', '\xc2\xae'], 'multi_same': ['FOO','FOO'], 'uni_utf8_bytes': '\xc2\xae', - 'uni_unicode_object': u'\u00ae' + 'uni_unicode_object': '\u00ae' } req = oauth.Request("GET", url, params) @@ -629,11 +629,11 @@ def test_get_normalized_parameters_ignores_auth_signature(self): res = req.get_normalized_parameters() - self.assertNotEquals(urllib.urlencode(sorted(params.items())), res) + self.assertNotEquals(urllib.parse.urlencode(sorted(params.items())), res) foo = params.copy() del foo["oauth_signature"] - self.assertEqual(urllib.urlencode(sorted(foo.items())), res) + self.assertEqual(urllib.parse.urlencode(sorted(foo.items())), res) def test_set_signature_method(self): consumer = oauth.Consumer('key', 'secret') @@ -661,7 +661,7 @@ def test_get_normalized_string_escapes_spaces_properly(self): req = oauth.Request("GET", url, params) res = req.get_normalized_parameters() - expected = urllib.urlencode(sorted(params.items())).replace('+', '%20') + expected = urllib.parse.urlencode(sorted(params.items())).replace('+', '%20') self.assertEqual(expected, res) @mock.patch('oauth2.Request.make_timestamp') @@ -686,7 +686,7 @@ def test_request_nonutf8_bytes(self, mock_make_nonce, mock_make_timestamp): self.assertRaises(TypeError, oauth.Request, method="GET", url=url, parameters=params) # And if they pass an unicode, then we'll use it. - url = u'http://sp.example.com/\u2019' + url = 'http://sp.example.com/\u2019' req = oauth.Request(method="GET", url=url, parameters=params) req.sign_request(oauth.SignatureMethod_HMAC_SHA1(), con, None) self.failUnlessReallyEqual(req['oauth_signature'], 'cMzvCkhvLL57+sTIxLITTHfkqZk=') @@ -707,7 +707,7 @@ def test_request_nonutf8_bytes(self, mock_make_nonce, mock_make_timestamp): self.assertRaises(TypeError, oauth.Request, method="GET", url=url, parameters=params) # And if they pass a unicode, then we'll use it. - params['non_oauth_thing'] = u'\u2019' + params['non_oauth_thing'] = '\u2019' req = oauth.Request(method="GET", url=url, parameters=params) req.sign_request(oauth.SignatureMethod_HMAC_SHA1(), con, None) self.failUnlessReallyEqual(req['oauth_signature'], '0GU50m0v60CVDB5JnoBXnvvvKx4=') @@ -740,7 +740,7 @@ def test_request_hash_of_body(self): 'oauth_consumer_key': con.key } - url = u"http://www.example.com/resource" + url = "http://www.example.com/resource" req = oauth.Request(method="PUT", url=url, parameters=params, body="Hello World!", is_form_encoded=False) req.sign_request(oauth.SignatureMethod_HMAC_SHA1(), con, None) self.failUnlessReallyEqual(req['oauth_body_hash'], 'Lve95gjOVATpfV8EL5X4nxwjKHE=') @@ -799,7 +799,7 @@ def test_sign_request(self): 'con-test-secret&tok-test-secret': oauth.SignatureMethod_PLAINTEXT() } - for exp, method in methods.items(): + for exp, method in list(methods.items()): req.sign_request(method, con, tok) self.assertEquals(req['oauth_signature_method'], method.name) self.assertEquals(req['oauth_signature'], exp) @@ -810,7 +810,7 @@ def test_sign_request(self): req.sign_request(oauth.SignatureMethod_HMAC_SHA1(), con, tok) self.assertEquals(req['oauth_signature'], 'loFvp5xC7YbOgd9exIO6TxB7H4s=') - url = u'http://sp.example.com/\u2019' # Python unicode object + url = 'http://sp.example.com/\u2019' # Python unicode object req = oauth.Request(method="GET", url=url, parameters=params) req.sign_request(oauth.SignatureMethod_HMAC_SHA1(), con, tok) self.assertEquals(req['oauth_signature'], 'loFvp5xC7YbOgd9exIO6TxB7H4s=') @@ -821,7 +821,7 @@ def test_sign_request(self): req.sign_request(oauth.SignatureMethod_HMAC_SHA1(), con, tok) self.assertEquals(req['oauth_signature'], 'IBw5mfvoCsDjgpcsVKbyvsDqQaU=') - url = u'http://sp.example.com/?q=\u2019' # Python unicode object + url = 'http://sp.example.com/?q=\u2019' # Python unicode object req = oauth.Request(method="GET", url=url, parameters=params) req.sign_request(oauth.SignatureMethod_HMAC_SHA1(), con, tok) self.assertEquals(req['oauth_signature'], 'IBw5mfvoCsDjgpcsVKbyvsDqQaU=') @@ -858,12 +858,12 @@ def test_from_request(self): url, bad_headers) # Test getting from query string - qs = urllib.urlencode(params) + qs = urllib.parse.urlencode(params) req = oauth.Request.from_request("GET", url, query_string=qs) exp = parse_qs(qs, keep_blank_values=False) - for k, v in exp.iteritems(): - exp[k] = urllib.unquote(v[0]) + for k, v in exp.items(): + exp[k] = urllib.parse.unquote(v[0]) self.assertEquals(exp, req.copy()) @@ -1147,7 +1147,7 @@ def create_simple_multipart_data(self, data): boundary = '---Boundary-%d' % random.randint(1,1000) crlf = '\r\n' items = [] - for key, value in data.iteritems(): + for key, value in data.items(): items += [ '--'+boundary, 'Content-Disposition: form-data; name="%s"'%str(key), @@ -1197,7 +1197,7 @@ def _two_legged(self, method): client = oauth.Client(self.consumer, None) return client.request(self._uri('two_legged'), method, - body=urllib.urlencode(self.body)) + body=urllib.parse.urlencode(self.body)) def test_two_legged_post(self): """A test of a two-legged OAuth POST request.""" @@ -1225,7 +1225,7 @@ def test_multipart_post_does_not_alter_body(self, mockHttpRequest): def mockrequest(cl, ur, **kw): self.failUnless(cl is client) self.failUnless(ur is uri) - self.failUnlessEqual(frozenset(kw.keys()), frozenset(['method', 'body', 'redirections', 'connection_type', 'headers'])) + self.failUnlessEqual(frozenset(list(kw.keys())), frozenset(['method', 'body', 'redirections', 'connection_type', 'headers'])) self.failUnlessEqual(kw['body'], body) self.failUnlessEqual(kw['connection_type'], None) self.failUnlessEqual(kw['method'], 'POST') @@ -1247,7 +1247,7 @@ def test_url_with_query_string(self, mockHttpRequest): def mockrequest(cl, ur, **kw): self.failUnless(cl is client) - self.failUnlessEqual(frozenset(kw.keys()), frozenset(['method', 'body', 'redirections', 'connection_type', 'headers'])) + self.failUnlessEqual(frozenset(list(kw.keys())), frozenset(['method', 'body', 'redirections', 'connection_type', 'headers'])) self.failUnlessEqual(kw['body'], '') self.failUnlessEqual(kw['connection_type'], None) self.failUnlessEqual(kw['method'], 'GET') @@ -1257,8 +1257,8 @@ def mockrequest(cl, ur, **kw): req = oauth.Request.from_consumer_and_token(self.consumer, None, http_method='GET', http_url=uri, parameters={}) req.sign_request(oauth.SignatureMethod_HMAC_SHA1(), self.consumer, None) - expected = parse_qsl(urlparse.urlparse(req.to_url()).query) - actual = parse_qsl(urlparse.urlparse(ur).query) + expected = parse_qsl(urllib.parse.urlparse(req.to_url()).query) + actual = parse_qsl(urllib.parse.urlparse(ur).query) self.failUnlessEqual(len(expected), len(actual)) actual = dict(actual) for key, value in expected: From b1c0d46c80aecab77efa52982fbded77f17a7ad9 Mon Sep 17 00:00:00 2001 From: Edward Hades Date: Thu, 10 Feb 2011 13:27:43 +0100 Subject: [PATCH 2/3] All tests now pass. --- oauth2/__init__.py | 17 +++++------ tests/test_oauth.py | 71 ++++++++++++++++++++++----------------------- 2 files changed, 43 insertions(+), 45 deletions(-) diff --git a/oauth2/__init__.py b/oauth2/__init__.py index 545995b6..66f25d0b 100644 --- a/oauth2/__init__.py +++ b/oauth2/__init__.py @@ -26,7 +26,6 @@ import urllib.request, urllib.parse, urllib.error import time import random -import urllib.parse import hmac import binascii import httplib2 @@ -98,7 +97,7 @@ def to_unicode(s): """ Convert to unicode, raise exception with instructive error message if s is not unicode, ascii, or utf-8. """ if not isinstance(s, str): - if not isinstance(s, str): + if not isinstance(s, bytes): raise TypeError('You are required to pass either unicode or string here, not: %r (%s)' % (type(s), s)) try: s = s.decode('utf-8') @@ -110,13 +109,13 @@ def to_utf8(s): return to_unicode(s).encode('utf-8') def to_unicode_if_string(s): - if isinstance(s, str): + if isinstance(s, str) or isinstance(s, bytes): return to_unicode(s) else: return s def to_utf8_if_string(s): - if isinstance(s, str): + if isinstance(s, str) or isinstance(s, bytes): return to_utf8(s) else: return s @@ -126,7 +125,7 @@ def to_unicode_optional_iterator(x): Raise TypeError if x is a str containing non-utf8 bytes or if x is an iterable which contains such a str. """ - if isinstance(x, str): + if isinstance(x, str) or isinstance(x, bytes): return to_unicode(x) try: @@ -436,7 +435,7 @@ def get_normalized_parameters(self): continue # 1.0a/9.1.1 states that kvp must be sorted by key, then by value, # so we unpack sequence values into multiple items for sorting. - if isinstance(value, str): + if isinstance(value, str) or isinstance(value, bytes): items.append((to_utf8_if_string(key), to_utf8(value))) else: try: @@ -471,7 +470,7 @@ def sign_request(self, signature_method, consumer, token): # section 4.1.1 "OAuth Consumers MUST NOT include an # oauth_body_hash parameter on requests with form-encoded # request bodies." - self['oauth_body_hash'] = base64.b64encode(sha(self.body).digest()) + self['oauth_body_hash'] = base64.b64encode(sha(self.body.encode('utf8')).digest()) if 'oauth_consumer_key' not in self: self['oauth_consumer_key'] = consumer.key @@ -587,7 +586,7 @@ def _split_header(header): @staticmethod def _split_url_string(param_str): """Turn URL string into parameters.""" - parameters = parse_qs(param_str.encode('utf-8'), keep_blank_values=True) + parameters = parse_qs(param_str, keep_blank_values=True) for k, v in parameters.items(): parameters[k] = urllib.parse.unquote(v[0]) return parameters @@ -818,7 +817,7 @@ def sign(self, request, consumer, token): """Builds the base signature string.""" key, raw = self.signing_base(request, consumer, token) - hashed = hmac.new(key, raw, sha) + hashed = hmac.new(key.encode('utf-8'), raw.encode('utf-8'), sha) # Calculate the digest base 64. return binascii.b2a_base64(hashed.digest())[:-1] diff --git a/tests/test_oauth.py b/tests/test_oauth.py index 8e8f9533..642c294f 100644 --- a/tests/test_oauth.py +++ b/tests/test_oauth.py @@ -31,7 +31,6 @@ import time import urllib.request, urllib.parse, urllib.error import urllib.parse -from types import ListType import mock import httplib2 @@ -257,14 +256,14 @@ def failUnlessReallyEqual(self, a, b, msg=None): class TestFuncs(unittest.TestCase): def test_to_unicode(self): - self.failUnlessRaises(TypeError, oauth.to_unicode, '\xae') - self.failUnlessRaises(TypeError, oauth.to_unicode_optional_iterator, '\xae') - self.failUnlessRaises(TypeError, oauth.to_unicode_optional_iterator, ['\xae']) + self.failUnlessRaises(TypeError, oauth.to_unicode, b'\xae') + self.failUnlessRaises(TypeError, oauth.to_unicode_optional_iterator, b'\xae') + self.failUnlessRaises(TypeError, oauth.to_unicode_optional_iterator, [b'\xae']) - self.failUnlessEqual(oauth.to_unicode(':-)'), ':-)') + self.failUnlessEqual(oauth.to_unicode(b':-)'), ':-)') self.failUnlessEqual(oauth.to_unicode('\u00ae'), '\u00ae') - self.failUnlessEqual(oauth.to_unicode('\xc2\xae'), '\u00ae') - self.failUnlessEqual(oauth.to_unicode_optional_iterator([':-)']), [':-)']) + self.failUnlessEqual(oauth.to_unicode(b'\xc2\xae'), '\u00ae') + self.failUnlessEqual(oauth.to_unicode_optional_iterator([b':-)']), [':-)']) self.failUnlessEqual(oauth.to_unicode_optional_iterator(['\u00ae']), ['\u00ae']) class TestRequest(unittest.TestCase, ReallyEqualMixin): @@ -490,25 +489,25 @@ def test_signature_base_string_nonascii_nonutf8(self): req = oauth.Request("GET", url) self.failUnlessReallyEqual(req.normalized_url, 'http://api.simplegeo.com/1.0/places/address.json') req.sign_request(oauth.SignatureMethod_HMAC_SHA1(), consumer, None) - self.failUnlessReallyEqual(req['oauth_signature'], 'WhufgeZKyYpKsI70GZaiDaYwl6g=') + self.failUnlessReallyEqual(req['oauth_signature'], b'WhufgeZKyYpKsI70GZaiDaYwl6g=') - url = 'http://api.simplegeo.com:80/1.0/places/address.json?q=monkeys&category=animal&address=41+Decatur+St,+San+Francisc\xe2\x9d\xa6,+CA' + url = b'http://api.simplegeo.com:80/1.0/places/address.json?q=monkeys&category=animal&address=41+Decatur+St,+San+Francisc\xe2\x9d\xa6,+CA' req = oauth.Request("GET", url) self.failUnlessReallyEqual(req.normalized_url, 'http://api.simplegeo.com/1.0/places/address.json') req.sign_request(oauth.SignatureMethod_HMAC_SHA1(), consumer, None) - self.failUnlessReallyEqual(req['oauth_signature'], 'WhufgeZKyYpKsI70GZaiDaYwl6g=') + self.failUnlessReallyEqual(req['oauth_signature'], b'WhufgeZKyYpKsI70GZaiDaYwl6g=') url = 'http://api.simplegeo.com:80/1.0/places/address.json?q=monkeys&category=animal&address=41+Decatur+St,+San+Francisc%E2%9D%A6,+CA' req = oauth.Request("GET", url) self.failUnlessReallyEqual(req.normalized_url, 'http://api.simplegeo.com/1.0/places/address.json') req.sign_request(oauth.SignatureMethod_HMAC_SHA1(), consumer, None) - self.failUnlessReallyEqual(req['oauth_signature'], 'WhufgeZKyYpKsI70GZaiDaYwl6g=') + self.failUnlessReallyEqual(req['oauth_signature'], b'WhufgeZKyYpKsI70GZaiDaYwl6g=') url = 'http://api.simplegeo.com:80/1.0/places/address.json?q=monkeys&category=animal&address=41+Decatur+St,+San+Francisc%E2%9D%A6,+CA' req = oauth.Request("GET", url) self.failUnlessReallyEqual(req.normalized_url, 'http://api.simplegeo.com/1.0/places/address.json') req.sign_request(oauth.SignatureMethod_HMAC_SHA1(), consumer, None) - self.failUnlessReallyEqual(req['oauth_signature'], 'WhufgeZKyYpKsI70GZaiDaYwl6g=') + self.failUnlessReallyEqual(req['oauth_signature'], b'WhufgeZKyYpKsI70GZaiDaYwl6g=') def test_signature_base_string_with_query(self): url = "https://www.google.com/m8/feeds/contacts/default/full/?alt=json&max-contacts=10" @@ -598,9 +597,9 @@ def test_get_normalized_parameters(self): 'oauth_consumer_key': "0685bd9184jfhq22", 'oauth_signature_method': "HMAC-SHA1", 'oauth_token': "ad180jjd733klru7", - 'multi': ['FOO','BAR', '\u00ae', '\xc2\xae'], + 'multi': ['FOO','BAR', '\u00ae', b'\xc2\xae'], 'multi_same': ['FOO','FOO'], - 'uni_utf8_bytes': '\xc2\xae', + 'uni_utf8_bytes': b'\xc2\xae', 'uni_unicode_object': '\u00ae' } @@ -682,46 +681,46 @@ def test_request_nonutf8_bytes(self, mock_make_nonce, mock_make_timestamp): # If someone passes a sequence of bytes which is not ascii for # url, we'll raise an exception as early as possible. - url = "http://sp.example.com/\x92" # It's actually cp1252-encoding... + url = b"http://sp.example.com/\x92" # It's actually cp1252-encoding... self.assertRaises(TypeError, oauth.Request, method="GET", url=url, parameters=params) # And if they pass an unicode, then we'll use it. url = 'http://sp.example.com/\u2019' req = oauth.Request(method="GET", url=url, parameters=params) req.sign_request(oauth.SignatureMethod_HMAC_SHA1(), con, None) - self.failUnlessReallyEqual(req['oauth_signature'], 'cMzvCkhvLL57+sTIxLITTHfkqZk=') + self.failUnlessReallyEqual(req['oauth_signature'], b'cMzvCkhvLL57+sTIxLITTHfkqZk=') # And if it is a utf-8-encoded-then-percent-encoded non-ascii # thing, we'll decode it and use it. url = "http://sp.example.com/%E2%80%99" req = oauth.Request(method="GET", url=url, parameters=params) req.sign_request(oauth.SignatureMethod_HMAC_SHA1(), con, None) - self.failUnlessReallyEqual(req['oauth_signature'], 'yMLKOyNKC/DkyhUOb8DLSvceEWE=') + self.failUnlessReallyEqual(req['oauth_signature'], b'yMLKOyNKC/DkyhUOb8DLSvceEWE=') # Same thing with the params. url = "http://sp.example.com/" # If someone passes a sequence of bytes which is not ascii in # params, we'll raise an exception as early as possible. - params['non_oauth_thing'] = '\xae', # It's actually cp1252-encoding... + params['non_oauth_thing'] = b'\xae', # It's actually cp1252-encoding... self.assertRaises(TypeError, oauth.Request, method="GET", url=url, parameters=params) # And if they pass a unicode, then we'll use it. params['non_oauth_thing'] = '\u2019' req = oauth.Request(method="GET", url=url, parameters=params) req.sign_request(oauth.SignatureMethod_HMAC_SHA1(), con, None) - self.failUnlessReallyEqual(req['oauth_signature'], '0GU50m0v60CVDB5JnoBXnvvvKx4=') + self.failUnlessReallyEqual(req['oauth_signature'], b'0GU50m0v60CVDB5JnoBXnvvvKx4=') # And if it is a utf-8-encoded non-ascii thing, we'll decode # it and use it. - params['non_oauth_thing'] = '\xc2\xae' + params['non_oauth_thing'] = b'\xc2\xae' req = oauth.Request(method="GET", url=url, parameters=params) req.sign_request(oauth.SignatureMethod_HMAC_SHA1(), con, None) - self.failUnlessReallyEqual(req['oauth_signature'], 'pqOCu4qvRTiGiXB8Z61Jsey0pMM=') + self.failUnlessReallyEqual(req['oauth_signature'], b'pqOCu4qvRTiGiXB8Z61Jsey0pMM=') # Also if there are non-utf8 bytes in the query args. - url = "http://sp.example.com/?q=\x92" # cp1252 + url = b"http://sp.example.com/?q=\x92" # cp1252 self.assertRaises(TypeError, oauth.Request, method="GET", url=url, parameters=params) def test_request_hash_of_body(self): @@ -743,8 +742,8 @@ def test_request_hash_of_body(self): url = "http://www.example.com/resource" req = oauth.Request(method="PUT", url=url, parameters=params, body="Hello World!", is_form_encoded=False) req.sign_request(oauth.SignatureMethod_HMAC_SHA1(), con, None) - self.failUnlessReallyEqual(req['oauth_body_hash'], 'Lve95gjOVATpfV8EL5X4nxwjKHE=') - self.failUnlessReallyEqual(req['oauth_signature'], 't+MX8l/0S8hdbVQL99nD0X1fPnM=') + self.failUnlessReallyEqual(req['oauth_body_hash'], b'Lve95gjOVATpfV8EL5X4nxwjKHE=') + self.failUnlessReallyEqual(req['oauth_signature'], b't+MX8l/0S8hdbVQL99nD0X1fPnM=') # oauth-bodyhash.html A.1 has # '08bUFF%2Fjmp59mWB7cSgCYBUpJ0U%3D', but I don't see how that # is possible. @@ -760,8 +759,8 @@ def test_request_hash_of_body(self): req = oauth.Request(method="PUT", url=url, parameters=params, body="Hello World!", is_form_encoded=False) req.sign_request(oauth.SignatureMethod_HMAC_SHA1(), con, None) - self.failUnlessReallyEqual(req['oauth_body_hash'], 'Lve95gjOVATpfV8EL5X4nxwjKHE=') - self.failUnlessReallyEqual(req['oauth_signature'], 'CTFmrqJIGT7NsWJ42OrujahTtTc=') + self.failUnlessReallyEqual(req['oauth_body_hash'], b'Lve95gjOVATpfV8EL5X4nxwjKHE=') + self.failUnlessReallyEqual(req['oauth_signature'], b'CTFmrqJIGT7NsWJ42OrujahTtTc=') # Appendix A.2 params = { @@ -774,8 +773,8 @@ def test_request_hash_of_body(self): req = oauth.Request(method="GET", url=url, parameters=params, is_form_encoded=False) req.sign_request(oauth.SignatureMethod_HMAC_SHA1(), con, None) - self.failUnlessReallyEqual(req['oauth_body_hash'], '2jmj7l5rSw0yVb/vlWAYkK/YBwk=') - self.failUnlessReallyEqual(req['oauth_signature'], 'Zhl++aWSP0O3/hYQ0CuBc7jv38I=') + self.failUnlessReallyEqual(req['oauth_body_hash'], b'2jmj7l5rSw0yVb/vlWAYkK/YBwk=') + self.failUnlessReallyEqual(req['oauth_signature'], b'Zhl++aWSP0O3/hYQ0CuBc7jv38I=') def test_sign_request(self): @@ -795,7 +794,7 @@ def test_sign_request(self): req = oauth.Request(method="GET", url=url, parameters=params) methods = { - 'DX01TdHws7OninCLK9VztNTH1M4=': oauth.SignatureMethod_HMAC_SHA1(), + b'DX01TdHws7OninCLK9VztNTH1M4=': oauth.SignatureMethod_HMAC_SHA1(), 'con-test-secret&tok-test-secret': oauth.SignatureMethod_PLAINTEXT() } @@ -805,26 +804,26 @@ def test_sign_request(self): self.assertEquals(req['oauth_signature'], exp) # Also if there are non-ascii chars in the URL. - url = "http://sp.example.com/\xe2\x80\x99" # utf-8 bytes + url = b"http://sp.example.com/\xe2\x80\x99" # utf-8 bytes req = oauth.Request(method="GET", url=url, parameters=params) req.sign_request(oauth.SignatureMethod_HMAC_SHA1(), con, tok) - self.assertEquals(req['oauth_signature'], 'loFvp5xC7YbOgd9exIO6TxB7H4s=') + self.assertEquals(req['oauth_signature'], b'loFvp5xC7YbOgd9exIO6TxB7H4s=') url = 'http://sp.example.com/\u2019' # Python unicode object req = oauth.Request(method="GET", url=url, parameters=params) req.sign_request(oauth.SignatureMethod_HMAC_SHA1(), con, tok) - self.assertEquals(req['oauth_signature'], 'loFvp5xC7YbOgd9exIO6TxB7H4s=') + self.assertEquals(req['oauth_signature'], b'loFvp5xC7YbOgd9exIO6TxB7H4s=') # Also if there are non-ascii chars in the query args. - url = "http://sp.example.com/?q=\xe2\x80\x99" # utf-8 bytes + url = b"http://sp.example.com/?q=\xe2\x80\x99" # utf-8 bytes req = oauth.Request(method="GET", url=url, parameters=params) req.sign_request(oauth.SignatureMethod_HMAC_SHA1(), con, tok) - self.assertEquals(req['oauth_signature'], 'IBw5mfvoCsDjgpcsVKbyvsDqQaU=') + self.assertEquals(req['oauth_signature'], b'IBw5mfvoCsDjgpcsVKbyvsDqQaU=') url = 'http://sp.example.com/?q=\u2019' # Python unicode object req = oauth.Request(method="GET", url=url, parameters=params) req.sign_request(oauth.SignatureMethod_HMAC_SHA1(), con, tok) - self.assertEquals(req['oauth_signature'], 'IBw5mfvoCsDjgpcsVKbyvsDqQaU=') + self.assertEquals(req['oauth_signature'], b'IBw5mfvoCsDjgpcsVKbyvsDqQaU=') def test_from_request(self): url = "http://sp.example.com/" @@ -1189,7 +1188,7 @@ def test_access_token_post(self): self.assertEquals(int(resp['status']), 200) - res = dict(parse_qsl(content)) + res = dict(parse_qsl(content.decode('utf-8'))) self.assertTrue('oauth_token' in res) self.assertTrue('oauth_token_secret' in res) From a90b5628cc14206f12e3a00a195fc96ec289bf43 Mon Sep 17 00:00:00 2001 From: osman Date: Fri, 12 Aug 2011 14:46:25 -0400 Subject: [PATCH 3/3] make sure oauth headers are not bytestrings the original port had both oauth_body_hash and oauth_signature as bytestrings. this caused the request to be sent out with those fields enclosed in b''. This caused POST requests to fail for me, not sure why GET requests worked. --- oauth2/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/oauth2/__init__.py b/oauth2/__init__.py index 66f25d0b..2e13aeee 100644 --- a/oauth2/__init__.py +++ b/oauth2/__init__.py @@ -470,7 +470,7 @@ def sign_request(self, signature_method, consumer, token): # section 4.1.1 "OAuth Consumers MUST NOT include an # oauth_body_hash parameter on requests with form-encoded # request bodies." - self['oauth_body_hash'] = base64.b64encode(sha(self.body.encode('utf8')).digest()) + self['oauth_body_hash'] = base64.b64encode(sha(self.body.encode('utf8')).digest()).decode('utf-8') if 'oauth_consumer_key' not in self: self['oauth_consumer_key'] = consumer.key @@ -479,7 +479,7 @@ def sign_request(self, signature_method, consumer, token): self['oauth_token'] = token.key self['oauth_signature_method'] = signature_method.name - self['oauth_signature'] = signature_method.sign(self, consumer, token) + self['oauth_signature'] = signature_method.sign(self, consumer, token).decode('utf-8') @classmethod def make_timestamp(cls):