Replace the 'default credentials' concept with the 'application default credentials' concept.

This commit is contained in:
Orest Bolohan
2014-07-11 13:09:18 -07:00
parent d02b317af0
commit df59cadb03
9 changed files with 176 additions and 148 deletions

View File

@@ -73,8 +73,9 @@ AUTHORIZED_USER = 'authorized_user'
# The value representing service account credentials. # The value representing service account credentials.
SERVICE_ACCOUNT = 'service_account' SERVICE_ACCOUNT = 'service_account'
# The environment variable pointing the file with local Default Credentials. # The environment variable pointing the file with local
GOOGLE_CREDENTIALS_DEFAULT = 'GOOGLE_CREDENTIALS_DEFAULT' # Application Default Credentials.
GOOGLE_APPLICATION_CREDENTIALS = 'GOOGLE_APPLICATION_CREDENTIALS'
# The access token along with the seconds in which it expires. # The access token along with the seconds in which it expires.
AccessTokenInfo = namedtuple('AccessTokenInfo', ['access_token', 'expires_in']) AccessTokenInfo = namedtuple('AccessTokenInfo', ['access_token', 'expires_in'])
@@ -111,8 +112,8 @@ class NonAsciiHeaderError(Error):
"""Header names and values must be ASCII strings.""" """Header names and values must be ASCII strings."""
class DefaultCredentialsError(Error): class ApplicationDefaultCredentialsError(Error):
"""Error retrieving the Default Credentials.""" """Error retrieving the Application Default Credentials."""
def _abstract(): def _abstract():
@@ -903,14 +904,15 @@ def _get_environment(urllib2_urlopen=None):
class GoogleCredentials(OAuth2Credentials): class GoogleCredentials(OAuth2Credentials):
"""Default credentials for use in calling Google APIs. """Application Default Credentials for use in calling Google APIs.
The Default Credentials are being constructed as a function of the environment The Application Default Credentials are being constructed as a function of
where the code is being run. More details can be found on this page: the environment where the code is being run.
https://developers.google.com/accounts/docs/default-credentials More details can be found on this page:
https://developers.google.com/accounts/docs/application-default-credentials
Here is an example of how to use the Default Credentials for a service that Here is an example of how to use the Application Default Credentials for a
requires authentication: service that requires authentication:
<code> <code>
from googleapiclient.discovery import build from googleapiclient.discovery import build
@@ -919,7 +921,8 @@ class GoogleCredentials(OAuth2Credentials):
PROJECT = 'bamboo-machine-422' # replace this with one of your projects PROJECT = 'bamboo-machine-422' # replace this with one of your projects
ZONE = 'us-central1-a' # replace this with the zone you care about ZONE = 'us-central1-a' # replace this with the zone you care about
service = build('compute', 'v1', credentials=GoogleCredentials.get_default()) credentials = GoogleCredentials.get_application_default()
service = build('compute', 'v1', credentials=credentials)
request = service.instances().list(project=PROJECT, zone=ZONE) request = service.instances().list(project=PROJECT, zone=ZONE)
response = request.execute() response = request.execute()
@@ -949,7 +952,8 @@ class GoogleCredentials(OAuth2Credentials):
This constructor is not usually called by the user, instead This constructor is not usually called by the user, instead
GoogleCredentials objects are instantiated by GoogleCredentials objects are instantiated by
GoogleCredentials.from_stream() or GoogleCredentials.get_default(). GoogleCredentials.from_stream() or
GoogleCredentials.get_application_default().
Args: Args:
access_token: string, access token. access_token: string, access token.
@@ -982,11 +986,12 @@ class GoogleCredentials(OAuth2Credentials):
return self return self
@staticmethod @staticmethod
def get_default(): def get_application_default():
"""Get the Default Credentials for the current environment. """Get the Application Default Credentials for the current environment.
Exceptions: Exceptions:
DefaultCredentialsError: raised when the credentials fail to be retrieved. ApplicationDefaultCredentialsError: raised when the credentials fail
to be retrieved.
""" """
_env_name = _get_environment() _env_name = _get_environment()
@@ -994,41 +999,40 @@ class GoogleCredentials(OAuth2Credentials):
if _env_name in ('GAE_PRODUCTION', 'GAE_LOCAL'): if _env_name in ('GAE_PRODUCTION', 'GAE_LOCAL'):
# if we are running inside Google App Engine # if we are running inside Google App Engine
# there is no need to look for credentials in local files # there is no need to look for credentials in local files
default_credential_filename = None application_default_credential_filename = None
well_known_file = None well_known_file = None
else: else:
default_credential_filename = _get_environment_variable_file() application_default_credential_filename = _get_environment_variable_file()
well_known_file = _get_well_known_file() well_known_file = _get_well_known_file()
if default_credential_filename: if application_default_credential_filename:
try: try:
return _get_default_credential_from_file(default_credential_filename) return _get_application_default_credential_from_file(
except (DefaultCredentialsError, ValueError) as error: application_default_credential_filename)
extra_help = (' (pointed to by ' + GOOGLE_CREDENTIALS_DEFAULT + except (ApplicationDefaultCredentialsError, ValueError) as error:
extra_help = (' (pointed to by ' + GOOGLE_APPLICATION_CREDENTIALS +
' environment variable)') ' environment variable)')
_raise_exception_for_reading_json(default_credential_filename, _raise_exception_for_reading_json(
extra_help, error) application_default_credential_filename, extra_help, error)
elif well_known_file: elif well_known_file:
try: try:
return _get_default_credential_from_file(well_known_file) return _get_application_default_credential_from_file(well_known_file)
except (DefaultCredentialsError, ValueError) as error: except (ApplicationDefaultCredentialsError, ValueError) as error:
extra_help = (' (produced automatically when running' extra_help = (' (produced automatically when running'
' "gcloud auth login" command)') ' "gcloud auth login" command)')
_raise_exception_for_reading_json(well_known_file, extra_help, error) _raise_exception_for_reading_json(well_known_file, extra_help, error)
elif _env_name in ('GAE_PRODUCTION', 'GAE_LOCAL'): elif _env_name in ('GAE_PRODUCTION', 'GAE_LOCAL'):
return _get_default_credential_GAE() return _get_application_default_credential_GAE()
elif _env_name == 'GCE_PRODUCTION': elif _env_name == 'GCE_PRODUCTION':
return _get_default_credential_GCE() return _get_application_default_credential_GCE()
else: else:
raise DefaultCredentialsError( raise ApplicationDefaultCredentialsError(
"The Default Credentials are not available. They are available if " "The Application Default Credentials are not available. They are "
"running in Google App Engine or Google Compute Engine. They are " "available if running in Google Compute Engine. Otherwise, the "
"also available if using the Google Cloud SDK and running 'gcloud " " environment variable " + GOOGLE_APPLICATION_CREDENTIALS +
"auth login'. Otherwise, the environment variable " + " must be defined pointing to a file defining the credentials. "
GOOGLE_CREDENTIALS_DEFAULT + " must be defined pointing to a file " "See https://developers.google.com/accounts/docs/application-default-"
"defining the credentials. " "credentials for more information.")
"See https://developers.google.com/accounts/docs/default-credentials "
"for details.")
@staticmethod @staticmethod
def from_stream(credential_filename): def from_stream(credential_filename):
@@ -1041,33 +1045,38 @@ class GoogleCredentials(OAuth2Credentials):
are to be read are to be read
Exceptions: Exceptions:
DefaultCredentialsError: raised when the credentials fail to be retrieved. ApplicationDefaultCredentialsError: raised when the credentials fail
to be retrieved.
""" """
if credential_filename and os.path.isfile(credential_filename): if credential_filename and os.path.isfile(credential_filename):
try: try:
return _get_default_credential_from_file(credential_filename) return _get_application_default_credential_from_file(
except (DefaultCredentialsError, ValueError) as error: credential_filename)
except (ApplicationDefaultCredentialsError, ValueError) as error:
extra_help = ' (provided as parameter to the from_stream() method)' extra_help = ' (provided as parameter to the from_stream() method)'
_raise_exception_for_reading_json(credential_filename, _raise_exception_for_reading_json(credential_filename,
extra_help, extra_help,
error) error)
else: else:
raise DefaultCredentialsError('The parameter passed to the from_stream()' raise ApplicationDefaultCredentialsError(
' method should point to a file.') 'The parameter passed to the from_stream() '
'method should point to a file.')
def _get_environment_variable_file(): def _get_environment_variable_file():
default_credential_filename = os.environ.get(GOOGLE_CREDENTIALS_DEFAULT, application_default_credential_filename = (
None) os.environ.get(GOOGLE_APPLICATION_CREDENTIALS,
None))
if default_credential_filename: if application_default_credential_filename:
if os.path.isfile(default_credential_filename): if os.path.isfile(application_default_credential_filename):
return default_credential_filename return application_default_credential_filename
else: else:
raise DefaultCredentialsError( raise ApplicationDefaultCredentialsError(
'File ' + default_credential_filename + ' (pointed by ' + 'File ' + application_default_credential_filename + ' (pointed by ' +
GOOGLE_CREDENTIALS_DEFAULT + ' environment variable) does not exist!') GOOGLE_APPLICATION_CREDENTIALS +
' environment variable) does not exist!')
def _get_well_known_file(): def _get_well_known_file():
@@ -1075,7 +1084,7 @@ def _get_well_known_file():
# TODO(orestica): Revisit this method once gcloud provides a better way # TODO(orestica): Revisit this method once gcloud provides a better way
# of pinpointing the exact location of the file. # of pinpointing the exact location of the file.
WELL_KNOWN_CREDENTIALS_FILE = 'credentials_default.json' WELL_KNOWN_CREDENTIALS_FILE = 'application_default_credentials.json'
CLOUDSDK_CONFIG_DIRECTORY = 'gcloud' CLOUDSDK_CONFIG_DIRECTORY = 'gcloud'
if os.name == 'nt': if os.name == 'nt':
@@ -1098,14 +1107,17 @@ def _get_well_known_file():
return default_config_path return default_config_path
def _get_default_credential_from_file(default_credential_filename): def _get_application_default_credential_from_file(
"""Build the Default Credentials from file.""" application_default_credential_filename):
"""Build the Application Default Credentials from file."""
import service_account import service_account
# read the credentials from the file # read the credentials from the file
with open(default_credential_filename) as default_credential: with open(application_default_credential_filename) as (
client_credentials = service_account.simplejson.load(default_credential) application_default_credential):
client_credentials = service_account.simplejson.load(
application_default_credential)
credentials_type = client_credentials.get('type') credentials_type = client_credentials.get('type')
if credentials_type == AUTHORIZED_USER: if credentials_type == AUTHORIZED_USER:
@@ -1114,9 +1126,9 @@ def _get_default_credential_from_file(default_credential_filename):
required_fields = set(['client_id', 'client_email', 'private_key_id', required_fields = set(['client_id', 'client_email', 'private_key_id',
'private_key']) 'private_key'])
else: else:
raise DefaultCredentialsError("'type' field should be defined " raise ApplicationDefaultCredentialsError(
"(and have one of the '" + AUTHORIZED_USER + "'type' field should be defined (and have one of the '" +
"' or '" + SERVICE_ACCOUNT + "' values)") AUTHORIZED_USER + "' or '" + SERVICE_ACCOUNT + "' values)")
missing_fields = required_fields.difference(client_credentials.keys()) missing_fields = required_fields.difference(client_credentials.keys())
@@ -1142,25 +1154,25 @@ def _get_default_credential_from_file(default_credential_filename):
def _raise_exception_for_missing_fields(missing_fields): def _raise_exception_for_missing_fields(missing_fields):
raise DefaultCredentialsError('The following field(s): ' + raise ApplicationDefaultCredentialsError(
', '.join(missing_fields) + ' must be defined.') 'The following field(s) must be defined: ' + ', '.join(missing_fields))
def _raise_exception_for_reading_json(credential_file, def _raise_exception_for_reading_json(credential_file,
extra_help, extra_help,
error): error):
raise DefaultCredentialsError('An error was encountered while reading ' raise ApplicationDefaultCredentialsError(
'json file: '+ credential_file + extra_help + 'An error was encountered while reading json file: '+
': ' + str(error)) credential_file + extra_help + ': ' + str(error))
def _get_default_credential_GAE(): def _get_application_default_credential_GAE():
from oauth2client.appengine import AppAssertionCredentials from oauth2client.appengine import AppAssertionCredentials
return AppAssertionCredentials([]) return AppAssertionCredentials([])
def _get_default_credential_GCE(): def _get_application_default_credential_GCE():
from oauth2client.gce import AppAssertionCredentials from oauth2client.gce import AppAssertionCredentials
return AppAssertionCredentials([]) return AppAssertionCredentials([])

