From 11128936384e9223aa0c78b0eb1b82a6a4fa7220 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Alfonso=20Mart=C3=ADnez?= Date: Fri, 5 Mar 2021 08:52:59 +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 (cherry picked from commit 4b96bb51e8f133badd7bc651bcb4dcd755b43d75) Conflicts: src/pybind/mgr/dashboard/controllers/auth.py - Resolved branch divergence conflicts. src/pybind/mgr/dashboard/services/auth.py - Resolved branch divergence conflicts. src/pybind/mgr/dashboard/requirements.txt - Removed specific version (already done in master branch). --- 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/requirements.txt | 2 +- src/pybind/mgr/dashboard/services/auth.py | 2 +- src/pybind/mgr/dashboard/tests/test_auth.py | 20 ++++++++++++++++++++ 6 files changed, 28 insertions(+), 5 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 f3df04c0a29..df5485d4de5 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 67b37078fc9..f7a1f59d823 100644 --- a/src/pybind/mgr/dashboard/constraints.txt +++ b/src/pybind/mgr/dashboard/constraints.txt @@ -1,7 +1,7 @@ CherryPy==13.1.0 enum34==1.1.6 more-itertools==4.1.0 -PyJWT==1.6.4 +PyJWT==2.0.1 bcrypt==3.1.4 python3-saml==1.4.1 requests==2.20.0 diff --git a/src/pybind/mgr/dashboard/controllers/auth.py b/src/pybind/mgr/dashboard/controllers/auth.py index 8452b6432e8..349b1c4ee72 100644 --- a/src/pybind/mgr/dashboard/controllers/auth.py +++ b/src/pybind/mgr/dashboard/controllers/auth.py @@ -29,7 +29,10 @@ class Auth(RESTController): url_prefix = 'https' if mgr.get_localized_module_option('ssl') else 'http' logger.debug('Login successful') 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/requirements.txt b/src/pybind/mgr/dashboard/requirements.txt index 3d63ef33d30..9a7c71f1ee3 100644 --- a/src/pybind/mgr/dashboard/requirements.txt +++ b/src/pybind/mgr/dashboard/requirements.txt @@ -18,7 +18,7 @@ portend==2.2 py==1.5.2 pycodestyle==2.4.0 pycparser==2.18 -PyJWT==1.6.4 +PyJWT pyopenssl pytest==3.3.2 pytest-cov==2.5.1 diff --git a/src/pybind/mgr/dashboard/services/auth.py b/src/pybind/mgr/dashboard/services/auth.py index 79350bbddbd..239efae816b 100644 --- a/src/pybind/mgr/dashboard/services/auth.py +++ b/src/pybind/mgr/dashboard/services/auth.py @@ -97,7 +97,7 @@ class JwtManager(object): @classmethod def blacklist_token(cls, token): - token = jwt.decode(token, verify=False) + token = cls.decode_token(token) blacklist_json = mgr.get_store(cls.JWT_TOKEN_BLACKLIST_KEY) if not blacklist_json: blacklist_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.47.3