From 4b96bb51e8f133badd7bc651bcb4dcd755b43d75 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Alfonso=20Mart=C3=ADnez?= Date: Wed, 3 Mar 2021 15:36:06 +0100 Subject: [PATCH] mgr/dashboard: fix issues related with PyJWT versions >=2.0.0 MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Fixes: https://tracker.ceph.com/issues/49574 Signed-off-by: Alfonso Martínez --- qa/tasks/mgr/dashboard/test_auth.py | 2 +- src/pybind/mgr/dashboard/constraints.txt | 2 +- src/pybind/mgr/dashboard/controllers/auth.py | 5 ++++- src/pybind/mgr/dashboard/services/auth.py | 2 +- src/pybind/mgr/dashboard/tests/test_auth.py | 20 ++++++++++++++++++++ 5 files changed, 27 insertions(+), 4 deletions(-) create mode 100644 src/pybind/mgr/dashboard/tests/test_auth.py diff --git a/qa/tasks/mgr/dashboard/test_auth.py b/qa/tasks/mgr/dashboard/test_auth.py index ca7a0cd8229..8fc7cd1992e 100644 --- a/qa/tasks/mgr/dashboard/test_auth.py +++ b/qa/tasks/mgr/dashboard/test_auth.py @@ -20,7 +20,7 @@ class AuthTest(DashboardTestCase): self.reset_session() def _validate_jwt_token(self, token, username, permissions): - payload = jwt.decode(token, verify=False) + payload = jwt.decode(token, options={'verify_signature': False}) self.assertIn('username', payload) self.assertEqual(payload['username'], username) diff --git a/src/pybind/mgr/dashboard/constraints.txt b/src/pybind/mgr/dashboard/constraints.txt index 8284ec737ef..bd5ec4a0a72 100644 --- a/src/pybind/mgr/dashboard/constraints.txt +++ b/src/pybind/mgr/dashboard/constraints.txt @@ -1,6 +1,6 @@ CherryPy==13.1.0 more-itertools==4.1.0 -PyJWT==1.6.4 +PyJWT==2.0.1 bcrypt==3.1.4 python3-saml==1.4.1 requests==2.25.1 diff --git a/src/pybind/mgr/dashboard/controllers/auth.py b/src/pybind/mgr/dashboard/controllers/auth.py index cd50006e28d..03408572fff 100644 --- a/src/pybind/mgr/dashboard/controllers/auth.py +++ b/src/pybind/mgr/dashboard/controllers/auth.py @@ -52,7 +52,10 @@ class Auth(RESTController): mgr.ACCESS_CTRL_DB.reset_attempt(username) mgr.ACCESS_CTRL_DB.save() token = JwtManager.gen_token(username) - token = token.decode('utf-8') + + # For backward-compatibility: PyJWT versions < 2.0.0 return bytes. + token = token.decode('utf-8') if isinstance(token, bytes) else token + set_cookies(url_prefix, token) return { 'token': token, diff --git a/src/pybind/mgr/dashboard/services/auth.py b/src/pybind/mgr/dashboard/services/auth.py index a3f16543001..55436afb6ad 100644 --- a/src/pybind/mgr/dashboard/services/auth.py +++ b/src/pybind/mgr/dashboard/services/auth.py @@ -123,7 +123,7 @@ class JwtManager(object): @classmethod def blocklist_token(cls, token): - token = jwt.decode(token, verify=False) + token = cls.decode_token(token) blocklist_json = mgr.get_store(cls.JWT_TOKEN_BLOCKLIST_KEY) if not blocklist_json: blocklist_json = "{}" diff --git a/src/pybind/mgr/dashboard/tests/test_auth.py b/src/pybind/mgr/dashboard/tests/test_auth.py new file mode 100644 index 00000000000..6f1d2a084ec --- /dev/null +++ b/src/pybind/mgr/dashboard/tests/test_auth.py @@ -0,0 +1,20 @@ +import unittest + +from .. import mgr +from ..services.auth import JwtManager + + +class JwtManagerTest(unittest.TestCase): + + def test_generate_token_and_decode(self): + mgr.get_module_option.return_value = JwtManager.JWT_TOKEN_TTL + mgr.get_store.return_value = 'jwt_secret' + + token = JwtManager.gen_token('my-username') + self.assertIsInstance(token, str) + self.assertTrue(token) + + decoded_token = JwtManager.decode_token(token) + self.assertIsInstance(decoded_token, dict) + self.assertEqual(decoded_token['iss'], 'ceph-dashboard') + self.assertEqual(decoded_token['username'], 'my-username') -- 2.39.5