View File

@@ -1,13 +1,14 @@
# To be used to test GoogleCredential.GetDefaultCredential() # To be used to test GoogleCredentials.get_application_default()
# from local machine and GCE. # from local machine and GCE.
from googleapiclient.discovery import build from googleapiclient.discovery import build
from oauth2client.client import GoogleCredentials from oauth2client.client import GoogleCredentials
PROJECT = "bamboo-machine-422" # Provide your own GCE project here PROJECT = 'bamboo-machine-422' # Provide your own GCE project here
ZONE = "us-central1-a" # Put here a zone which has some VMs ZONE = 'us-central1-a' # Put here a zone which has some VMs
service = build("compute", "v1", credentials=GoogleCredentials.get_default()) credentials = GoogleCredentials.get_application_default()
service = build('compute', 'v1', credentials=credentials)
request = service.instances().list(project=PROJECT, zone=ZONE) request = service.instances().list(project=PROJECT, zone=ZONE)
response = request.execute() response = request.execute()

View File

@@ -1,15 +1,16 @@
# To be used to test GoogleCredential.GetDefaultCredential() # To be used to test GoogleCredentials.get_application_default()
# from devel GAE (ie, dev_appserver.py). # from devel GAE (ie, dev_appserver.py).
import webapp2 import webapp2
from googleapiclient.discovery import build from googleapiclient.discovery import build
from oauth2client.client import GoogleCredentials from oauth2client.client import GoogleCredentials
PROJECT = "bamboo-machine-422" # Provide your own GCE project here PROJECT = 'bamboo-machine-422' # Provide your own GCE project here
ZONE = "us-central1-a" # Put here a zone which has some VMs ZONE = 'us-central1-a' # Put here a zone which has some VMs
def get_instances(): def get_instances():
service = build("compute", "v1", credentials=GoogleCredentials.get_default()) credentials = GoogleCredentials.get_application_default()
service = build('compute', 'v1', credentials=credentials)
request = service.instances().list(project=PROJECT, zone=ZONE) request = service.instances().list(project=PROJECT, zone=ZONE)
return request.execute() return request.execute()

