From e110a63a6fca5b1de12beb4a629cad74d82a8cf4 Mon Sep 17 00:00:00 2001 From: Ray Luo Date: Fri, 15 Jan 2021 00:37:02 -0800 Subject: [PATCH] Be compatible with PyJWT 1 & 2 --- oauth2cli/assertion.py | 12 +++++++++++- oauth2cli/oauth2.py | 8 +++++--- setup.py | 4 ++-- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/oauth2cli/assertion.py b/oauth2cli/assertion.py index f8d3f16f..0cf58799 100644 --- a/oauth2cli/assertion.py +++ b/oauth2cli/assertion.py @@ -9,6 +9,15 @@ logger = logging.getLogger(__name__) + +def _str2bytes(raw): + # A conversion based on duck-typing rather than six.text_type + try: # Assuming it is a string + return raw.encode(encoding="utf-8") + except: # Otherwise we treat it as bytes and return it as-is + return raw + + class AssertionCreator(object): def create_normal_assertion( self, audience, issuer, subject, expires_at=None, expires_in=600, @@ -103,8 +112,9 @@ def create_normal_assertion( payload['nbf'] = not_before payload.update(additional_claims or {}) try: - return jwt.encode( + str_or_bytes = jwt.encode( # PyJWT 1 returns bytes, PyJWT 2 returns str payload, self.key, algorithm=self.algorithm, headers=self.headers) + return _str2bytes(str_or_bytes) # We normalize them into bytes except: if self.algorithm.startswith("RS") or self.algorithm.starswith("ES"): logger.exception( diff --git a/oauth2cli/oauth2.py b/oauth2cli/oauth2.py index 07432364..fd764082 100644 --- a/oauth2cli/oauth2.py +++ b/oauth2cli/oauth2.py @@ -99,8 +99,8 @@ def __init__( client_secret (str): Triggers HTTP AUTH for Confidential Client client_assertion (bytes, callable): The client assertion to authenticate this client, per RFC 7521. - It can be a raw SAML2 assertion (this method will encode it for you), - or a raw JWT assertion. + It can be a raw SAML2 assertion (we will base64 encode it for you), + or a raw JWT assertion in bytes (which we will relay to http layer). It can also be a callable (recommended), so that we will do lazy creation of an assertion. client_assertion_type (str): @@ -198,7 +198,9 @@ def _obtain_token( # The verb "obtain" is influenced by OAUTH2 RFC 6749 self.default_body["client_assertion_type"], lambda a: a) _data["client_assertion"] = encoder( self.client_assertion() # Do lazy on-the-fly computation - if callable(self.client_assertion) else self.client_assertion) + if callable(self.client_assertion) else self.client_assertion + ) # The type is bytes, which is preferrable. See also: + # https://github.com/psf/requests/issues/4503#issuecomment-455001070 _data.update(self.default_body) # It may contain authen parameters _data.update(data or {}) # So the content in data param prevails diff --git a/setup.py b/setup.py index ff96ce61..a849b87b 100644 --- a/setup.py +++ b/setup.py @@ -30,7 +30,7 @@ ], packages=['oauth2cli'], install_requires=[ - 'requests>=2.0.0', - 'PyJWT>=1.0.0', + 'requests>=2.0.0,<3', + 'PyJWT>=1.0.0,<3', ] )