Skip to content
This repository has been archived by the owner on Nov 5, 2019. It is now read-only.

Implementing p12 support in ServiceAccountCredentials. #398

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion oauth2client/_openssl_crypt.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ def from_string(key_pem, is_x509_cert):
Raises:
OpenSSL.crypto.Error: if the key_pem can't be parsed.
"""
key_pem = _to_bytes(key_pem)
if is_x509_cert:
pubkey = crypto.load_certificate(crypto.FILETYPE_PEM, key_pem)
else:
Expand Down Expand Up @@ -112,7 +113,8 @@ def from_string(key, password=b'notasecret'):
Raises:
OpenSSL.crypto.Error if the key can't be parsed.
"""
parsed_pem_key = _parse_pem_key(_to_bytes(key))
key = _to_bytes(key)
parsed_pem_key = _parse_pem_key(key)
if parsed_pem_key:
pkey = crypto.load_privatekey(crypto.FILETYPE_PEM, parsed_pem_key)
else:
Expand Down
2 changes: 1 addition & 1 deletion oauth2client/_pycrypto_crypt.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ def from_string(key, password='notasecret'):
Raises:
NotImplementedError if the key isn't in PEM format.
"""
parsed_pem_key = _parse_pem_key(key)
parsed_pem_key = _parse_pem_key(_to_bytes(key))
if parsed_pem_key:
pkey = RSA.importKey(parsed_pem_key)
else:
Expand Down
59 changes: 29 additions & 30 deletions oauth2client/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -256,32 +256,37 @@ def apply(self, headers):
"""
_abstract()

def _to_json(self, strip):
def _to_json(self, strip, to_serialize=None):
"""Utility function that creates JSON repr. of a Credentials object.

Args:
strip: array, An array of names of members to not include in the
strip: array, An array of names of members to exclude from the
JSON.
to_serialize: dict, (Optional) The properties for this object
that will be serialized. This allows callers to modify
before serializing.

Returns:
string, a JSON representation of this instance, suitable to pass to
from_json().
"""
t = type(self)
d = copy.copy(self.__dict__)
curr_type = self.__class__
if to_serialize is None:
to_serialize = copy.copy(self.__dict__)
for member in strip:
if member in d:
del d[member]
d['token_expiry'] = _parse_expiry(d.get('token_expiry'))
# Add in information we will need later to reconsistitue this instance.
d['_class'] = t.__name__
d['_module'] = t.__module__
for key, val in d.items():
if member in to_serialize:
del to_serialize[member]
to_serialize['token_expiry'] = _parse_expiry(
to_serialize.get('token_expiry'))
# Add in information we will need later to reconstitute this instance.
to_serialize['_class'] = curr_type.__name__
to_serialize['_module'] = curr_type.__module__
for key, val in to_serialize.items():
if isinstance(val, bytes):
d[key] = val.decode('utf-8')
to_serialize[key] = val.decode('utf-8')
if isinstance(val, set):
d[key] = list(val)
return json.dumps(d)
to_serialize[key] = list(val)
return json.dumps(to_serialize)

def to_json(self):
"""Creating a JSON representation of an instance of Credentials.
Expand Down Expand Up @@ -1230,17 +1235,17 @@ def create_scoped(self, scopes):
return self

@classmethod
def from_json(cls, s):
def from_json(cls, json_data):
# TODO(issue 388): eliminate the circularity that is the reason for
# this non-top-level import.
from oauth2client.service_account import _ServiceAccountCredentials
data = json.loads(_from_bytes(s))
# this non-top-level import.
from oauth2client.service_account import ServiceAccountCredentials
data = json.loads(_from_bytes(json_data))

# We handle service_account._ServiceAccountCredentials since it is a
# We handle service_account.ServiceAccountCredentials since it is a
# possible return type of GoogleCredentials.get_application_default()
if (data['_module'] == 'oauth2client.service_account' and
data['_class'] == '_ServiceAccountCredentials'):
return _ServiceAccountCredentials.from_json(s)
data['_class'] == 'ServiceAccountCredentials'):
return ServiceAccountCredentials.from_json(data)

token_expiry = _parse_expiry(data.get('token_expiry'))
google_credentials = cls(
Expand Down Expand Up @@ -1490,9 +1495,6 @@ def _get_well_known_file():

def _get_application_default_credential_from_file(filename):
"""Build the Application Default Credentials from file."""

from oauth2client import service_account

# read the credentials from the file
with open(filename) as file_obj:
client_credentials = json.load(file_obj)
Expand Down Expand Up @@ -1523,12 +1525,9 @@ def _get_application_default_credential_from_file(filename):
token_uri=GOOGLE_TOKEN_URI,
user_agent='Python client library')
else: # client_credentials['type'] == SERVICE_ACCOUNT
return service_account._ServiceAccountCredentials(
service_account_id=client_credentials['client_id'],
service_account_email=client_credentials['client_email'],
private_key_id=client_credentials['private_key_id'],
private_key_pkcs8_text=client_credentials['private_key'],
scopes=[])
from oauth2client.service_account import ServiceAccountCredentials
return ServiceAccountCredentials.from_json_keyfile_dict(
client_credentials)


def _raise_exception_for_missing_fields(missing_fields):
Expand Down
Loading