diff --git a/oauth2client/anyjson.py b/oauth2client/anyjson.py deleted file mode 100644 index ae21c33..0000000 --- a/oauth2client/anyjson.py +++ /dev/null @@ -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 diff --git a/oauth2client/appengine.py b/oauth2client/appengine.py index 0aaa877..b284ad7 100644 --- a/oauth2client/appengine.py +++ b/oauth2client/appengine.py @@ -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) diff --git a/oauth2client/client.py b/oauth2client/client.py index 8b72156..648e22f 100644 --- a/oauth2client/client.py +++ b/oauth2client/client.py @@ -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 diff --git a/oauth2client/clientsecrets.py b/oauth2client/clientsecrets.py index ac99aae..ef958d9 100644 --- a/oauth2client/clientsecrets.py +++ b/oauth2client/clientsecrets.py @@ -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: diff --git a/oauth2client/crypt.py b/oauth2client/crypt.py index c70c95c..d0e48ef 100644 --- a/oauth2client/crypt.py +++ b/oauth2client/crypt.py @@ -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) diff --git a/oauth2client/file.py b/oauth2client/file.py index 1895f94..776c2a6 100644 --- a/oauth2client/file.py +++ b/oauth2client/file.py @@ -24,7 +24,6 @@ import os import stat import threading -from anyjson import simplejson from client import Storage as BaseStorage from client import Credentials diff --git a/oauth2client/gce.py b/oauth2client/gce.py index be8c528..509990e 100644 --- a/oauth2client/gce.py +++ b/oauth2client/gce.py @@ -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'] diff --git a/oauth2client/multistore_file.py b/oauth2client/multistore_file.py index ce7a519..a5bf6c9 100644 --- a/oauth2client/multistore_file.py +++ b/oauth2client/multistore_file.py @@ -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) diff --git a/oauth2client/service_account.py b/oauth2client/service_account.py index 6bd4bd1..feb5d33 100644 --- a/oauth2client/service_account.py +++ b/oauth2client/service_account.py @@ -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.""" diff --git a/setup.py b/setup.py index 4e738fa..f01f401 100644 --- a/setup.py +++ b/setup.py @@ -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 diff --git a/tests/http_mock.py b/tests/http_mock.py index cbf35a9..57b5f15 100644 --- a/tests/http_mock.py +++ b/tests/http_mock.py @@ -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() diff --git a/tests/test_appengine.py b/tests/test_appengine.py index 579b30f..40fde6f 100644 --- a/tests/test_appengine.py +++ b/tests/test_appengine.py @@ -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) diff --git a/tests/test_file.py b/tests/test_file.py index 1de82af..72f9e91 100644 --- a/tests/test_file.py +++ b/tests/test_file.py @@ -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') diff --git a/tests/test_jwt.py b/tests/test_jwt.py index 8b17fea..8b94d40 100644 --- a/tests/test_jwt.py +++ b/tests/test_jwt.py @@ -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 diff --git a/tests/test_oauth2client.py b/tests/test_oauth2client.py index a4b56fd..d4a5613 100644 --- a/tests/test_oauth2client.py +++ b/tests/test_oauth2client.py @@ -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), ]) diff --git a/tests/test_service_account.py b/tests/test_service_account.py index 56313d3..3a7bd3c 100644 --- a/tests/test_service_account.py +++ b/tests/test_service_account.py @@ -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)