-
Notifications
You must be signed in to change notification settings - Fork 312
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: all asynchronous credential types required for all authentication types (service accounts, default... etc) #573
Conversation
Thanks for your pull request. It looks like this may be your first contribution to a Google open source project (if not, look below for help). Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). 📝 Please visit https://cla.developers.google.com/ to sign. Once you've signed (or fixed any issues), please reply here with What to do if you already signed the CLAIndividual signers
Corporate signers
ℹ️ Googlers: Go here for more info. |
google/auth/_default_async.py
Outdated
from google.auth import exceptions | ||
|
||
|
||
def _warn_about_problematic_credentials(credentials): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
extract to a helper to share?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed to extract from auth/_default
@@ -62,7 +63,10 @@ async def before_request(self, request, method, url, headers): | |||
# the http request.) | |||
|
|||
if not self.valid: | |||
self.refresh(request) | |||
if inspect.iscoroutinefunction(self.refresh): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is the scenario where this wouldn't be a coroutine?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are a couple of async credentials scenarios where self.refresh for those class instances return a None Type object (when it is not an async function). We run into this in an auth/jwt credentials object, and therefore add the check on whether refresh for that specific class instance is a coroutine or not.
from google.auth import jwt | ||
|
||
|
||
def encode(signer, payload, header=None, key_id=None): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The top level methods of this don't appear to be specific to async. If that is so, you can get them here with from google.auth.jwt import encode, _unverified_decode...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Made this change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Turns out that the jwt_async test file defines our async version of the jwt token, and then calls encode/decode etc with the token object, so the direct import of that form wouldn't account for a token.decode/token.encode statement. Is there another way I could do the import to make that type of logic work? The reasoning is that there could be external locations where these encode/decode etc methods are called on the async tokens, so I'm leaning towards the current approach to account for those cases.
google/oauth2/_client_async.py
Outdated
) | ||
|
||
""" | ||
except exceptions.TransportError as caught_exc: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
commented out code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Deleted.
google/oauth2/_client_async.py
Outdated
if hasattr(response_body1, "decode") | ||
else response_body1 | ||
) | ||
# CHANGE TO READ TO END OF STREAM |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Made this change as the approach to reading in the http response was modified, comment deleted.
error_code = response_data.get("error") or "" | ||
if ( | ||
any(e == "internal_failure" for e in (error_code, error_desc)) | ||
and retry < 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the condition for controlling the number of loops is pretty buried. I also think you may be able to use an existing retry helper for this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought about changing this logic but am wary of diverging from the sync implementation of the error handling as we would want both to behave the same for consistency (especially if a user does use both async and sync clients). I would like to further understand the reasoning for using an existing retry helper so we could clarify this in our next call.
tests_async/test__oauth2client.py
Outdated
import sys | ||
|
||
import mock | ||
import oauth2client.client |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't appear to be testing an async module, at least according to the naming. Is this a direct copy of what is in tests?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These do test the async _oauth2client internal to the auth library implementation. The other library that is imported is from https://github.com/googleapis/oauth2client, and the tests in this file test conversion between credentials from the oauth2client to the types of async credentials that we define in the auth library and that are added to this PR. Therefore, though these tests parallel those of the sync oauth2client, they use the async version and are as a result not a direct copy.
@@ -1,4 +1,4 @@ | |||
# Copyright 2016 Google LLC | |||
# Copyright 2020 Google LLC |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
similar, is this a test that is unique to async? If not we shouldn't duplicate it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These tests are unique to async, I changed the names of the test files so that this is clear. The import of credentials_async is renamed to credentials to make writing the tests shorter but we need to test the new async constructions.
google/auth/_default_async.py
Outdated
|
||
if credentials.client_id == _cloud_sdk.CLOUD_SDK_CLIENT_ID: | ||
warnings.warn(_default._CLOUD_SDK_CREDENTIALS_WARNING) | ||
return _default._warn_about_problematic_credentials(credentials) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
99% sure you can just import _warn_about_problematic credentials and not wrap it here, further reducing duplication.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense, made the modification to directly import and remove this method.
google/auth/_oauth2client_async.py
Outdated
"""Helpers for transitioning from oauth2client to google-auth. | ||
|
||
.. warning:: | ||
This module is private as it is intended to assist first-party downstream | ||
clients with the transition from oauth2client to google-auth. | ||
""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting, wasn't aware that oauth2client had been depricated - As long as this isn't used in any of the other internal libraries like resumable media it may make sense to remove it if it is not going to be used.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sgtm :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally looks good aside from issues already raised by @crwilcox
noxfile.py
Outdated
@@ -1,4 +1,4 @@ | |||
# Copyright 2019 Google LLC | |||
# Copyright 2020 Google LLC |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be reverted to 2019 since it's not a new file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed.
PR # 2 for AsyncIO Auth Library: