diff --git a/jupyterhub/apihandlers/users.py b/jupyterhub/apihandlers/users.py index b12320c1..29513f78 100644 --- a/jupyterhub/apihandlers/users.py +++ b/jupyterhub/apihandlers/users.py @@ -242,7 +242,10 @@ class UserTokenListAPIHandler(APIHandler): # defer to Authenticator for identifying the user # can be username+password or an upstream auth token try: - name = await self.authenticator.authenticate(self, body.get('auth')) + name = await self.authenticate(body.get('auth')) + if isinstance(name, dict): + # not a simple string so it has to be a dict + name = name.get('name') except web.HTTPError as e: # turn any authentication error into 403 raise web.HTTPError(403) diff --git a/jupyterhub/tests/test_api.py b/jupyterhub/tests/test_api.py index 3fdf0f3d..8711a2ad 100644 --- a/jupyterhub/tests/test_api.py +++ b/jupyterhub/tests/test_api.py @@ -1324,6 +1324,32 @@ async def test_token_authenticator_noauth(app): assert reply['name'] == name +async def test_token_authenticator_dict_noauth(app): + """Create a token for a user relying on Authenticator.authenticate and no auth header""" + app.authenticator.auth_state = { + 'who': 'cares', + } + name = 'user' + data = { + 'auth': { + 'username': name, + 'password': name, + }, + } + r = await api_request(app, 'users', name, 'tokens', + method='post', + data=json.dumps(data) if data else None, + noauth=True, + ) + assert r.status_code == 200 + reply = r.json() + assert 'token' in reply + r = await api_request(app, 'authorizations', 'token', reply['token']) + r.raise_for_status() + reply = r.json() + assert reply['name'] == name + + @mark.parametrize("as_user, for_user, status", [ ('admin', 'other', 200), ('admin', 'missing', 404),