Skip to content

Commit cae69d5

Browse files
bojeil-googlebusunkim96tseaverarithmetic1728release-please[bot]
authored
chore: sync to master (#628)
* refactor: split 'with_quota_project' into separate base class (#561) Co-authored-by: Tres Seaver <[email protected]> * fix: dummy commit to trigger a auto release (#597) * chore: release 1.21.1 (#599) * chore: updated CHANGELOG.md [ci skip] * chore: updated setup.cfg [ci skip] * chore: updated setup.py Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> * fix: migrate signBlob to iamcredentials.googleapis.com (#600) Migrate signBlob from iam.googleapis.com to iamcredentials.googleapis.com. This API is deprecated and will be shutdown in one year. This is used google.auth.iam.Signer. Added a system_test to sanity check the implementation. * chore: release 1.21.2 (#601) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> * fix: fix expiry for `to_json()` (#589) * This patch for </issues/501> includes the following fixes: - The access token is always set to `None`, so the fix involves using (the access) `token` from the saved JSON credentials file. - For refresh needs, `expiry` also needs to be saved via `to_json()`. - DUMP: As `expiry` is a `datetime.datetime` object, serialize to `datetime.isoformat()` in the same [`oauth2client` format](https://github.com/googleapis/oauth2client/blob/master/oauth2client/client.py#L55) for consistency. - LOAD: Add code to restore `expiry` back to `datetime.datetime` object when imported. - LOAD: If `expiry` was unsaved, automatically set it as expired so refresh takes place. - Minor `scopes` updates - DUMP: Add property for `scopes` so `to_json()` can grab it - LOAD: `scopes` may be saved as a string instead of a JSON array (Python list), so ensure it is Sequence[str] when imported. * chore: add default CODEOWNERS (#609) * chore: release 1.21.3 (#607) * feat: add asyncio based auth flow (#612) * feat: asyncio http request logic and asynchronous credentials logic (#572) Co-authored-by: Anirudh Baddepudi <[email protected]> * chore: release 1.22.0 (#615) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> * fix: move aiohttp to extra as it is currently internal surface (#619) Fix #618. Removes aiohttp from required dependencies to lessen dependency tree for google-auth. This will need to be looked at again as more folks use aiohttp and once the surfaces goes to public visibility. * chore: release 1.22.1 (#620) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> * fix: remove checks for ancient versions of Cryptography (#596) Refs #595 (comment) I see no point in checking whether someone is running a version of https://github.com/pyca/cryptography/ from 2014 that doesn't even compile against modern versions of OpenSSL anymore. * chore: sync to master Syncs to master. Fixes broken unit tests in Python 3.6 and 3.7. Aligns test_identity_pool.py with test_aws.py. Co-authored-by: Bu Sun Kim <[email protected]> Co-authored-by: Tres Seaver <[email protected]> Co-authored-by: arithmetic1728 <[email protected]> Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> Co-authored-by: wesley chun <[email protected]> Co-authored-by: Christopher Wilcox <[email protected]> Co-authored-by: Anirudh Baddepudi <[email protected]> Co-authored-by: Aarni Koskela <[email protected]>
1 parent a57aba9 commit cae69d5

File tree

3 files changed

+39
-36
lines changed

3 files changed

+39
-36
lines changed

noxfile.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
"grpcio",
3131
]
3232

33-
ASYNC_DEPENDENCIES = ["pytest-asyncio", "aioresponses"]
33+
ASYNC_DEPENDENCIES = ["pytest-asyncio", "aioresponses", "asynctest"]
3434

3535
BLACK_VERSION = "black==19.3b0"
3636
BLACK_PATHS = [
@@ -64,9 +64,7 @@ def lint(session):
6464
@nox.session(python="3.6")
6565
def blacken(session):
6666
"""Run black.
67-
6867
Format code to uniform standard.
69-
7068
This currently uses Python 3.6 due to the automated Kokoro run of synthtool.
7169
That run uses an image that doesn't have 3.6 installed. Before updating this
7270
check the state of the `gcp_ubuntu_config` we use for that Kokoro run.

setup.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,13 @@
2020

2121
DEPENDENCIES = (
2222
"cachetools>=2.0.0,<5.0",
23-
'enum34; python_version < "3.4"',
2423
"pyasn1-modules>=0.2.1",
2524
# rsa==4.5 is the last version to support 2.7
2625
# https://github.com/sybrenstuvel/python-rsa/issues/152#issuecomment-643470233
2726
'rsa<4.6; python_version < "3.5"',
2827
'rsa>=3.1.4,<5; python_version >= "3.5"',
2928
"setuptools>=40.3.0",
3029
"six>=1.9.0",
31-
'aiohttp >= 3.6.2, < 4.0.0dev; python_version>="3.6"',
3230
)
3331

3432
extras = {"aiohttp": "aiohttp >= 3.6.2, < 4.0.0dev; python_version>='3.6'"}

tests/test_identity_pool.py

Lines changed: 38 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -72,19 +72,20 @@ class TestCredentials(object):
7272
@classmethod
7373
def make_mock_request(
7474
cls,
75-
data,
76-
status=http_client.OK,
77-
impersonation_data=None,
75+
token_status=http_client.OK,
76+
token_data=None,
7877
impersonation_status=None,
78+
impersonation_data=None,
7979
):
80+
responses = []
8081
# STS token exchange request.
8182
token_response = mock.create_autospec(transport.Response, instance=True)
82-
token_response.status = status
83-
token_response.data = json.dumps(data).encode("utf-8")
84-
responses = [token_response]
83+
token_response.status = token_status
84+
token_response.data = json.dumps(token_data).encode("utf-8")
85+
responses.append(token_response)
8586

8687
# If service account impersonation is requested, mock the expected response.
87-
if impersonation_status and impersonation_status:
88+
if impersonation_status:
8889
impersonation_response = mock.create_autospec(
8990
transport.Response, instance=True
9091
)
@@ -169,8 +170,6 @@ def assert_underlying_credentials_refresh(
169170
"subject_token": subject_token,
170171
"subject_token_type": subject_token_type,
171172
}
172-
if token_scopes == "":
173-
token_request_data.pop("scope", None)
174173
# Service account impersonation request/response.
175174
impersonation_response = {
176175
"accessToken": "SA_ACCESS_TOKEN",
@@ -180,8 +179,6 @@ def assert_underlying_credentials_refresh(
180179
"Content-Type": "application/json",
181180
"authorization": "Bearer {}".format(token_response["access_token"]),
182181
}
183-
if quota_project_id:
184-
impersonation_headers["x-goog-user-project"] = quota_project_id
185182
impersonation_request_data = {
186183
"delegates": None,
187184
"scope": scopes,
@@ -190,8 +187,8 @@ def assert_underlying_credentials_refresh(
190187
# Initialize mock request to handle token exchange and service account
191188
# impersonation request.
192189
request = cls.make_mock_request(
193-
status=http_client.OK,
194-
data=token_response,
190+
token_status=http_client.OK,
191+
token_data=token_response,
195192
impersonation_status=impersonation_status,
196193
impersonation_data=impersonation_response,
197194
)
@@ -243,7 +240,8 @@ def make_credentials(
243240
scopes=scopes,
244241
)
245242

246-
def test_from_info_full_options(self):
243+
@mock.patch.object(identity_pool.Credentials, "__init__", return_value=None)
244+
def test_from_info_full_options(self, mock_init):
247245
credentials = identity_pool.Credentials.from_info(
248246
{
249247
"audience": AUDIENCE,
@@ -259,18 +257,19 @@ def test_from_info_full_options(self):
259257

260258
# Confirm identity_pool.Credentials instantiated with expected attributes.
261259
assert isinstance(credentials, identity_pool.Credentials)
262-
self.assert_underlying_credentials_refresh(
263-
credentials=credentials,
260+
mock_init.assert_called_once_with(
264261
audience=AUDIENCE,
265-
subject_token=TEXT_FILE_SUBJECT_TOKEN,
266262
subject_token_type=SUBJECT_TOKEN_TYPE,
267263
token_url=TOKEN_URL,
268264
service_account_impersonation_url=SERVICE_ACCOUNT_IMPERSONATION_URL,
269-
basic_auth_encoding=BASIC_AUTH_ENCODING,
265+
client_id=CLIENT_ID,
266+
client_secret=CLIENT_SECRET,
267+
credential_source=self.CREDENTIAL_SOURCE_TEXT,
270268
quota_project_id=QUOTA_PROJECT_ID,
271269
)
272270

273-
def test_from_info_required_options_only(self):
271+
@mock.patch.object(identity_pool.Credentials, "__init__", return_value=None)
272+
def test_from_info_required_options_only(self, mock_init):
274273
credentials = identity_pool.Credentials.from_info(
275274
{
276275
"audience": AUDIENCE,
@@ -282,15 +281,19 @@ def test_from_info_required_options_only(self):
282281

283282
# Confirm identity_pool.Credentials instantiated with expected attributes.
284283
assert isinstance(credentials, identity_pool.Credentials)
285-
self.assert_underlying_credentials_refresh(
286-
credentials=credentials,
284+
mock_init.assert_called_once_with(
287285
audience=AUDIENCE,
288-
subject_token=TEXT_FILE_SUBJECT_TOKEN,
289286
subject_token_type=SUBJECT_TOKEN_TYPE,
290287
token_url=TOKEN_URL,
288+
service_account_impersonation_url=None,
289+
client_id=None,
290+
client_secret=None,
291+
credential_source=self.CREDENTIAL_SOURCE_TEXT,
292+
quota_project_id=None,
291293
)
292294

293-
def test_from_file_full_options(self, tmpdir):
295+
@mock.patch.object(identity_pool.Credentials, "__init__", return_value=None)
296+
def test_from_file_full_options(self, mock_init, tmpdir):
294297
info = {
295298
"audience": AUDIENCE,
296299
"subject_token_type": SUBJECT_TOKEN_TYPE,
@@ -307,18 +310,19 @@ def test_from_file_full_options(self, tmpdir):
307310

308311
# Confirm identity_pool.Credentials instantiated with expected attributes.
309312
assert isinstance(credentials, identity_pool.Credentials)
310-
self.assert_underlying_credentials_refresh(
311-
credentials=credentials,
313+
mock_init.assert_called_once_with(
312314
audience=AUDIENCE,
313-
subject_token=TEXT_FILE_SUBJECT_TOKEN,
314315
subject_token_type=SUBJECT_TOKEN_TYPE,
315316
token_url=TOKEN_URL,
316317
service_account_impersonation_url=SERVICE_ACCOUNT_IMPERSONATION_URL,
317-
basic_auth_encoding=BASIC_AUTH_ENCODING,
318+
client_id=CLIENT_ID,
319+
client_secret=CLIENT_SECRET,
320+
credential_source=self.CREDENTIAL_SOURCE_TEXT,
318321
quota_project_id=QUOTA_PROJECT_ID,
319322
)
320323

321-
def test_from_file_required_options_only(self, tmpdir):
324+
@mock.patch.object(identity_pool.Credentials, "__init__", return_value=None)
325+
def test_from_file_required_options_only(self, mock_init, tmpdir):
322326
info = {
323327
"audience": AUDIENCE,
324328
"subject_token_type": SUBJECT_TOKEN_TYPE,
@@ -331,12 +335,15 @@ def test_from_file_required_options_only(self, tmpdir):
331335

332336
# Confirm identity_pool.Credentials instantiated with expected attributes.
333337
assert isinstance(credentials, identity_pool.Credentials)
334-
self.assert_underlying_credentials_refresh(
335-
credentials=credentials,
338+
mock_init.assert_called_once_with(
336339
audience=AUDIENCE,
337-
subject_token=TEXT_FILE_SUBJECT_TOKEN,
338340
subject_token_type=SUBJECT_TOKEN_TYPE,
339341
token_url=TOKEN_URL,
342+
service_account_impersonation_url=None,
343+
client_id=None,
344+
client_secret=None,
345+
credential_source=self.CREDENTIAL_SOURCE_TEXT,
346+
quota_project_id=None,
340347
)
341348

342349
def test_constructor_invalid_options(self):

0 commit comments

Comments
 (0)