View File

@@ -41,10 +41,10 @@ from oauth2client.client import AccessTokenRefreshError
from oauth2client.client import AssertionCredentials from oauth2client.client import AssertionCredentials
from oauth2client.client import AUTHORIZED_USER from oauth2client.client import AUTHORIZED_USER
from oauth2client.client import Credentials from oauth2client.client import Credentials
from oauth2client.client import DefaultCredentialsError from oauth2client.client import ApplicationDefaultCredentialsError
from oauth2client.client import FlowExchangeError from oauth2client.client import FlowExchangeError
from oauth2client.client import GoogleCredentials from oauth2client.client import GoogleCredentials
from oauth2client.client import GOOGLE_CREDENTIALS_DEFAULT from oauth2client.client import GOOGLE_APPLICATION_CREDENTIALS
from oauth2client.client import MemoryCache from oauth2client.client import MemoryCache
from oauth2client.client import NonAsciiHeaderError from oauth2client.client import NonAsciiHeaderError
from oauth2client.client import OAuth2Credentials from oauth2client.client import OAuth2Credentials
@@ -57,7 +57,7 @@ from oauth2client.client import TokenRevokeError
from oauth2client.client import VerifyJwtTokenError from oauth2client.client import VerifyJwtTokenError
from oauth2client.client import _env_name from oauth2client.client import _env_name
from oauth2client.client import _extract_id_token from oauth2client.client import _extract_id_token
from oauth2client.client import _get_default_credential_from_file from oauth2client.client import _get_application_default_credential_from_file
from oauth2client.client import _get_environment from oauth2client.client import _get_environment
from oauth2client.client import _get_environment_variable_file from oauth2client.client import _get_environment_variable_file
from oauth2client.client import _get_well_known_file from oauth2client.client import _get_well_known_file
@@ -140,8 +140,8 @@ class GoogleCredentialsTests(unittest.TestCase):
def setUp(self): def setUp(self):
self.env_server_software = os.environ.get('SERVER_SOFTWARE', None) self.env_server_software = os.environ.get('SERVER_SOFTWARE', None)
self.env_google_credentials_default = ( self.env_google_application_credentials = (
os.environ.get(GOOGLE_CREDENTIALS_DEFAULT, None)) os.environ.get(GOOGLE_APPLICATION_CREDENTIALS, None))
self.env_appdata = os.environ.get('APPDATA', None) self.env_appdata = os.environ.get('APPDATA', None)
self.os_name = os.name self.os_name = os.name
from oauth2client import client from oauth2client import client
@@ -149,8 +149,8 @@ class GoogleCredentialsTests(unittest.TestCase):
def tearDown(self): def tearDown(self):
self.reset_env('SERVER_SOFTWARE', self.env_server_software) self.reset_env('SERVER_SOFTWARE', self.env_server_software)
self.reset_env(GOOGLE_CREDENTIALS_DEFAULT, self.reset_env(GOOGLE_APPLICATION_CREDENTIALS,
self.env_google_credentials_default) self.env_google_application_credentials)
self.reset_env('APPDATA', self.env_appdata) self.reset_env('APPDATA', self.env_appdata)
os.name = self.os_name os.name = self.os_name
@@ -235,27 +235,27 @@ class GoogleCredentialsTests(unittest.TestCase):
def test_get_environment_variable_file(self): def test_get_environment_variable_file(self):
environment_variable_file = datafile( environment_variable_file = datafile(
os.path.join('gcloud', 'credentials_default.json')) os.path.join('gcloud', 'application_default_credentials.json'))
os.environ[GOOGLE_CREDENTIALS_DEFAULT] = environment_variable_file os.environ[GOOGLE_APPLICATION_CREDENTIALS] = environment_variable_file
self.assertEqual(environment_variable_file, self.assertEqual(environment_variable_file,
_get_environment_variable_file()) _get_environment_variable_file())
def test_get_environment_variable_file_error(self): def test_get_environment_variable_file_error(self):
nonexistent_file = datafile('nonexistent') nonexistent_file = datafile('nonexistent')
os.environ[GOOGLE_CREDENTIALS_DEFAULT] = nonexistent_file os.environ[GOOGLE_APPLICATION_CREDENTIALS] = nonexistent_file
# we can't use self.assertRaisesRegexp() because it is only in Python 2.7+ # we can't use self.assertRaisesRegexp() because it is only in Python 2.7+
try: try:
_get_environment_variable_file() _get_environment_variable_file()
self.fail(nonexistent_file + ' should not exist.') self.fail(nonexistent_file + ' should not exist.')
except DefaultCredentialsError as error: except ApplicationDefaultCredentialsError as error:
self.assertEqual('File ' + nonexistent_file + self.assertEqual('File ' + nonexistent_file +
' (pointed by ' + GOOGLE_CREDENTIALS_DEFAULT + ' (pointed by ' + GOOGLE_APPLICATION_CREDENTIALS +
' environment variable) does not exist!', ' environment variable) does not exist!',
str(error)) str(error))
def test_get_well_known_file_on_windows(self): def test_get_well_known_file_on_windows(self):
well_known_file = datafile( well_known_file = datafile(
os.path.join('gcloud', 'credentials_default.json')) os.path.join('gcloud', 'application_default_credentials.json'))
os.name = 'nt' os.name = 'nt'
os.environ['APPDATA'] = DATA_DIR os.environ['APPDATA'] = DATA_DIR
self.assertEqual(well_known_file, _get_well_known_file()) self.assertEqual(well_known_file, _get_well_known_file())
@@ -265,47 +265,52 @@ class GoogleCredentialsTests(unittest.TestCase):
os.environ['APPDATA'] = os.path.join(DATA_DIR, 'nonexistentpath') os.environ['APPDATA'] = os.path.join(DATA_DIR, 'nonexistentpath')
self.assertEqual(None, _get_well_known_file()) self.assertEqual(None, _get_well_known_file())
def test_get_default_credential_from_file_service_account(self): def test_get_application_default_credential_from_file_service_account(self):
credentials_file = datafile( credentials_file = datafile(
os.path.join('gcloud', 'credentials_default.json')) os.path.join('gcloud', 'application_default_credentials.json'))
credentials = _get_default_credential_from_file(credentials_file) credentials = _get_application_default_credential_from_file(
credentials_file)
self.validate_service_account_credentials(credentials) self.validate_service_account_credentials(credentials)
def test_get_default_credential_from_file_authorized_user(self): def test_get_application_default_credential_from_file_authorized_user(self):
credentials_file = datafile( credentials_file = datafile(
os.path.join('gcloud', 'credentials_default_authorized_user.json')) os.path.join('gcloud',
credentials = _get_default_credential_from_file(credentials_file) 'application_default_credentials_authorized_user.json'))
credentials = _get_application_default_credential_from_file(
credentials_file)
self.validate_google_credentials(credentials) self.validate_google_credentials(credentials)
def test_get_default_credential_from_malformed_file_1(self): def test_get_application_default_credential_from_malformed_file_1(self):
credentials_file = datafile( credentials_file = datafile(
os.path.join('gcloud', 'credentials_default_malformed_1.json')) os.path.join('gcloud',
'application_default_credentials_malformed_1.json'))
# we can't use self.assertRaisesRegexp() because it is only in Python 2.7+ # we can't use self.assertRaisesRegexp() because it is only in Python 2.7+
try: try:
_get_default_credential_from_file(credentials_file) _get_application_default_credential_from_file(credentials_file)
self.fail('An exception was expected!') self.fail('An exception was expected!')
except DefaultCredentialsError as error: except ApplicationDefaultCredentialsError as error:
self.assertEqual("'type' field should be defined " self.assertEqual("'type' field should be defined "
"(and have one of the '" + AUTHORIZED_USER + "(and have one of the '" + AUTHORIZED_USER +
"' or '" + SERVICE_ACCOUNT + "' values)", "' or '" + SERVICE_ACCOUNT + "' values)",
str(error)) str(error))
def test_get_default_credential_from_malformed_file_2(self): def test_get_application_default_credential_from_malformed_file_2(self):
credentials_file = datafile( credentials_file = datafile(
os.path.join('gcloud', 'credentials_default_malformed_2.json')) os.path.join('gcloud',
'application_default_credentials_malformed_2.json'))
# we can't use self.assertRaisesRegexp() because it is only in Python 2.7+ # we can't use self.assertRaisesRegexp() because it is only in Python 2.7+
try: try:
_get_default_credential_from_file(credentials_file) _get_application_default_credential_from_file(credentials_file)
self.fail('An exception was expected!') self.fail('An exception was expected!')
except DefaultCredentialsError as error: except ApplicationDefaultCredentialsError as error:
self.assertEqual('The following field(s): ' self.assertEqual('The following field(s) must be defined: private_key_id',
'private_key_id must be defined.',
str(error)) str(error))
def test_get_default_credential_from_malformed_file_3(self): def test_get_application_default_credential_from_malformed_file_3(self):
credentials_file = datafile( credentials_file = datafile(
os.path.join('gcloud', 'credentials_default_malformed_3.json')) os.path.join('gcloud',
self.assertRaises(ValueError, _get_default_credential_from_file, 'application_default_credentials_malformed_3.json'))
self.assertRaises(ValueError, _get_application_default_credential_from_file,
credentials_file) credentials_file)
def test_raise_exception_for_missing_fields(self): def test_raise_exception_for_missing_fields(self):
@@ -314,105 +319,112 @@ class GoogleCredentialsTests(unittest.TestCase):
try: try:
_raise_exception_for_missing_fields(missing_fields) _raise_exception_for_missing_fields(missing_fields)
self.fail('An exception was expected!') self.fail('An exception was expected!')
except DefaultCredentialsError as error: except ApplicationDefaultCredentialsError as error:
self.assertEqual('The following field(s): ' + self.assertEqual('The following field(s) must be defined: ' +
', '.join(missing_fields) + ' must be defined.', ', '.join(missing_fields),
str(error)) str(error))
def test_raise_exception_for_reading_json(self): def test_raise_exception_for_reading_json(self):
credential_file = 'any_file' credential_file = 'any_file'
extra_help = ' be good' extra_help = ' be good'
error = DefaultCredentialsError('stuff happens') error = ApplicationDefaultCredentialsError('stuff happens')
# we can't use self.assertRaisesRegexp() because it is only in Python 2.7+ # we can't use self.assertRaisesRegexp() because it is only in Python 2.7+
try: try:
_raise_exception_for_reading_json(credential_file, extra_help, error) _raise_exception_for_reading_json(credential_file, extra_help, error)
self.fail('An exception was expected!') self.fail('An exception was expected!')
except DefaultCredentialsError as ex: except ApplicationDefaultCredentialsError as ex:
self.assertEqual('An error was encountered while reading ' self.assertEqual('An error was encountered while reading '
'json file: '+ credential_file + 'json file: '+ credential_file +
extra_help + ': ' + str(error), extra_help + ': ' + str(error),
str(ex)) str(ex))
def test_get_default_from_environment_variable_service_account(self): def test_get_application_default_from_environment_variable_service_account(
self):
os.environ['SERVER_SOFTWARE'] = '' os.environ['SERVER_SOFTWARE'] = ''
environment_variable_file = datafile( environment_variable_file = datafile(
os.path.join('gcloud', 'credentials_default.json')) os.path.join('gcloud', 'application_default_credentials.json'))
os.environ[GOOGLE_CREDENTIALS_DEFAULT] = environment_variable_file os.environ[GOOGLE_APPLICATION_CREDENTIALS] = environment_variable_file
self.validate_service_account_credentials(GoogleCredentials.get_default()) self.validate_service_account_credentials(
GoogleCredentials.get_application_default())
def test_env_name(self): def test_env_name(self):
from oauth2client import client from oauth2client import client
self.assertEqual(None, getattr(client, '_env_name')) self.assertEqual(None, getattr(client, '_env_name'))
self.test_get_default_from_environment_variable_service_account() self.test_get_application_default_from_environment_variable_service_account()
self.assertEqual('UNKNOWN', getattr(client, '_env_name')) self.assertEqual('UNKNOWN', getattr(client, '_env_name'))
def test_get_default_from_environment_variable_authorized_user(self): def test_get_application_default_from_environment_variable_authorized_user(
self):
os.environ['SERVER_SOFTWARE'] = '' os.environ['SERVER_SOFTWARE'] = ''
environment_variable_file = datafile( environment_variable_file = datafile(
os.path.join('gcloud', 'credentials_default_authorized_user.json')) os.path.join('gcloud',
os.environ[GOOGLE_CREDENTIALS_DEFAULT] = environment_variable_file 'application_default_credentials_authorized_user.json'))
self.validate_google_credentials(GoogleCredentials.get_default()) os.environ[GOOGLE_APPLICATION_CREDENTIALS] = environment_variable_file
self.validate_google_credentials(
GoogleCredentials.get_application_default())
def test_get_default_from_environment_variable_malformed_file(self): def test_get_application_default_from_environment_variable_malformed_file(
self):
os.environ['SERVER_SOFTWARE'] = '' os.environ['SERVER_SOFTWARE'] = ''
environment_variable_file = datafile( environment_variable_file = datafile(
os.path.join('gcloud', 'credentials_default_malformed_3.json')) os.path.join('gcloud',
os.environ[GOOGLE_CREDENTIALS_DEFAULT] = environment_variable_file 'application_default_credentials_malformed_3.json'))
os.environ[GOOGLE_APPLICATION_CREDENTIALS] = environment_variable_file
# we can't use self.assertRaisesRegexp() because it is only in Python 2.7+ # we can't use self.assertRaisesRegexp() because it is only in Python 2.7+
try: try:
GoogleCredentials.get_default() GoogleCredentials.get_application_default()
self.fail('An exception was expected!') self.fail('An exception was expected!')
except DefaultCredentialsError as error: except ApplicationDefaultCredentialsError as error:
self.assertTrue(str(error).startswith( self.assertTrue(str(error).startswith(
'An error was encountered while reading json file: ' + 'An error was encountered while reading json file: ' +
environment_variable_file + ' (pointed to by ' + environment_variable_file + ' (pointed to by ' +
GOOGLE_CREDENTIALS_DEFAULT + ' environment variable):')) GOOGLE_APPLICATION_CREDENTIALS + ' environment variable):'))
def test_get_default_environment_not_set_up(self): def test_get_application_default_environment_not_set_up(self):
# It is normal for this test to fail if run inside # It is normal for this test to fail if run inside
# a Google Compute Engine VM or after 'gcloud auth login' command # a Google Compute Engine VM or after 'gcloud auth login' command
# has been executed on a non Windows machine. # has been executed on a non Windows machine.
os.environ['SERVER_SOFTWARE'] = '' os.environ['SERVER_SOFTWARE'] = ''
os.environ[GOOGLE_CREDENTIALS_DEFAULT] = '' os.environ[GOOGLE_APPLICATION_CREDENTIALS] = ''
os.environ['APPDATA'] = '' os.environ['APPDATA'] = ''
# we can't use self.assertRaisesRegexp() because it is only in Python 2.7+ # we can't use self.assertRaisesRegexp() because it is only in Python 2.7+
try: try:
GoogleCredentials.get_default() GoogleCredentials.get_application_default()
self.fail('An exception was expected!') self.fail('An exception was expected!')
except DefaultCredentialsError as error: except ApplicationDefaultCredentialsError as error:
self.assertEqual("The Default Credentials are not available. They are " self.assertEqual(
"available if running in Google App Engine or Google " "The Application Default Credentials are not available. They are "
"Compute Engine. They are also available if using the " "available if running in Google Compute Engine. Otherwise, the "
"Google Cloud SDK and running 'gcloud auth login'. " " environment variable " + GOOGLE_APPLICATION_CREDENTIALS +
"Otherwise, the environment variable " + " must be defined pointing to a file defining the credentials. "
GOOGLE_CREDENTIALS_DEFAULT + " must be defined pointing " "See https://developers.google.com/accounts/docs/application-default-"
"to a file defining the credentials. See " "credentials for more information.",
"https://developers.google.com/accounts/docs/default-" str(error))
"credentials for details.",
str(error))
def test_from_stream_service_account(self): def test_from_stream_service_account(self):
credentials_file = datafile( credentials_file = datafile(
os.path.join('gcloud', 'credentials_default.json')) os.path.join('gcloud', 'application_default_credentials.json'))
credentials = ( credentials = (
self.get_a_google_credentials_object().from_stream(credentials_file)) self.get_a_google_credentials_object().from_stream(credentials_file))
self.validate_service_account_credentials(credentials) self.validate_service_account_credentials(credentials)
def test_from_stream_authorized_user(self): def test_from_stream_authorized_user(self):
credentials_file = datafile( credentials_file = datafile(
os.path.join('gcloud', 'credentials_default_authorized_user.json')) os.path.join('gcloud',
'application_default_credentials_authorized_user.json'))
credentials = ( credentials = (
self.get_a_google_credentials_object().from_stream(credentials_file)) self.get_a_google_credentials_object().from_stream(credentials_file))
self.validate_google_credentials(credentials) self.validate_google_credentials(credentials)
def test_from_stream_malformed_file_1(self): def test_from_stream_malformed_file_1(self):
credentials_file = datafile( credentials_file = datafile(
os.path.join('gcloud', 'credentials_default_malformed_1.json')) os.path.join('gcloud',
'application_default_credentials_malformed_1.json'))
# we can't use self.assertRaisesRegexp() because it is only in Python 2.7+ # we can't use self.assertRaisesRegexp() because it is only in Python 2.7+
try: try:
self.get_a_google_credentials_object().from_stream(credentials_file) self.get_a_google_credentials_object().from_stream(credentials_file)
self.fail('An exception was expected!') self.fail('An exception was expected!')
except DefaultCredentialsError as error: except ApplicationDefaultCredentialsError as error:
self.assertEqual("An error was encountered while reading json file: " + self.assertEqual("An error was encountered while reading json file: " +
credentials_file + credentials_file +
" (provided as parameter to the from_stream() method): " " (provided as parameter to the from_stream() method): "
@@ -423,24 +435,26 @@ class GoogleCredentialsTests(unittest.TestCase):
def test_from_stream_malformed_file_2(self): def test_from_stream_malformed_file_2(self):
credentials_file = datafile( credentials_file = datafile(
os.path.join('gcloud', 'credentials_default_malformed_2.json')) os.path.join('gcloud',
'application_default_credentials_malformed_2.json'))
# we can't use self.assertRaisesRegexp() because it is only in Python 2.7+ # we can't use self.assertRaisesRegexp() because it is only in Python 2.7+
try: try:
self.get_a_google_credentials_object().from_stream(credentials_file) self.get_a_google_credentials_object().from_stream(credentials_file)
self.fail('An exception was expected!') self.fail('An exception was expected!')
except DefaultCredentialsError as error: except ApplicationDefaultCredentialsError as error:
self.assertEqual('An error was encountered while reading json file: ' + self.assertEqual('An error was encountered while reading json file: ' +
credentials_file + credentials_file +
' (provided as parameter to the from_stream() method): ' ' (provided as parameter to the from_stream() method): '
'The following field(s): private_key_id must be ' 'The following field(s) must be defined: '
'defined.', 'private_key_id',
str(error)) str(error))
def test_from_stream_malformed_file_3(self): def test_from_stream_malformed_file_3(self):
credentials_file = datafile( credentials_file = datafile(
os.path.join('gcloud', 'credentials_default_malformed_3.json')) os.path.join('gcloud',
'application_default_credentials_malformed_3.json'))
self.assertRaises( self.assertRaises(
DefaultCredentialsError, ApplicationDefaultCredentialsError,
self.get_a_google_credentials_object().from_stream, credentials_file) self.get_a_google_credentials_object().from_stream, credentials_file)