-
Notifications
You must be signed in to change notification settings - Fork 345
Closed
Labels
🚨This issue needs some love.This issue needs some love.priority: p2Moderately-important priority. Fix may not be included in next release.Moderately-important priority. Fix may not be included in next release.type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.Error or flaw in code with unintended results or allowing sub-optimal usage patterns.
Description
Hi, I think I found a problem with google.auth.compute_engine.credentials.IDTokenCredentials. When the methods with_target_audience and then refresh are called, a TypeError: 'Signer' object is not callable is raised.
Environment details
- OS: Debian GNU/Linux 9 (stretch) (but I believe it does not depend on the os)
- Python version: 2.7/3.7
google-authversion: 1.6.3
Steps to reproduce
- have access either to dev shell or to a
vmshell - run
python
>>> import google.auth
>>> cred, _ = google.auth.default()
>>> cred
<google.auth.compute_engine.credentials.Credentials object at 0x7fcfb4612810>
>>> from google.auth.transport.requests import Request
>>> from google.auth.compute_engine.credentials import IDTokenCredentials
>>> id_credentials = IDTokenCredentials(Request(), None)
>>> id_credentials
<google.auth.compute_engine.credentials.IDTokenCredentials object at 0x7fcfb3dd4650>
>>> cred_with_audience = id_credentials.with_target_audience("some-existing-client-id") # client id has been removed, put an existing one
>>> cred_with_audience.refresh(Request())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python2.7/dist-packages/google/auth/compute_engine/credentials.py", line 217, in refresh
assertion = self._make_authorization_grant_assertion()
File "/usr/local/lib/python2.7/dist-packages/google/auth/compute_engine/credentials.py", line 211, in _make_authorization_grant_assertion
token = jwt.encode(self._signer, payload)
File "/usr/local/lib/python2.7/dist-packages/google/auth/jwt.py", line 97, in encode
signature = signer.sign(signing_input)
File "/usr/local/lib/python2.7/dist-packages/google/auth/iam.py", line 101, in sign
response = self._make_signing_request(message)
File "/usr/local/lib/python2.7/dist-packages/google/auth/iam.py", line 78, in _make_signing_request
self._credentials.before_request(self._request, method, url, headers)
File "/usr/local/lib/python2.7/dist-packages/google/auth/credentials.py", line 122, in before_request
self.refresh(request)
File "/usr/local/lib/python2.7/dist-packages/google/auth/compute_engine/credentials.py", line 96, in refresh
self._retrieve_info(request)
File "/usr/local/lib/python2.7/dist-packages/google/auth/compute_engine/credentials.py", line 78, in _retrieve_info
service_account=self._service_account_email)
File "/usr/local/lib/python2.7/dist-packages/google/auth/compute_engine/_metadata.py", line 186, in get_service_account_info
recursive=True)
File "/usr/local/lib/python2.7/dist-packages/google/auth/compute_engine/_metadata.py", line 122, in get
response = request(url=url, method='GET', headers=_METADATA_HEADERS)
TypeError: 'Signer' object is not callablePossible fix
I believe that the problem is in this line of code. When the copy of the credentials is created, the constructor of IDTokenCredentials is called and the self._signer is passed as first parameter instead of the Request object. That is why it fails with TypeError: 'Signer' object is not callable.
A possible clean solution could consist in adding signer as parameter to the constructor.
class IDTokenCredentials(credentials.Credentials, credentials.Signing):
"""Open ID Connect ID Token-based service account credentials.
These credentials relies on the default service account of a GCE instance.
In order for this to work, the GCE instance must have been started with
a service account that has access to the IAM Cloud API.
"""
def __init__(self, request, target_audience,
token_uri=_DEFAULT_TOKEN_URI,
additional_claims=None,
service_account_email=None,
signer = None):
"""
...
if signer is None:
signer = iam.Signer(
request=request,
credentials=Credentials(),
service_account_email=service_account_email)
self._signer = signer
...
def with_target_audience(self, target_audience):
"""Create a copy of these credentials with the specified target
audience.
Args:
target_audience (str): The intended audience for these credentials,
used when requesting the ID Token.
Returns:
google.auth.service_account.IDTokenCredentials: A new credentials
instance.
"""
return self.__class__(
Request(),
service_account_email=self._service_account_email,
token_uri=self._token_uri,
target_audience=target_audience,
additional_claims=self._additional_claims.copy(),
signer=self._signer)Metadata
Metadata
Assignees
Labels
🚨This issue needs some love.This issue needs some love.priority: p2Moderately-important priority. Fix may not be included in next release.Moderately-important priority. Fix may not be included in next release.type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.Error or flaw in code with unintended results or allowing sub-optimal usage patterns.