From 6b53c8f50a171aa7a116048221bd07c4a25b29c8 Mon Sep 17 00:00:00 2001 From: Jay Lee Date: Tue, 22 Dec 2020 11:12:36 -0500 Subject: [PATCH 1/5] Add headers parameter to generate() headers parameter allows optional headers to be set on generated JWT such as "kid". --- adafruit_jwt.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/adafruit_jwt.py b/adafruit_jwt.py index 775e152..0632b75 100644 --- a/adafruit_jwt.py +++ b/adafruit_jwt.py @@ -94,10 +94,12 @@ def validate(jwt): return (jose_header, claims) @staticmethod - def generate(claims, private_key_data=None, algo=None): + def generate(claims, private_key_data=None, algo=None, headers=None): """Generates and returns a new JSON Web Token. :param dict claims: JWT claims set :param str private_key_data: Decoded RSA private key data. + :param str algo: algorithm to be used. One of None, RS256, RS384 or RS512. + :param dict headers: additional headers for the claim. :rtype: str """ # Allow for unencrypted JWTs @@ -108,6 +110,8 @@ def generate(claims, private_key_data=None, algo=None): # Create the JOSE Header # https://tools.ietf.org/html/rfc7519#section-5 jose_header = {"typ": "JWT", "alg": algo} + if headers: + jose_headers.update(headers) payload = "{}.{}".format( STRING_TOOLS.urlsafe_b64encode(json.dumps(jose_header).encode("utf-8")), STRING_TOOLS.urlsafe_b64encode(json.dumps(claims).encode("utf-8")), From 7b3019dae87226b6488d2fdcbeb50a9c6512ab68 Mon Sep 17 00:00:00 2001 From: Jay Lee Date: Tue, 22 Dec 2020 11:21:18 -0500 Subject: [PATCH 2/5] jose_header not jose_headers --- adafruit_jwt.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adafruit_jwt.py b/adafruit_jwt.py index 0632b75..bcff743 100644 --- a/adafruit_jwt.py +++ b/adafruit_jwt.py @@ -111,7 +111,7 @@ def generate(claims, private_key_data=None, algo=None, headers=None): # https://tools.ietf.org/html/rfc7519#section-5 jose_header = {"typ": "JWT", "alg": algo} if headers: - jose_headers.update(headers) + jose_header.update(headers) payload = "{}.{}".format( STRING_TOOLS.urlsafe_b64encode(json.dumps(jose_header).encode("utf-8")), STRING_TOOLS.urlsafe_b64encode(json.dumps(claims).encode("utf-8")), From 572a679f93b007b77db804735e3155c457efc717 Mon Sep 17 00:00:00 2001 From: Jay Lee Date: Wed, 23 Dec 2020 09:41:47 -0500 Subject: [PATCH 3/5] first attempt at resolving pylint warnings --- adafruit_jwt.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/adafruit_jwt.py b/adafruit_jwt.py index bcff743..446d2f8 100644 --- a/adafruit_jwt.py +++ b/adafruit_jwt.py @@ -77,8 +77,8 @@ def validate(jwt): # Attempt to decode JOSE header try: jose_header = STRING_TOOLS.urlsafe_b64decode(jwt.split(".")[0]) - except UnicodeError: - raise UnicodeError("Unable to decode JOSE header.") + except UnicodeError as unicode_error: + raise unicode_error("Unable to decode JOSE header.") # Check for typ and alg in decoded JOSE header if "typ" not in jose_header: raise TypeError("JOSE Header does not contain required type key.") @@ -87,8 +87,8 @@ def validate(jwt): # Attempt to decode claim set try: claims = json.loads(STRING_TOOLS.urlsafe_b64decode(jwt.split(".")[1])) - except UnicodeError: - raise UnicodeError("Invalid claims encoding.") + except UnicodeError as unicode_error: + raise unicode_error("Invalid claims encoding.") if not hasattr(claims, "keys"): raise TypeError("Provided claims is not a JSON dict. object") return (jose_header, claims) From 859b456a7446bc7c1ab3a6da125c7ffe0b18fe22 Mon Sep 17 00:00:00 2001 From: Jay Lee Date: Wed, 23 Dec 2020 09:48:02 -0500 Subject: [PATCH 4/5] pylint warning fix take two --- adafruit_jwt.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/adafruit_jwt.py b/adafruit_jwt.py index 446d2f8..f7bbabd 100644 --- a/adafruit_jwt.py +++ b/adafruit_jwt.py @@ -78,7 +78,7 @@ def validate(jwt): try: jose_header = STRING_TOOLS.urlsafe_b64decode(jwt.split(".")[0]) except UnicodeError as unicode_error: - raise unicode_error("Unable to decode JOSE header.") + raise UnicodeError("Unable to decode JOSE header.") from unicode_error # Check for typ and alg in decoded JOSE header if "typ" not in jose_header: raise TypeError("JOSE Header does not contain required type key.") @@ -88,7 +88,7 @@ def validate(jwt): try: claims = json.loads(STRING_TOOLS.urlsafe_b64decode(jwt.split(".")[1])) except UnicodeError as unicode_error: - raise unicode_error("Invalid claims encoding.") + raise UnicodeError("Invalid claims encoding.") from unicode_error if not hasattr(claims, "keys"): raise TypeError("Provided claims is not a JSON dict. object") return (jose_header, claims) @@ -183,8 +183,8 @@ def _bytes_from_decode_data(str_data): if isinstance(str_data, str): try: return str_data.encode("ascii") - except: - raise ValueError("string argument should contain only ASCII characters") + except BaseException as error: + raise ValueError("string argument should contain only ASCII characters") from error elif isinstance(str_data, bit_types): return str_data else: From 2f414177afa8b751c5d57c2a4df58829f2266f71 Mon Sep 17 00:00:00 2001 From: Jay Lee Date: Wed, 23 Dec 2020 09:53:52 -0500 Subject: [PATCH 5/5] reformat like black wants it. --- adafruit_jwt.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/adafruit_jwt.py b/adafruit_jwt.py index f7bbabd..d8124d4 100644 --- a/adafruit_jwt.py +++ b/adafruit_jwt.py @@ -143,8 +143,7 @@ def generate(claims, private_key_data=None, algo=None, headers=None): # pylint: disable=invalid-name class STRING_TOOLS: - """Tools and helpers for URL-safe string encoding. - """ + """Tools and helpers for URL-safe string encoding.""" # Some strings for ctype-style character classification whitespace = " \t\n\r\v\f" @@ -184,7 +183,9 @@ def _bytes_from_decode_data(str_data): try: return str_data.encode("ascii") except BaseException as error: - raise ValueError("string argument should contain only ASCII characters") from error + raise ValueError( + "string argument should contain only ASCII characters" + ) from error elif isinstance(str_data, bit_types): return str_data else: