Repository: auth0/auth0-python

Issue:
Returning boolean on token validator
Hi,

I'm using the token validator of the authentication submodule. It's raising a TokenValidationError if validation failed and returning nothing (so the method returning None by python internals) if validation success.

I'm not sure is it a good idea. If I use this method inside an if condition and assume the token is valid the condition won't work. Because it will return None which is equal to False.

In my opinion, the method should return True when a token is validated. And IMHO it should return False instead of raising an error, but it will be a breaking change. So I'm not sure is it necessary.

Discussion:

Patch:
diff --git a/auth0/v3/authentication/token_verifier.py b/auth0/v3/authentication/token_verifier.py
index ea411c0..1f44c08 100644
--- a/auth0/v3/authentication/token_verifier.py
+++ b/auth0/v3/authentication/token_verifier.py
@@ -229,6 +229,9 @@ class TokenVerifier():
             organization (str, optional): The expected organization ID (org_id) claim value. This should be specified
             when logging in to an organization.
 
+        Returns:
+            the decoded payload from the token
+
         Raises:
             TokenValidationError: when the token cannot be decoded, the token signing algorithm is not the expected one,
             the token signature is invalid or the token has a claim missing or with unexpected value.
@@ -244,6 +247,8 @@ class TokenVerifier():
         # Verify claims
         self._verify_payload(payload, nonce, max_age, organization)
 
+        return payload
+
     def _verify_payload(self, payload, nonce=None, max_age=None, organization=None):
         try:
             # on Python 2.7, 'str' keys as parsed as 'unicode'


Test patch:
diff --git a/auth0/v3/test/authentication/test_token_verifier.py b/auth0/v3/test/authentication/test_token_verifier.py
index 7ff0eee..d1306d3 100644
--- a/auth0/v3/test/authentication/test_token_verifier.py
+++ b/auth0/v3/test/authentication/test_token_verifier.py
@@ -390,7 +390,7 @@ class TestTokenVerifier(unittest.TestCase):
             audience=expectations['audience']
         )
         tv._clock = MOCKED_CLOCK
-        tv.verify(token, organization='org_123')    
+        tv.verify(token, organization='org_123')
 
     def test_fails_when_org_specified_but_not_present(self):
         token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhdXRoMHxzZGs0NThma3MiLCJhdWQiOiJ0b2tlbnMtdGVzdC0xMjMiLCJpc3MiOiJodHRwczovL3Rva2Vucy10ZXN0LmF1dGgwLmNvbS8iLCJleHAiOjE1ODc3NjUzNjEsImlhdCI6MTU4NzU5MjU2MX0.wotJnUdD5IfdZMewF_-BnHc0pI56uwzwr5qaSXvSu9w"
@@ -402,4 +402,22 @@ class TestTokenVerifier(unittest.TestCase):
 
     def test_fails_when_org_specified_but_does_not_match(self):
         token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhdXRoMHxzZGs0NThma3MiLCJhdWQiOiJ0b2tlbnMtdGVzdC0xMjMiLCJvcmdfaWQiOiJvcmdfMTIzIiwiaXNzIjoiaHR0cHM6Ly90b2tlbnMtdGVzdC5hdXRoMC5jb20vIiwiZXhwIjoxNTg3NzY1MzYxLCJpYXQiOjE1ODc1OTI1NjF9.hjSPgJpg0Dn2z0giCdGqVLD5Kmqy_yMYlSkgwKD7ahQ"
-        self.assert_fails_with_error(token, 'Organization (org_id) claim mismatch in the ID token; expected "org_abc", found "org_123"', signature_verifier=SymmetricSignatureVerifier(HMAC_SHARED_SECRET), organization='org_abc')
\ No newline at end of file
+        self.assert_fails_with_error(token, 'Organization (org_id) claim mismatch in the ID token; expected "org_abc", found "org_123"', signature_verifier=SymmetricSignatureVerifier(HMAC_SHARED_SECRET), organization='org_abc')
+
+    def test_verify_returns_payload(self):
+        token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhdXRoMHxzZGs0NThma3MiLCJhdWQiOiJ0b2tlbnMtdGVzdC0xMjMiLCJvcmdfaWQiOiJvcmdfMTIzIiwiaXNzIjoiaHR0cHM6Ly90b2tlbnMtdGVzdC5hdXRoMC5jb20vIiwiZXhwIjoxNTg3NzY1MzYxLCJpYXQiOjE1ODc1OTI1NjF9.hjSPgJpg0Dn2z0giCdGqVLD5Kmqy_yMYlSkgwKD7ahQ"
+        sv = SymmetricSignatureVerifier(HMAC_SHARED_SECRET)
+        tv = TokenVerifier(
+            signature_verifier=sv,
+            issuer=expectations['issuer'],
+            audience=expectations['audience']
+        )
+        tv._clock = MOCKED_CLOCK
+        response = tv.verify(token)
+        self.assertIn('sub', response);
+        self.assertIn('aud', response);
+        self.assertIn('org_id', response);
+        self.assertIn('iss', response);
+        self.assertIn('exp', response);
+        self.assertIn('iat', response);
+        self.assertEqual('org_123', response['org_id'])