Add jwt.Credentials.from_signing_credentials, remove serivce_account.Credentials.to_jwt_credentials (#120)
diff --git a/google/auth/jwt.py b/google/auth/jwt.py
index 087dbd9..7a9bdd5 100644
--- a/google/auth/jwt.py
+++ b/google/auth/jwt.py
@@ -47,8 +47,8 @@
from google.auth import _helpers
from google.auth import _service_account_info
-from google.auth import credentials
from google.auth import crypt
+import google.auth.credentials
_DEFAULT_TOKEN_LIFETIME_SECS = 3600 # 1 hour in sections
@@ -239,8 +239,8 @@
return payload
-class Credentials(credentials.Signing,
- credentials.Credentials):
+class Credentials(google.auth.credentials.Signing,
+ google.auth.credentials.Credentials):
"""Credentials that use a JWT as the bearer token.
These credentials require an "audience" claim. This claim identifies the
@@ -253,23 +253,24 @@
To create JWT credentials using a Google service account private key
JSON file::
+ audience = 'https://pubsub.googleapis.com/google.pubsub.v1.Publisher'
credentials = jwt.Credentials.from_service_account_file(
'service-account.json',
- audience='https://speech.googleapis.com')
+ audience=audience)
If you already have the service account file loaded and parsed::
service_account_info = json.load(open('service_account.json'))
credentials = jwt.Credentials.from_service_account_info(
service_account_info,
- audience='https://speech.googleapis.com')
+ audience=audience)
Both helper methods pass on arguments to the constructor, so you can
specify the JWT claims::
credentials = jwt.Credentials.from_service_account_file(
'service-account.json',
- audience='https://speech.googleapis.com',
+ audience=audience,
additional_claims={'meta': 'data'})
You can also construct the credentials directly if you have a
@@ -279,13 +280,14 @@
signer,
issuer='your-issuer',
subject='your-subject',
- audience=''https://speech.googleapis.com'')
+ audience=audience)
The claims are considered immutable. If you want to modify the claims,
you can easily create another instance using :meth:`with_claims`::
- new_credentials = credentials.with_claims(
- audience='https://vision.googleapis.com')
+ new_audience = (
+ 'https://pubsub.googleapis.com/google.pubsub.v1.Subscriber')
+ new_credentials = credentials.with_claims(audience=new_audience)
"""
def __init__(self, signer, issuer, subject, audience,
@@ -371,6 +373,41 @@
filename, require=['client_email'])
return cls._from_signer_and_info(signer, info, **kwargs)
+ @classmethod
+ def from_signing_credentials(cls, credentials, audience, **kwargs):
+ """Creates a new :class:`google.auth.jwt.Credentials` instance from an
+ existing :class:`google.auth.credentials.Signing` instance.
+
+ The new instance will use the same signer as the existing instance and
+ will use the existing instance's signer email as the issuer and
+ subject by default.
+
+ Example::
+
+ svc_creds = service_account.Credentials.from_service_account_file(
+ 'service_account.json')
+ audience = (
+ 'https://pubsub.googleapis.com/google.pubsub.v1.Publisher')
+ jwt_creds = jwt.Credentials.from_signing_credentials(
+ svc_creds, audience=audience)
+
+ Args:
+ credentials (google.auth.credentials.Signing): The credentials to
+ use to construct the new credentials.
+ audience (str): the `aud` claim. The intended audience for the
+ credentials.
+ kwargs: Additional arguments to pass to the constructor.
+
+ Returns:
+ google.auth.jwt.Credentials: A new Credentials instance.
+ """
+ kwargs.setdefault('issuer', credentials.signer_email)
+ kwargs.setdefault('subject', credentials.signer_email)
+ return cls(
+ credentials.signer,
+ audience=audience,
+ **kwargs)
+
def with_claims(self, issuer=None, subject=None, audience=None,
additional_claims=None):
"""Returns a copy of these credentials with modified claims.
@@ -431,16 +468,16 @@
# (pylint doesn't correctly recognize overridden methods.)
self.token, self.expiry = self._make_jwt()
- @_helpers.copy_docstring(credentials.Signing)
+ @_helpers.copy_docstring(google.auth.credentials.Signing)
def sign_bytes(self, message):
return self._signer.sign(message)
@property
- @_helpers.copy_docstring(credentials.Signing)
+ @_helpers.copy_docstring(google.auth.credentials.Signing)
def signer_email(self):
return self._issuer
@property
- @_helpers.copy_docstring(credentials.Signing)
+ @_helpers.copy_docstring(google.auth.credentials.Signing)
def signer(self):
return self._signer
diff --git a/google/oauth2/service_account.py b/google/oauth2/service_account.py
index a4fc1b6..58580e2 100644
--- a/google/oauth2/service_account.py
+++ b/google/oauth2/service_account.py
@@ -204,38 +204,6 @@
filename, require=['client_email', 'token_uri'])
return cls._from_signer_and_info(signer, info, **kwargs)
- def to_jwt_credentials(self, audience):
- """Creates a :class:`google.auth.jwt.Credentials` instance from this
- instance.
-
- The new instance will use the same private key as this instance and
- will use this instance's service account email as the issuer and
- subject.
-
- This is the same as calling
- :meth:`jwt.Credentials.from_service_account_file` with the same
- file used to create these credentials::
-
- svc_creds = service_account.Credentials.from_service_account_file(
- 'service_account.json')
- jwt_from_svc = svc_credentials.to_jwt_credentials()
- # is the same as:
- jwt_creds = jwt.Credentials.from_service_account_file(
- 'service_account.json')
-
- Args:
- audience (str): the `aud` claim. The intended audience for the
- credentials.
-
- Returns:
- google.auth.jwt.Credentials: A new Credentials instance.
- """
- return jwt.Credentials(
- self._signer,
- issuer=self._service_account_email,
- subject=self._service_account_email,
- audience=audience)
-
@property
def service_account_email(self):
"""The service account email."""