Skip to content
This repository was archived by the owner on Jan 18, 2025. It is now read-only.

Commit 3c647bd

Browse files
committed
Re-enable Python3 tests and fixing Py2/Py3 issues in tests.
Partially fixes #85.
1 parent b20d3d6 commit 3c647bd

5 files changed

Lines changed: 46 additions & 36 deletions

File tree

.travis.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ env:
55
- TOX_ENV=py26openssl14
66
- TOX_ENV=py27openssl13
77
- TOX_ENV=py27openssl14
8+
- TOX_ENV=py33openssl14
9+
- TOX_ENV=py34openssl14
810
- TOX_ENV=pypyopenssl13
911
- TOX_ENV=pypyopenssl14
1012
install:

oauth2client/client.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,7 @@ def clean_headers(headers):
409409
clean = {}
410410
try:
411411
for k, v in six.iteritems(headers):
412-
clean[str(k)] = str(v)
412+
clean[k.encode('ascii')] = v.encode('ascii')
413413
except UnicodeEncodeError:
414414
raise NonAsciiHeaderError(k + ': ' + v)
415415
return clean
@@ -1252,16 +1252,14 @@ def _get_well_known_file():
12521252
return default_config_path
12531253

12541254

1255-
def _get_application_default_credential_from_file(
1256-
application_default_credential_filename):
1255+
def _get_application_default_credential_from_file(filename):
12571256
"""Build the Application Default Credentials from file."""
12581257

12591258
from oauth2client import service_account
12601259

12611260
# read the credentials from the file
1262-
with open(application_default_credential_filename) as (
1263-
application_default_credential):
1264-
client_credentials = json.load(application_default_credential)
1261+
with open(filename) as file_obj:
1262+
client_credentials = json.load(file_obj)
12651263

