28
28
import os
29
29
import sys
30
30
import time
31
- import urllib
32
- import urlparse
31
+ import six
32
+ from six . moves import urllib
33
33
34
34
import httplib2
35
35
from oauth2client import clientsecrets
@@ -231,6 +231,9 @@ def _to_json(self, strip):
231
231
# Add in information we will need later to reconsistitue this instance.
232
232
d ['_class' ] = t .__name__
233
233
d ['_module' ] = t .__module__
234
+ for key , val in d .items ():
235
+ if isinstance (val , bytes ):
236
+ d [key ] = val .decode ('utf-8' )
234
237
return json .dumps (d )
235
238
236
239
def to_json (self ):
@@ -254,6 +257,8 @@ def new_from_json(cls, s):
254
257
An instance of the subclass of Credentials that was serialized with
255
258
to_json().
256
259
"""
260
+ if six .PY3 and isinstance (s , bytes ):
261
+ s = s .decode ('utf-8' )
257
262
data = json .loads (s )
258
263
# Find and call the right classmethod from_json() to restore the object.
259
264
module = data ['_module' ]
@@ -398,7 +403,7 @@ def clean_headers(headers):
398
403
"""
399
404
clean = {}
400
405
try :
401
- for k , v in headers .iteritems ():
406
+ for k , v in six .iteritems (headers ):
402
407
clean [str (k )] = str (v )
403
408
except UnicodeEncodeError :
404
409
raise NonAsciiHeaderError (k + ': ' + v )
@@ -415,11 +420,11 @@ def _update_query_params(uri, params):
415
420
Returns:
416
421
The same URI but with the new query parameters added.
417
422
"""
418
- parts = urlparse .urlparse (uri )
419
- query_params = dict (urlparse .parse_qsl (parts .query ))
423
+ parts = urllib . parse .urlparse (uri )
424
+ query_params = dict (urllib . parse .parse_qsl (parts .query ))
420
425
query_params .update (params )
421
- new_parts = parts ._replace (query = urllib .urlencode (query_params ))
422
- return urlparse .urlunparse (new_parts )
426
+ new_parts = parts ._replace (query = urllib .parse . urlencode (query_params ))
427
+ return urllib . parse .urlunparse (new_parts )
423
428
424
429
425
430
class OAuth2Credentials (Credentials ):
@@ -589,6 +594,8 @@ def from_json(cls, s):
589
594
Returns:
590
595
An instance of a Credentials subclass.
591
596
"""
597
+ if six .PY3 and isinstance (s , bytes ):
598
+ s = s .decode ('utf-8' )
592
599
data = json .loads (s )
593
600
if (data .get ('token_expiry' ) and
594
601
not isinstance (data ['token_expiry' ], datetime .datetime )):
@@ -691,7 +698,7 @@ def __setstate__(self, state):
691
698
692
699
def _generate_refresh_request_body (self ):
693
700
"""Generate the body that will be used in the refresh request."""
694
- body = urllib .urlencode ({
701
+ body = urllib .parse . urlencode ({
695
702
'grant_type' : 'refresh_token' ,
696
703
'client_id' : self .client_id ,
697
704
'client_secret' : self .client_secret ,
@@ -755,8 +762,9 @@ def _do_refresh_request(self, http_request):
755
762
logger .info ('Refreshing access_token' )
756
763
resp , content = http_request (
757
764
self .token_uri , method = 'POST' , body = body , headers = headers )
765
+ if six .PY3 :
766
+ content = content .decode ('utf-8' )
758
767
if resp .status == 200 :
759
- # TODO(jcgregorio) Raise an error if loads fails?
760
768
d = json .loads (content )
761
769
self .token_response = d
762
770
self .access_token = d ['access_token' ]
@@ -785,7 +793,7 @@ def _do_refresh_request(self, http_request):
785
793
self .invalid = True
786
794
if self .store :
787
795
self .store .locked_put (self )
788
- except StandardError :
796
+ except ( TypeError , ValueError ) :
789
797
pass
790
798
raise AccessTokenRefreshError (error_msg )
791
799
@@ -822,7 +830,7 @@ def _do_revoke(self, http_request, token):
822
830
d = json .loads (content )
823
831
if 'error' in d :
824
832
error_msg = d ['error' ]
825
- except StandardError :
833
+ except ( TypeError , ValueError ) :
826
834
pass
827
835
raise TokenRevokeError (error_msg )
828
836
@@ -880,10 +888,12 @@ def __init__(self, access_token, user_agent, revoke_uri=None):
880
888
881
889
@classmethod
882
890
def from_json (cls , s ):
891
+ if six .PY3 and isinstance (s , bytes ):
892
+ s = s .decode ('utf-8' )
883
893
data = json .loads (s )
884
894
retval = AccessTokenCredentials (
885
- data ['access_token' ],
886
- data ['user_agent' ])
895
+ data ['access_token' ],
896
+ data ['user_agent' ])
887
897
return retval
888
898
889
899
def _refresh (self , http_request ):
@@ -903,7 +913,7 @@ def _revoke(self, http_request):
903
913
_env_name = None
904
914
905
915
906
- def _get_environment (urllib2_urlopen = None ):
916
+ def _get_environment (urlopen = None ):
907
917
"""Detect the environment the code is being run on."""
908
918
909
919
global _env_name
@@ -917,16 +927,15 @@ def _get_environment(urllib2_urlopen=None):
917
927
elif server_software .startswith ('Development/' ):
918
928
_env_name = 'GAE_LOCAL'
919
929
else :
920
- import urllib2
921
930
try :
922
- if urllib2_urlopen is None :
923
- urllib2_urlopen = urllib2 .urlopen
924
- response = urllib2_urlopen ('http://metadata.google.internal' )
931
+ if urlopen is None :
932
+ urlopen = urllib . request .urlopen
933
+ response = urlopen ('http://metadata.google.internal' )
925
934
if any ('Metadata-Flavor: Google' in h for h in response .info ().headers ):
926
935
_env_name = 'GCE_PRODUCTION'
927
936
else :
928
937
_env_name = 'UNKNOWN'
929
- except urllib2 .URLError :
938
+ except urllib . error .URLError :
930
939
_env_name = 'UNKNOWN'
931
940
932
941
return _env_name
@@ -956,7 +965,7 @@ class GoogleCredentials(OAuth2Credentials):
956
965
request = service.instances().list(project=PROJECT, zone=ZONE)
957
966
response = request.execute()
958
967
959
- print response
968
+ print( response)
960
969
</code>
961
970
962
971
A service that does not require authentication does not need credentials
@@ -970,7 +979,7 @@ class GoogleCredentials(OAuth2Credentials):
970
979
request = service.apis().list()
971
980
response = request.execute()
972
981
973
- print response
982
+ print( response)
974
983
</code>
975
984
"""
976
985
@@ -1168,7 +1177,7 @@ def _get_application_default_credential_from_file(
1168
1177
application_default_credential_filename ):
1169
1178
"""Build the Application Default Credentials from file."""
1170
1179
1171
- import service_account
1180
+ from oauth2client import service_account
1172
1181
1173
1182
# read the credentials from the file
1174
1183
with open (application_default_credential_filename ) as (
@@ -1274,7 +1283,7 @@ def __init__(self, assertion_type, user_agent=None,
1274
1283
def _generate_refresh_request_body (self ):
1275
1284
assertion = self ._generate_assertion ()
1276
1285
1277
- body = urllib .urlencode ({
1286
+ body = urllib .parse . urlencode ({
1278
1287
'assertion' : assertion ,
1279
1288
'grant_type' : 'urn:ietf:params:oauth:grant-type:jwt-bearer' ,
1280
1289
})
@@ -1363,6 +1372,8 @@ def __init__(self,
1363
1372
1364
1373
# Keep base64 encoded so it can be stored in JSON.
1365
1374
self .private_key = base64 .b64encode (private_key )
1375
+ if isinstance (self .private_key , six .text_type ):
1376
+ self .private_key = self .private_key .encode ('utf-8' )
1366
1377
1367
1378
self .private_key_password = private_key_password
1368
1379
self .service_account_name = service_account_name
@@ -1386,7 +1397,7 @@ def from_json(cls, s):
1386
1397
1387
1398
def _generate_assertion (self ):
1388
1399
"""Generate the assertion that will be used in the request."""
1389
- now = long (time .time ())
1400
+ now = int (time .time ())
1390
1401
payload = {
1391
1402
'aud' : self .token_uri ,
1392
1403
'scope' : self .scope ,
@@ -1435,16 +1446,17 @@ def verify_id_token(id_token, audience, http=None,
1435
1446
resp , content = http .request (cert_uri )
1436
1447
1437
1448
if resp .status == 200 :
1438
- certs = json .loads (content )
1449
+ certs = json .loads (content . decode ( 'utf-8' ) )
1439
1450
return crypt .verify_signed_jwt_with_certs (id_token , certs , audience )
1440
1451
else :
1441
1452
raise VerifyJwtTokenError ('Status code: %d' % resp .status )
1442
1453
1443
1454
1444
1455
def _urlsafe_b64decode (b64string ):
1445
1456
# Guard against unicode strings, which base64 can't handle.
1446
- b64string = b64string .encode ('ascii' )
1447
- padded = b64string + '=' * (4 - len (b64string ) % 4 )
1457
+ if isinstance (b64string , six .text_type ):
1458
+ b64string = b64string .encode ('ascii' )
1459
+ padded = b64string + b'=' * (4 - len (b64string ) % 4 )
1448
1460
return base64 .urlsafe_b64decode (padded )
1449
1461
1450
1462
@@ -1465,7 +1477,7 @@ def _extract_id_token(id_token):
1465
1477
raise VerifyJwtTokenError (
1466
1478
'Wrong number of segments in token: %s' % id_token )
1467
1479
1468
- return json .loads (_urlsafe_b64decode (segments [1 ]))
1480
+ return json .loads (_urlsafe_b64decode (segments [1 ]). decode ( 'utf-8' ) )
1469
1481
1470
1482
1471
1483
def _parse_exchange_token_response (content ):
@@ -1483,11 +1495,11 @@ def _parse_exchange_token_response(content):
1483
1495
"""
1484
1496
resp = {}
1485
1497
try :
1486
- resp = json .loads (content )
1487
- except StandardError :
1498
+ resp = json .loads (content . decode ( 'utf-8' ) )
1499
+ except Exception :
1488
1500
# different JSON libs raise different exceptions,
1489
1501
# so we just do a catch-all here
1490
- resp = dict (urlparse .parse_qsl (content ))
1502
+ resp = dict (urllib . parse .parse_qsl (content ))
1491
1503
1492
1504
# some providers respond with 'expires', others with 'expires_in'
1493
1505
if resp and 'expires' in resp :
@@ -1810,7 +1822,7 @@ def step2_exchange(self, code=None, http=None, device_flow_info=None):
1810
1822
else :
1811
1823
post_data ['grant_type' ] = 'authorization_code'
1812
1824
post_data ['redirect_uri' ] = self .redirect_uri
1813
- body = urllib .urlencode (post_data )
1825
+ body = urllib .parse . urlencode (post_data )
1814
1826
headers = {
1815
1827
'content-type' : 'application/x-www-form-urlencoded' ,
1816
1828
}
@@ -1851,7 +1863,7 @@ def step2_exchange(self, code=None, http=None, device_flow_info=None):
1851
1863
logger .info ('Failed to retrieve access token: %s' , content )
1852
1864
if 'error' in d :
1853
1865
# you never know what those providers got to say
1854
- error_msg = unicode (d ['error' ])
1866
+ error_msg = str (d ['error' ])
1855
1867
else :
1856
1868
error_msg = 'Invalid response: %s.' % str (resp .status )
1857
1869
raise FlowExchangeError (error_msg )
0 commit comments