From c9e6d6afa3987091f8eb8eaa72124f031ca8ff79 Mon Sep 17 00:00:00 2001 From: Min RK Date: Wed, 10 Aug 2022 08:36:23 +0200 Subject: [PATCH] restore trimming of username input continue to not trim password or custom fields trailing/leading space is explicitly forbidden in validate_username --- jupyterhub/auth.py | 3 +++ jupyterhub/handlers/login.py | 4 +++- jupyterhub/tests/test_pages.py | 16 ++++++++++++---- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/jupyterhub/auth.py b/jupyterhub/auth.py index 192becdb..e31cd395 100644 --- a/jupyterhub/auth.py +++ b/jupyterhub/auth.py @@ -256,6 +256,9 @@ class Authenticator(LoggingConfigurable): if not username: # empty usernames are not allowed return False + if username != username.strip(): + # starting/ending with space is not allowed + return False if not self.username_regex: return True return bool(self.username_regex.match(username)) diff --git a/jupyterhub/handlers/login.py b/jupyterhub/handlers/login.py index 29f2ff02..f913146a 100644 --- a/jupyterhub/handlers/login.py +++ b/jupyterhub/handlers/login.py @@ -145,7 +145,9 @@ class LoginHandler(BaseHandler): # parse the arguments dict data = {} for arg in self.request.arguments: - data[arg] = self.get_argument(arg, strip=False) + # strip username, but not other fieldsĀ like passwords, + # which should be allowed to start or end with space + data[arg] = self.get_argument(arg, strip=arg == "username") auth_timer = self.statsd.timer('login.authenticate').start() user = await self.login_user(data) diff --git a/jupyterhub/tests/test_pages.py b/jupyterhub/tests/test_pages.py index 29507a20..0b622097 100644 --- a/jupyterhub/tests/test_pages.py +++ b/jupyterhub/tests/test_pages.py @@ -740,9 +740,17 @@ async def test_login_fail(app): assert not r.cookies -async def test_login_strip(app): - """Test that login form doesn't strip whitespace from passwords""" - form_data = {'username': 'spiff', 'password': ' space man '} +@pytest.mark.parametrize( + "form_user, auth_user, form_password", + [ + ("spiff", "spiff", " space man "), + (" spiff ", "spiff", " space man "), + ], +) +async def test_login_strip(app, form_user, auth_user, form_password): + """Test that login form strips space form usernames, but not passwords""" + form_data = {"username": form_user, "password": form_password} + expected_auth = {"username": auth_user, "password": form_password} base_url = public_url(app) called_with = [] @@ -754,7 +762,7 @@ async def test_login_strip(app): base_url + 'hub/login', data=form_data, allow_redirects=False ) - assert called_with == [form_data] + assert called_with == [expected_auth] @pytest.mark.parametrize(