12661264
credentials_type = client_credentials.get('type')
12671265
if credentials_type == AUTHORIZED_USER:
@@ -1545,12 +1543,15 @@ def _extract_id_token(id_token):
15451543
Does the extraction w/o checking the signature.
15461544
15471545
Args:
1548-
id_token: string, OAuth 2.0 id_token.
1546+
id_token: string or bytestring, OAuth 2.0 id_token.
15491547
15501548
Returns:
15511549
object, The deserialized JSON payload.
15521550
"""
1553-
segments = id_token.split('.')
1551+
if type(id_token) == bytes:
1552+
segments = id_token.split(b'.')
1553+
else:
1554+
segments = id_token.split(u'.')
15541555

15551556
if len(segments) != 3:
15561557
raise VerifyJwtTokenError(
@@ -1578,6 +1579,7 @@ def _parse_exchange_token_response(content):
15781579
except Exception:
15791580
# different JSON libs raise different exceptions,
15801581
# so we just do a catch-all here
1582+
content = content.decode('utf-8')
15811583
resp = dict(urllib.parse.parse_qsl(content))
15821584

15831585
# some providers respond with 'expires', others with 'expires_in'

oauth2client/service_account.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
import base64
2121
import json
22+
import six
2223
import time
2324

2425
from pyasn1.codec.ber import decoder
@@ -131,6 +132,8 @@ def _urlsafe_b64encode(data):
131132
def _get_private_key(private_key_pkcs8_text):
132133
"""Get an RSA private key object from a pkcs8 representation."""
133134

135+
if not isinstance(private_key_pkcs8_text, six.binary_type):
136+
private_key_pkcs8_text = private_key_pkcs8_text.encode('ascii')
134137
der = rsa.pem.load_pem(private_key_pkcs8_text, 'PRIVATE KEY')
135138
asn1_private_key, _ = decoder.decode(der, asn1Spec=PrivateKeyInfo())
136139
return rsa.PrivateKey.load_pkcs1(

tests/test_jwt.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ def test_credentials_good(self):
217217
])
218218
http = credentials.authorize(http)
219219
resp, content = http.request('http://example.org')
220-
self.assertEqual('Bearer 1/3w', content['Authorization'])
220+
self.assertEqual(b'Bearer 1/3w', content[b'Authorization'])
221221

222222
def test_credentials_to_from_json(self):
223223
private_key = datafile('privatekey.%s' % self.format)
@@ -254,7 +254,7 @@ def test_credentials_refresh_without_storage(self):
254254

255255
content = self._credentials_refresh(credentials)
256256

257-
self.assertEqual('Bearer 3/3w', content['Authorization'])
257+
self.assertEqual(b'Bearer 3/3w', content[b'Authorization'])
258258

259259
def test_credentials_refresh_with_storage(self):
260260
private_key = datafile('privatekey.%s' % self.format)
@@ -272,7 +272,7 @@ def test_credentials_refresh_with_storage(self):
272272

273273
content = self._credentials_refresh(credentials)
274274

275-
self.assertEqual('Bearer 3/3w', content['Authorization'])
275+
self.assertEqual(b'Bearer 3/3w', content[b'Authorization'])
276276
os.unlink(filename)
277277

278278

tests/test_oauth2client.py

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -545,7 +545,7 @@ def test_token_refresh_success(self):
545545
])
546546
http = self.credentials.authorize(http)
547547
resp, content = http.request('http://example.com')
548-
self.assertEqual('Bearer 1/3w', content['Authorization'])
548+
self.assertEqual(b'Bearer 1/3w', content[b'Authorization'])
549549
self.assertFalse(self.credentials.access_token_expired)
550550
self.assertEqual(token_response, self.credentials.token_response)
551551

@@ -615,10 +615,10 @@ def test_no_unicode_in_request_params(self):
615615
http = credentials.authorize(http)
616616
http.request(u'http://example.com', method=u'GET', headers={u'foo': u'bar'})
617617
for k, v in six.iteritems(http.headers):
618-
self.assertEqual(str, type(k))
619-
self.assertEqual(str, type(v))
618+
self.assertEqual(six.binary_type, type(k))
619+
self.assertEqual(six.binary_type, type(v))
620620

621-
# Test again with unicode strings that can't simple be converted to ASCII.
621+
# Test again with unicode strings that can't simply be converted to ASCII.
622622
try:
623623
http.request(
624624
u'http://example.com', method=u'GET', headers={u'foo': u'\N{COMET}'})
@@ -707,7 +707,7 @@ def test_auth_header_sent(self):
707707
])
708708
http = self.credentials.authorize(http)
709709
resp, content = http.request('http://example.com')
710-
self.assertEqual('Bearer foo', content['Authorization'])
710+
self.assertEqual(b'Bearer foo', content[b'Authorization'])
711711

712712

713713
class TestAssertionCredentials(unittest.TestCase):
@@ -738,7 +738,7 @@ def test_assertion_refresh(self):
738738
])
739739
http = self.credentials.authorize(http)
740740
resp, content = http.request('http://example.com')
741-
self.assertEqual('Bearer 1/3w', content['Authorization'])
741+
self.assertEqual(b'Bearer 1/3w', content[b'Authorization'])
742742

743743
def test_token_revoke_success(self):
744744
_token_revoke_test_helper(
@@ -769,16 +769,18 @@ class ExtractIdTokenTest(unittest.TestCase):
769769

770770
def test_extract_success(self):
771771
body = {'foo': 'bar'}
772-
payload = base64.urlsafe_b64encode(json.dumps(body)).strip('=')
773-
jwt = 'stuff.' + payload + '.signature'
772+
body_json = json.dumps(body).encode('ascii')
773+
payload = base64.urlsafe_b64encode(body_json).strip(b'=')
774+
jwt = b'stuff.' + payload + b'.signature'
774775

775776
extracted = _extract_id_token(jwt)
776777
self.assertEqual(extracted, body)
777778

778779
def test_extract_failure(self):
779780
body = {'foo': 'bar'}
780-
payload = base64.urlsafe_b64encode(json.dumps(body)).strip('=')
781-
jwt = 'stuff.' + payload
781+
body_json = json.dumps(body).encode('ascii')
782+
payload = base64.urlsafe_b64encode(body_json).strip(b'=')
783+
jwt = b'stuff.' + payload
782784

783785
self.assertRaises(VerifyJwtTokenError, _extract_id_token, jwt)
784786

@@ -840,14 +842,14 @@ def test_exchange_failure(self):
840842

841843
def test_urlencoded_exchange_failure(self):
842844
http = HttpMockSequence([
843-
({'status': '400'}, 'error=invalid_request'),
845+
({'status': '400'}, b'error=invalid_request'),
844846
])
845847

846848
try:
847849
credentials = self.flow.step2_exchange('some random code', http=http)
848850
self.fail('should raise exception if exchange doesn\'t get 200')
849851
except FlowExchangeError as e:
850-
self.assertEquals('invalid_request', str(e))
852+
self.assertEqual('invalid_request', str(e))
851853

852854
def test_exchange_failure_with_json_error(self):
853855
# Some providers have 'error' attribute as a JSON object
@@ -894,12 +896,12 @@ def __contains__(self, name):
894896

895897
code = 'some random code'
896898
not_a_dict = FakeDict({'code': code})
897-
http = HttpMockSequence([
898-
({'status': '200'},
899-
"""{ "access_token":"SlAV32hkKG",
900-
"expires_in":3600,
901-
"refresh_token":"8xLOxBtZp8" }"""),
902-
])
899+
payload = (b'{'
900+
b' "access_token":"SlAV32hkKG",'
901+
b' "expires_in":3600,'
902+
b' "refresh_token":"8xLOxBtZp8"'
903+
b'}')
904+
http = HttpMockSequence([({'status': '200'}, payload),])
903905

904906
credentials = self.flow.step2_exchange(not_a_dict, http=http)
905907
self.assertEqual('SlAV32hkKG', credentials.access_token)
@@ -972,9 +974,10 @@ def test_exchange_id_token_fail(self):
972974

973975
def test_exchange_id_token(self):
974976
body = {'foo': 'bar'}
975-
payload = base64.urlsafe_b64encode(json.dumps(body)).strip('=')
976-
jwt = (base64.urlsafe_b64encode('stuff')+ '.' + payload + '.' +
977-
base64.urlsafe_b64encode('signature'))
977+
body_json = json.dumps(body).encode('ascii')
978+
payload = base64.urlsafe_b64encode(body_json).strip(b'=')
979+
jwt = (base64.urlsafe_b64encode(b'stuff') + b'.' + payload + b'.' +
980+
base64.urlsafe_b64encode(b'signature'))
978981

979982
http = HttpMockSequence([
980983
({'status': '200'}, ("""{ "access_token":"SlAV32hkKG",
@@ -994,7 +997,7 @@ def test_flow_from_clientsecrets_cached(self):
994997

995998
flow = flow_from_clientsecrets(
996999
'some_secrets', '', redirect_uri='oob', cache=cache_mock)
997-
self.assertEquals('foo_client_secret', flow.client_secret)
1000+
self.assertEqual('foo_client_secret', flow.client_secret)
9981001

9991002

10001003
class CredentialsFromCodeTests(unittest.TestCase):
@@ -1014,7 +1017,7 @@ def test_exchange_code_for_token(self):
10141017
credentials = credentials_from_code(self.client_id, self.client_secret,
10151018
self.scope, self.code, redirect_uri=self.redirect_uri,
10161019
http=http)
1017-
self.assertEquals(credentials.access_token, token)
1020+
self.assertEqual(credentials.access_token, token)
10181021
self.assertNotEqual(None, credentials.token_expiry)
10191022

10201023
def test_exchange_code_for_token_fail(self):
@@ -1039,7 +1042,7 @@ def test_exchange_code_and_file_for_token(self):
10391042
credentials = credentials_from_clientsecrets_and_code(
10401043
datafile('client_secrets.json'), self.scope,
10411044
self.code, http=http)
1042-
self.assertEquals(credentials.access_token, 'asdfghjkl')
1045+
self.assertEqual(credentials.access_token, 'asdfghjkl')
10431046
self.assertNotEqual(None, credentials.token_expiry)
10441047

10451048
def test_exchange_code_and_cached_file_for_token(self):
@@ -1052,7 +1055,7 @@ def test_exchange_code_and_cached_file_for_token(self):
10521055
credentials = credentials_from_clientsecrets_and_code(
10531056
'some_secrets', self.scope,
10541057
self.code, http=http, cache=cache_mock)
1055-
self.assertEquals(credentials.access_token, 'asdfghjkl')
1058+
self.assertEqual(credentials.access_token, 'asdfghjkl')
10561059

10571060
def test_exchange_code_and_file_for_token_fail(self):
10581061
http = HttpMockSequence([

0 commit comments

Comments
 (0)