Require python >= 2.6, use the json module.

* Set the minimum version of python to be 2.6, since we don't need to support
  anything older anymore.

* As the first of a series of related cleanups, drop our custom json
  module (since json is in the stdlib since 2.6).
This commit is contained in:
Craig Citro
2014-08-15 11:22:05 -07:00
parent 0399a77a6a
commit 0cad208658
16 changed files with 68 additions and 111 deletions

View File

@@ -1,32 +0,0 @@
# Copyright (C) 2010 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Utility module to import a JSON module
Hides all the messy details of exactly where
we get a simplejson module from.
"""
__author__ = 'jcgregorio@google.com (Joe Gregorio)'
try: # pragma: no cover
# Should work for Python2.6 and higher.
import json as simplejson
except ImportError: # pragma: no cover
try:
import simplejson
except ImportError:
# Try to import from django, should work on App Engine
from django.utils import simplejson

View File

@@ -22,6 +22,7 @@ __author__ = 'jcgregorio@google.com (Joe Gregorio)'
import base64
import cgi
import httplib2
import json
import logging
import os
import pickle
@@ -41,7 +42,6 @@ from oauth2client import GOOGLE_TOKEN_URI
from oauth2client import clientsecrets
from oauth2client import util
from oauth2client import xsrfutil
from oauth2client.anyjson import simplejson
from oauth2client.client import AccessTokenRefreshError
from oauth2client.client import AssertionCredentials
from oauth2client.client import Credentials
@@ -172,7 +172,7 @@ class AppAssertionCredentials(AssertionCredentials):
@classmethod
def from_json(cls, json):
data = simplejson.loads(json)
data = json.loads(json)
return AppAssertionCredentials(data['scope'])
def _refresh(self, http_request):
@@ -882,7 +882,7 @@ class OAuth2Decorator(object):
user)
if decorator._token_response_param and credentials.token_response:
resp_json = simplejson.dumps(credentials.token_response)
resp_json = json.dumps(credentials.token_response)
redirect_uri = util._add_query_parameter(
redirect_uri, decorator._token_response_param, resp_json)

View File

@@ -24,6 +24,7 @@ import clientsecrets
import copy
import datetime
import httplib2
import json
import logging
import os
import sys
@@ -36,7 +37,6 @@ from oauth2client import GOOGLE_AUTH_URI
from oauth2client import GOOGLE_REVOKE_URI
from oauth2client import GOOGLE_TOKEN_URI
from oauth2client import util
from oauth2client.anyjson import simplejson
HAS_OPENSSL = False
HAS_CRYPTO = False
@@ -210,7 +210,7 @@ class Credentials(object):
# Add in information we will need later to reconsistitue this instance.
d['_class'] = t.__name__
d['_module'] = t.__module__
return simplejson.dumps(d)
return json.dumps(d)
def to_json(self):
"""Creating a JSON representation of an instance of Credentials.
@@ -233,7 +233,7 @@ class Credentials(object):
An instance of the subclass of Credentials that was serialized with
to_json().
"""
data = simplejson.loads(s)
data = json.loads(s)
# Find and call the right classmethod from_json() to restore the object.
module = data['_module']
try:
@@ -568,7 +568,7 @@ class OAuth2Credentials(Credentials):
Returns:
An instance of a Credentials subclass.
"""
data = simplejson.loads(s)
data = json.loads(s)
if 'token_expiry' in data and not isinstance(data['token_expiry'],
datetime.datetime):
try:
@@ -736,7 +736,7 @@ class OAuth2Credentials(Credentials):
self.token_uri, method='POST', body=body, headers=headers)
if resp.status == 200:
# TODO(jcgregorio) Raise an error if loads fails?
d = simplejson.loads(content)
d = json.loads(content)
self.token_response = d
self.access_token = d['access_token']
self.refresh_token = d.get('refresh_token', self.refresh_token)
@@ -756,7 +756,7 @@ class OAuth2Credentials(Credentials):
logger.info('Failed to retrieve access token: %s' % content)
error_msg = 'Invalid response %s.' % resp['status']
try:
d = simplejson.loads(content)
d = json.loads(content)
if 'error' in d:
error_msg = d['error']
self.invalid = True
@@ -796,7 +796,7 @@ class OAuth2Credentials(Credentials):
else:
error_msg = 'Invalid response %s.' % resp.status
try:
d = simplejson.loads(content)
d = json.loads(content)
if 'error' in d:
error_msg = d['error']
except StandardError:
@@ -857,7 +857,7 @@ class AccessTokenCredentials(OAuth2Credentials):
@classmethod
def from_json(cls, s):
data = simplejson.loads(s)
data = json.loads(s)
retval = AccessTokenCredentials(
data['access_token'],
data['user_agent'])
@@ -1102,7 +1102,7 @@ def save_to_well_known_file(credentials, well_known_file=None):
credentials_data = credentials.serialization_data
with open(well_known_file, 'w') as f:
simplejson.dump(credentials_data, f, sort_keys=True, indent=2)
json.dump(credentials_data, f, sort_keys=True, indent=2)
def _get_environment_variable_file():
@@ -1156,8 +1156,7 @@ def _get_application_default_credential_from_file(
# read the credentials from the file
with open(application_default_credential_filename) as (
application_default_credential):
client_credentials = service_account.simplejson.load(
application_default_credential)
client_credentials = json.load(application_default_credential)
credentials_type = client_credentials.get('type')
if credentials_type == AUTHORIZED_USER:
@@ -1343,7 +1342,7 @@ if HAS_CRYPTO:
@classmethod
def from_json(cls, s):
data = simplejson.loads(s)
data = json.loads(s)
retval = SignedJwtAssertionCredentials(
data['service_account_name'],
base64.b64decode(data['private_key']),
@@ -1406,7 +1405,7 @@ if HAS_CRYPTO:
resp, content = http.request(cert_uri)
if resp.status == 200:
certs = simplejson.loads(content)
certs = json.loads(content)
return crypt.verify_signed_jwt_with_certs(id_token, certs, audience)
else:
raise VerifyJwtTokenError('Status code: %d' % resp.status)
@@ -1436,7 +1435,7 @@ def _extract_id_token(id_token):
raise VerifyJwtTokenError(
'Wrong number of segments in token: %s' % id_token)
return simplejson.loads(_urlsafe_b64decode(segments[1]))
return json.loads(_urlsafe_b64decode(segments[1]))
def _parse_exchange_token_response(content):
@@ -1454,7 +1453,7 @@ def _parse_exchange_token_response(content):
"""
resp = {}
try:
resp = simplejson.loads(content)
resp = json.loads(content)
except StandardError:
# different JSON libs raise different exceptions,
# so we just do a catch-all here

View File

@@ -20,8 +20,8 @@ an OAuth 2.0 protected service.
__author__ = 'jcgregorio@google.com (Joe Gregorio)'
import json
from anyjson import simplejson
# Properties that make a client_secrets.json file valid.
TYPE_WEB = 'web'
@@ -87,12 +87,12 @@ def _validate_clientsecrets(obj):
def load(fp):
obj = simplejson.load(fp)
obj = json.load(fp)
return _validate_clientsecrets(obj)
def loads(s):
obj = simplejson.loads(s)
obj = json.loads(s)
return _validate_clientsecrets(obj)
@@ -100,7 +100,7 @@ def _loadfile(filename):
try:
fp = file(filename, 'r')
try:
obj = simplejson.load(fp)
obj = json.load(fp)
finally:
fp.close()
except IOError:

View File

@@ -17,11 +17,10 @@
import base64
import hashlib
import json
import logging
import time
from anyjson import simplejson
CLOCK_SKEW_SECS = 300 # 5 minutes in seconds
AUTH_TOKEN_LIFETIME_SECS = 300 # 5 minutes in seconds
@@ -287,7 +286,7 @@ def _urlsafe_b64decode(b64string):
def _json_encode(data):
return simplejson.dumps(data, separators = (',', ':'))
return json.dumps(data, separators = (',', ':'))
def make_signed_jwt(signer, payload):
@@ -347,7 +346,7 @@ def verify_signed_jwt_with_certs(jwt, certs, audience):
# Parse token.
json_body = _urlsafe_b64decode(segments[1])
try:
parsed = simplejson.loads(json_body)
parsed = json.loads(json_body)
except:
raise AppIdentityError('Can\'t parse token: %s' % json_body)

View File

@@ -24,7 +24,6 @@ import os
import stat
import threading
from anyjson import simplejson
from client import Storage as BaseStorage
from client import Credentials

View File

@@ -20,11 +20,11 @@ Utilities for making it easier to use OAuth 2.0 on Google Compute Engine.
__author__ = 'jcgregorio@google.com (Joe Gregorio)'
import httplib2
import json
import logging
import uritemplate
from oauth2client import util
from oauth2client.anyjson import simplejson
from oauth2client.client import AccessTokenRefreshError
from oauth2client.client import AssertionCredentials
@@ -63,8 +63,8 @@ class AppAssertionCredentials(AssertionCredentials):
super(AppAssertionCredentials, self).__init__(None)
@classmethod
def from_json(cls, json):
data = simplejson.loads(json)
def from_json(cls, json_data):
data = json.loads(json_data)
return AppAssertionCredentials(data['scope'])
def _refresh(self, http_request):
@@ -83,7 +83,7 @@ class AppAssertionCredentials(AssertionCredentials):
response, content = http_request(uri)
if response.status == 200:
try:
d = simplejson.loads(content)
d = json.loads(content)
except StandardError as e:
raise AccessTokenRefreshError(str(e))
self.access_token = d['accessToken']

View File

@@ -45,11 +45,11 @@ __author__ = 'jbeda@google.com (Joe Beda)'
import base64
import errno
import json
import logging
import os
import threading
from anyjson import simplejson
from oauth2client.client import Storage as BaseStorage
from oauth2client.client import Credentials
from oauth2client import util
@@ -315,7 +315,7 @@ class _MultiStore(object):
"""
assert self._thread_lock.locked()
self._file.file_handle().seek(0)
return simplejson.load(self._file.file_handle())
return json.load(self._file.file_handle())
def _locked_json_write(self, data):
"""Write a JSON serializable data structure to the multistore.
@@ -329,7 +329,7 @@ class _MultiStore(object):
if self._read_only:
return
self._file.file_handle().seek(0)
simplejson.dump(data, self._file.file_handle(), sort_keys=True, indent=2)
json.dump(data, self._file.file_handle(), sort_keys=True, indent=2)
self._file.file_handle().truncate()
def _refresh_data_cache(self):
@@ -387,7 +387,7 @@ class _MultiStore(object):
raw_key = cred_entry['key']
key = util.dict_to_tuple_key(raw_key)
credential = None
credential = Credentials.new_from_json(simplejson.dumps(cred_entry['credential']))
credential = Credentials.new_from_json(json.dumps(cred_entry['credential']))
return (key, credential)
def _write(self):
@@ -400,7 +400,7 @@ class _MultiStore(object):
raw_data['data'] = raw_creds
for (cred_key, cred) in self._data.items():
raw_key = dict(cred_key)
raw_cred = simplejson.loads(cred.to_json())
raw_cred = json.loads(cred.to_json())
raw_creds.append({'key': raw_key, 'credential': raw_cred})
self._locked_json_write(raw_data)

View File

@@ -18,6 +18,7 @@ This credentials class is implemented on top of rsa library.
"""
import base64
import json
import rsa
import time
import types
@@ -25,7 +26,6 @@ import types
from oauth2client import GOOGLE_REVOKE_URI
from oauth2client import GOOGLE_TOKEN_URI
from oauth2client import util
from oauth2client.anyjson import simplejson
from oauth2client.client import AssertionCredentials
from pyasn1.codec.ber import decoder
@@ -43,7 +43,7 @@ class _ServiceAccountCredentials(AssertionCredentials):
super(_ServiceAccountCredentials, self).__init__(
None, user_agent=user_agent, token_uri=token_uri, revoke_uri=revoke_uri)
self._service_account_id = service_account_id
self._service_account_email = service_account_email
self._private_key_id = private_key_id
@@ -118,8 +118,7 @@ class _ServiceAccountCredentials(AssertionCredentials):
def _urlsafe_b64encode(data):
return base64.urlsafe_b64encode(
simplejson.dumps(data, separators = (',', ':'))\
.encode('UTF-8')).rstrip('=')
json.dumps(data, separators=(',', ':')).encode('UTF-8')).rstrip('=')
def _get_private_key(private_key_pkcs8_text):
"""Get an RSA private key object from a pkcs8 representation."""

View File

@@ -17,6 +17,14 @@
Also installs included versions of third party libraries, if those libraries
are not already installed.
"""
from __future__ import print_function
import sys
if sys.version_info <= (2, 6):
print('oauth2client requires python version >= 2.6.', file=sys.stderr)
sys.exit(1)
from setuptools import setup
packages = [
@@ -31,18 +39,6 @@ install_requires = [
'rsa==3.1.4',
]
needs_json = False
try:
import json
except ImportError:
try:
import simplejson
except ImportError:
needs_json = True
if needs_json:
install_requires.append('simplejson')
long_desc = """The oauth2client is a client library for OAuth 2.0."""
import oauth2client

View File

@@ -14,9 +14,9 @@
"""Copy of googleapiclient.http's mock functionality."""
import httplib2
import json
from oauth2client.anyjson import simplejson
import httplib2
# TODO(craigcitro): Find a cleaner way to share this code with googleapiclient.
@@ -101,7 +101,7 @@ class HttpMockSequence(object):
if content == 'echo_request_headers':
content = headers
elif content == 'echo_request_headers_as_json':
content = simplejson.dumps(headers)
content = json.dumps(headers)
elif content == 'echo_request_body':
if hasattr(body, 'read'):
content = body.read()

View File

@@ -25,6 +25,7 @@ __author__ = 'jcgregorio@google.com (Joe Gregorio)'
import base64
import datetime
import httplib2
import json
import mox
import os
import time
@@ -53,7 +54,6 @@ from google.appengine.runtime import apiproxy_errors
from http_mock import HttpMockSequence
from oauth2client import appengine
from oauth2client import GOOGLE_TOKEN_URI
from oauth2client.anyjson import simplejson
from oauth2client.clientsecrets import _loadfile
from oauth2client.clientsecrets import InvalidClientSecretsError
from oauth2client.appengine import AppAssertionCredentials
@@ -128,7 +128,7 @@ class Http2Mock(object):
def request(self, token_uri, method, body, headers, *args, **kwargs):
self.body = body
self.headers = headers
return (self, simplejson.dumps(self.content))
return (self, json.dumps(self.content))
class TestAppAssertionCredentials(unittest.TestCase):
@@ -309,7 +309,7 @@ class FlowNDBPropertyTest(unittest.TestCase):
def _http_request(*args, **kwargs):
resp = httplib2.Response({'status': '200'})
content = simplejson.dumps({'access_token': 'bar'})
content = json.dumps({'access_token': 'bar'})
return resp, content
@@ -584,8 +584,7 @@ class DecoratorTests(unittest.TestCase):
self.assertEqual(None, self.decorator.credentials)
if self.decorator._token_response_param:
response = parse_qs(parts[1])[self.decorator._token_response_param][0]
self.assertEqual(Http2Mock.content,
simplejson.loads(urllib.unquote(response)))
self.assertEqual(Http2Mock.content, json.loads(urllib.unquote(response)))
self.assertEqual(self.decorator.flow, self.decorator._tls.flow)
self.assertEqual(self.decorator.credentials,
self.decorator._tls.credentials)

View File

@@ -25,6 +25,7 @@ __author__ = 'jcgregorio@google.com (Joe Gregorio)'
import copy
import datetime
import httplib2
import json
import os
import pickle
import stat
@@ -37,7 +38,6 @@ from oauth2client import file
from oauth2client import locked_file
from oauth2client import multistore_file
from oauth2client import util
from oauth2client.anyjson import simplejson
from oauth2client.client import AccessTokenCredentials
from oauth2client.client import AssertionCredentials
from oauth2client.client import OAuth2Credentials
@@ -108,9 +108,8 @@ class OAuth2ClientFileTests(unittest.TestCase):
# Now write it back out and confirm it has been rewritten as JSON
s.put(credentials)
f = open(FILENAME)
data = simplejson.load(f)
f.close()
with open(FILENAME) as f:
data = json.load(f)
self.assertEquals(data['access_token'], 'foo')
self.assertEquals(data['_class'], 'OAuth2Credentials')

View File

@@ -37,7 +37,6 @@ except ImportError:
from http_mock import HttpMockSequence
from oauth2client import crypt
from oauth2client.anyjson import simplejson
from oauth2client.client import Credentials
from oauth2client.client import SignedJwtAssertionCredentials
from oauth2client.client import VerifyJwtTokenError

View File

@@ -24,6 +24,7 @@ __author__ = 'jcgregorio@google.com (Joe Gregorio)'
import base64
import datetime
import json
import mox
import os
import time
@@ -34,7 +35,6 @@ from http_mock import HttpMock
from http_mock import HttpMockSequence
from oauth2client import GOOGLE_REVOKE_URI
from oauth2client import GOOGLE_TOKEN_URI
from oauth2client.anyjson import simplejson
from oauth2client.client import AccessTokenCredentials
from oauth2client.client import AccessTokenCredentialsError
from oauth2client.client import AccessTokenRefreshError
@@ -277,7 +277,7 @@ class GoogleCredentialsTests(unittest.TestCase):
os.path.join('gcloud', 'temp_well_known_file_service_account.json'))
save_to_well_known_file(credentials, temp_credential_file)
with open(temp_credential_file) as f:
d = simplejson.load(f)
d = json.load(f)
self.assertEqual('service_account', d['type'])
self.assertEqual('123', d['client_id'])
self.assertEqual('dummy@google.com', d['client_email'])
@@ -302,7 +302,7 @@ class GoogleCredentialsTests(unittest.TestCase):
os.path.join('gcloud', 'temp_well_known_file_authorized_user.json'))
save_to_well_known_file(credentials, temp_credential_file)
with open(temp_credential_file) as f:
d = simplejson.load(f)
d = json.load(f)
self.assertEqual('authorized_user', d['type'])
self.assertEqual('123', d['client_id'])
self.assertEqual('secret', d['client_secret'])
@@ -541,7 +541,7 @@ class BasicCredentialsTests(unittest.TestCase):
token_response = {'access_token': '1/3w', 'expires_in': 3600}
http = HttpMockSequence([
({'status': status_code}, ''),
({'status': '200'}, simplejson.dumps(token_response)),
({'status': '200'}, json.dumps(token_response)),
({'status': '200'}, 'echo_request_headers'),
])
http = self.credentials.authorize(http)
@@ -630,8 +630,8 @@ class BasicCredentialsTests(unittest.TestCase):
token_response_first = {'access_token': 'first_token', 'expires_in': S}
token_response_second = {'access_token': 'second_token', 'expires_in': S}
http = HttpMockSequence([
({'status': '200'}, simplejson.dumps(token_response_first)),
({'status': '200'}, simplejson.dumps(token_response_second)),
({'status': '200'}, json.dumps(token_response_first)),
({'status': '200'}, json.dumps(token_response_second)),
])
token = self.credentials.get_access_token(http=http)
@@ -763,7 +763,7 @@ class ExtractIdTokenTest(unittest.TestCase):
def test_extract_success(self):
body = {'foo': 'bar'}
payload = base64.urlsafe_b64encode(simplejson.dumps(body)).strip('=')
payload = base64.urlsafe_b64encode(json.dumps(body)).strip('=')
jwt = 'stuff.' + payload + '.signature'
extracted = _extract_id_token(jwt)
@@ -771,7 +771,7 @@ class ExtractIdTokenTest(unittest.TestCase):
def test_extract_failure(self):
body = {'foo': 'bar'}
payload = base64.urlsafe_b64encode(simplejson.dumps(body)).strip('=')
payload = base64.urlsafe_b64encode(json.dumps(body)).strip('=')
jwt = 'stuff.' + payload
self.assertRaises(VerifyJwtTokenError, _extract_id_token, jwt)
@@ -938,7 +938,7 @@ class OAuth2WebServerFlowTest(unittest.TestCase):
def test_exchange_id_token(self):
body = {'foo': 'bar'}
payload = base64.urlsafe_b64encode(simplejson.dumps(body)).strip('=')
payload = base64.urlsafe_b64encode(json.dumps(body)).strip('=')
jwt = (base64.urlsafe_b64encode('stuff')+ '.' + payload + '.' +
base64.urlsafe_b64encode('signature'))
@@ -973,7 +973,7 @@ class CredentialsFromCodeTests(unittest.TestCase):
def test_exchange_code_for_token(self):
token = 'asdfghjkl'
payload =simplejson.dumps({'access_token': token, 'expires_in': 3600})
payload = json.dumps({'access_token': token, 'expires_in': 3600})
http = HttpMockSequence([
({'status': '200'}, payload),
])

View File

@@ -20,13 +20,13 @@
Unit tests for service account credentials implemented using RSA.
"""
import json
import os
import rsa
import time
import unittest
from http_mock import HttpMockSequence
from oauth2client.anyjson import simplejson
from oauth2client.service_account import _ServiceAccountCredentials
@@ -98,13 +98,13 @@ class ServiceAccountCredentialsTests(unittest.TestCase):
token_response_first = {'access_token': 'first_token', 'expires_in': S}
token_response_second = {'access_token': 'second_token', 'expires_in': S}
http = HttpMockSequence([
({'status': '200'}, simplejson.dumps(token_response_first)),
({'status': '200'}, simplejson.dumps(token_response_second)),
({'status': '200'}, json.dumps(token_response_first)),
({'status': '200'}, json.dumps(token_response_second)),
])
token = self.credentials.get_access_token(http=http)
self.assertEqual('first_token', token.access_token)
self.assertEqual(S - 1, token.expires_in)
self.assertEqual(S - 1, token.expires_in)
self.assertFalse(self.credentials.access_token_expired)
self.assertEqual(token_response_first, self.credentials.token_response)