Skip to content

Commit 252d532

Browse files
committed
Merge pull request #1510 from dhermes/fix-1412
Allowing credentials that don't implement create_scoped().
2 parents 3cc6571 + 1064889 commit 252d532

6 files changed

Lines changed: 47 additions & 44 deletions

File tree

gcloud/bigtable/client.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,11 @@ def __init__(self, project=None, credentials=None,
144144
scopes.append(ADMIN_SCOPE)
145145

146146
self._admin = bool(admin)
147-
self._credentials = credentials.create_scoped(scopes)
147+
try:
148+
credentials = credentials.create_scoped(scopes)
149+
except AttributeError:
150+
pass
151+
self._credentials = credentials
148152
self.user_agent = user_agent
149153
self.timeout_seconds = timeout_seconds
150154

gcloud/bigtable/test_client.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ def _constructor_test_helper(self, expected_scopes, creds,
4141

4242
expected_creds = expected_creds or creds
4343
self.assertTrue(client._credentials is expected_creds)
44-
self.assertEqual(client._credentials.scopes, expected_scopes)
44+
if expected_scopes is not None:
45+
self.assertEqual(client._credentials.scopes, expected_scopes)
4546

4647
self.assertEqual(client.project, PROJECT)
4748
self.assertEqual(client.timeout_seconds, timeout_seconds)
@@ -90,7 +91,7 @@ def test_constructor_both_admin_and_read_only(self):
9091
self._constructor_test_helper([], creds, admin=True,
9192
read_only=True)
9293

93-
def test_constructor_implict_credentials(self):
94+
def test_constructor_implicit_credentials(self):
9495
from gcloud._testing import _Monkey
9596
from gcloud.bigtable import client as MUT
9697

@@ -104,6 +105,11 @@ def mock_get_credentials():
104105
self._constructor_test_helper(expected_scopes, None,
105106
expected_creds=creds)
106107

108+
def test_constructor_credentials_wo_create_scoped(self):
109+
creds = object()
110+
expected_scopes = None
111+
self._constructor_test_helper(expected_scopes, creds)
112+
107113
def _copy_test_helper(self, read_only=False, admin=False):
108114
credentials = _Credentials('value')
109115
project = 'PROJECT'

gcloud/connection.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,12 @@ def _create_scoped_credentials(credentials, scope):
115115
:class:`NoneType`
116116
:returns: A new credentials object that has a scope added (if needed).
117117
"""
118-
if credentials and credentials.create_scoped_required():
119-
credentials = credentials.create_scoped(scope)
118+
if credentials:
119+
try:
120+
if credentials.create_scoped_required():
121+
credentials = credentials.create_scoped(scope)
122+
except AttributeError:
123+
pass
120124
return credentials
121125

122126

gcloud/credentials.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
crypto = None
2828

2929
from oauth2client import client
30-
from oauth2client.client import _get_application_default_credential_from_file
3130
from oauth2client import crypt
3231
from oauth2client.service_account import ServiceAccountCredentials
3332
try:
@@ -125,11 +124,8 @@ def get_for_service_account_json(json_credentials_path, scope=None):
125124
:returns: New service account or Google (for a user JSON key file)
126125
credentials object.
127126
"""
128-
credentials = _get_application_default_credential_from_file(
129-
json_credentials_path)
130-
if scope is not None:
131-
credentials = credentials.create_scoped(scope)
132-
return credentials
127+
return ServiceAccountCredentials.from_json_keyfile_name(
128+
json_credentials_path, scopes=scope)
133129

134130

135131
def get_for_service_account_p12(client_email, private_key_path, scope=None):

gcloud/test_connection.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ def test_ctor_defaults(self):
3030

3131
def test_ctor_explicit(self):
3232
credentials = _Credentials()
33+
self.assertEqual(credentials._create_scoped_calls, 0)
3334
conn = self._makeOne(credentials)
35+
self.assertEqual(credentials._create_scoped_calls, 1)
3436
self.assertTrue(conn.credentials is credentials)
3537
self.assertEqual(conn._http, None)
3638

@@ -40,6 +42,12 @@ def test_ctor_explicit_http(self):
4042
self.assertEqual(conn.credentials, None)
4143
self.assertTrue(conn.http is http)
4244

45+
def test_ctor_credentials_wo_create_scoped(self):
46+
credentials = object()
47+
conn = self._makeOne(credentials)
48+
self.assertTrue(conn.credentials is credentials)
49+
self.assertEqual(conn._http, None)
50+
4351
def test_http_w_existing(self):
4452
conn = self._makeOne()
4553
conn._http = http = object()
@@ -371,11 +379,12 @@ class _Credentials(object):
371379

372380
def __init__(self, authorized=None):
373381
self._authorized = authorized
382+
self._create_scoped_calls = 0
374383

375384
def authorize(self, http):
376385
self._called_with = http
377386
return self._authorized
378387

379-
@staticmethod
380-
def create_scoped_required():
388+
def create_scoped_required(self):
389+
self._create_scoped_calls += 1
381390
return False

gcloud/test_credentials.py

Lines changed: 15 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -127,42 +127,26 @@ def test_it(self):
127127
from gcloud._testing import _Monkey
128128
from gcloud import credentials as MUT
129129

130-
CREDS = _Credentials()
131-
_filenames = []
132-
133-
def get_creds(filename):
134-
_filenames.append(filename)
135-
return CREDS
136-
137130
FILENAME = object()
131+
MOCK_CRED_CLASS = _MockServiceAccountCredentials()
132+
with _Monkey(MUT, ServiceAccountCredentials=MOCK_CRED_CLASS):
133+
result = self._callFUT(FILENAME)
138134

139-
renames = {'_get_application_default_credential_from_file': get_creds}
140-
with _Monkey(MUT, **renames):
141-
self._callFUT(FILENAME)
142-
143-
self.assertEqual(_filenames, [FILENAME])
144-
self.assertFalse(hasattr(CREDS, '_scopes'))
135+
self.assertEqual(result, MOCK_CRED_CLASS._result)
136+
self.assertEqual(MOCK_CRED_CLASS.json_called, [(FILENAME, None)])
145137

146138
def test_it_with_scope(self):
147139
from gcloud._testing import _Monkey
148140
from gcloud import credentials as MUT
149141

150-
CREDS = _Credentials()
151-
_filenames = []
152-
153-
def get_creds(filename):
154-
_filenames.append(filename)
155-
return CREDS
156-
157142
FILENAME = object()
158143
SCOPE = object()
144+
MOCK_CRED_CLASS = _MockServiceAccountCredentials()
145+
with _Monkey(MUT, ServiceAccountCredentials=MOCK_CRED_CLASS):
146+
result = self._callFUT(FILENAME, scope=SCOPE)
159147

160-
renames = {'_get_application_default_credential_from_file': get_creds}
161-
with _Monkey(MUT, **renames):
162-
self._callFUT(FILENAME, scope=SCOPE)
163-
164-
self.assertEqual(_filenames, [FILENAME])
165-
self.assertEqual(CREDS._scopes, SCOPE)
148+
self.assertEqual(result, MOCK_CRED_CLASS._result)
149+
self.assertEqual(MOCK_CRED_CLASS.json_called, [(FILENAME, SCOPE)])
166150

167151

168152
class Test_generate_signed_url(unittest2.TestCase):
@@ -604,13 +588,8 @@ def test_w_timedelta_days(self):
604588

605589

606590
class _Credentials(object):
607-
608591
service_account_name = 'testing@example.com'
609592

610-
def create_scoped(self, scopes):
611-
self._scopes = scopes
612-
return self
613-
614593

615594
class _Client(object):
616595

@@ -692,8 +671,13 @@ class _MockServiceAccountCredentials(object):
692671

693672
def __init__(self):
694673
self.p12_called = []
674+
self.json_called = []
695675
self._result = _Credentials()
696676

697677
def from_p12_keyfile(self, email, path, scopes=None):
698678
self.p12_called.append((email, path, scopes))
699679
return self._result
680+
681+
def from_json_keyfile_name(self, path, scopes=None):
682+
self.json_called.append((path, scopes))
683+
return self._result

0 commit comments

Comments
 (0)