13
13
import sys
14
14
import uuid
15
15
from dataclasses import asdict , dataclass
16
- from typing import TYPE_CHECKING , Any , cast
16
+ from typing import TYPE_CHECKING , Any , Awaitable , cast
17
17
18
18
from tornado import web
19
19
from traitlets import Bool , Dict , Type , Unicode , default
@@ -175,7 +175,7 @@ def _token_default(self):
175
175
176
176
need_token = Bool (True )
177
177
178
- def get_user (self , handler : JupyterHandler ) -> User | None :
178
+ async def get_user (self , handler : JupyterHandler ) -> User | None :
179
179
"""Get the authenticated user for a request
180
180
181
181
Must return a :class:`.jupyter_server.auth.User`,
@@ -188,11 +188,18 @@ def get_user(self, handler: JupyterHandler) -> User | None:
188
188
if getattr (handler , "_jupyter_current_user" , None ):
189
189
# already authenticated
190
190
return handler ._jupyter_current_user
191
- token_user = self .get_user_token (handler )
192
- cookie_user = self .get_user_cookie (handler )
191
+ _token_user : User | None | Awaitable [User | None ] = self .get_user_token (handler )
192
+ if isinstance (_token_user , Awaitable ):
193
+ _token_user = await _token_user
194
+ token_user : User | None = _token_user # need second variable name to collapse type
195
+ _cookie_user = self .get_user_cookie (handler )
196
+ if isinstance (_cookie_user , Awaitable ):
197
+ _cookie_user = await _cookie_user
198
+ cookie_user : User | None = _cookie_user
193
199
# prefer token to cookie if both given,
194
200
# because token is always explicit
195
201
user = token_user or cookie_user
202
+
196
203
if token_user :
197
204
# if token-authenticated, persist user_id in cookie
198
205
# if it hasn't already been stored there
@@ -258,16 +265,16 @@ def set_login_cookie(self, handler: JupyterHandler, user: User) -> None:
258
265
cookie_options .setdefault ("path" , handler .base_url )
259
266
handler .set_secure_cookie (handler .cookie_name , self .user_to_cookie (user ), ** cookie_options )
260
267
261
- def get_user_cookie (self , handler : JupyterHandler ) -> User | None :
268
+ def get_user_cookie (self , handler : JupyterHandler ) -> User | None | Awaitable [ User | None ] :
262
269
"""Get user from a cookie
263
270
264
271
Calls user_from_cookie to deserialize cookie value
265
272
"""
266
273
get_secure_cookie_kwargs = handler .settings .get ("get_secure_cookie_kwargs" , {})
267
- user_cookie = handler .get_secure_cookie (handler .cookie_name , ** get_secure_cookie_kwargs )
268
- if not user_cookie :
274
+ _user_cookie = handler .get_secure_cookie (handler .cookie_name , ** get_secure_cookie_kwargs )
275
+ if not _user_cookie :
269
276
return None
270
- user_cookie = user_cookie .decode ()
277
+ user_cookie = _user_cookie .decode ()
271
278
# TODO: try/catch in case of change in config?
272
279
try :
273
280
return self .user_from_cookie (user_cookie )
@@ -296,7 +303,7 @@ def get_token(self, handler: JupyterHandler) -> str | None:
296
303
user_token = m .group (2 )
297
304
return user_token
298
305
299
- def get_user_token (self , handler : JupyterHandler ) -> User | None :
306
+ async def get_user_token (self , handler : JupyterHandler ) -> User | None :
300
307
"""Identify the user based on a token in the URL or Authorization header
301
308
302
309
Returns:
@@ -321,7 +328,10 @@ def get_user_token(self, handler: JupyterHandler) -> User | None:
321
328
# token does not correspond to user-id,
322
329
# which is stored in a cookie.
323
330
# still check the cookie for the user id
324
- user = self .get_user_cookie (handler )
331
+ _user = self .get_user_cookie (handler )
332
+ if isinstance (_user , Awaitable ):
333
+ _user = await _user
334
+ user : User | None = _user
325
335
if user is None :
326
336
user = self .generate_anonymous_user (handler )
327
337
return user
0 commit comments