11"""Base classes for request handlers"""
22
33import json
4+ import os
45
56from http .client import responses
67from tornado import web
8+ from tornado .log import app_log
9+ from tornado .httpclient import AsyncHTTPClient , HTTPRequest , HTTPError
10+
711from jupyterhub .services .auth import HubOAuthenticated , HubOAuth
812
913from . import __version__ as binder_version
@@ -16,6 +20,7 @@ def initialize(self):
1620 super ().initialize ()
1721 if self .settings ['auth_enabled' ]:
1822 self .hub_auth = HubOAuth .instance (config = self .settings ['traitlets_config' ])
23+ self .current_user_model = None
1924
2025 def get_current_user (self ):
2126 if not self .settings ['auth_enabled' ]:
@@ -43,16 +48,46 @@ def get_spec_from_request(self, prefix):
4348 spec = self .request .path [idx + len (prefix ) + 1 :]
4449 return spec
4550
46- def get_provider (self , provider_prefix , spec ):
51+ async def get_provider (self , provider_prefix , spec ):
4752 """Construct a provider object"""
4853 providers = self .settings ['repo_providers' ]
4954 if provider_prefix not in providers :
5055 raise web .HTTPError (404 , "No provider found for prefix %s" % provider_prefix )
5156
57+ async def api_request (url , * args , ** kwargs ):
58+ headers = kwargs .setdefault ('headers' , {})
59+ headers .update ({'Authorization' : 'token %s' % self .hub_auth .api_token })
60+ hub_api_url = os .getenv ('JUPYTERHUB_API_URL' , '' ) or self .hub_auth .api_url
61+ request_url = hub_api_url + url
62+ req = HTTPRequest (request_url , * args , ** kwargs )
63+
64+ try :
65+ return await AsyncHTTPClient ().fetch (req )
66+ except HTTPError as e :
67+ app_log .error ("Error accessing Hub API (using %s): %s" , request_url , e )
68+
69+ async def get_current_user_model ():
70+ """Get the current user model.
71+ The user auth_state is only accessible to admin users.
72+ """
73+ if not self .settings ['auth_enabled' ]:
74+ return None
75+
76+ if self .current_user_model is None :
77+ username = self .get_current_user ()['name' ]
78+ resp = await api_request (
79+ f'/users/{ username } ' ,
80+ method = 'GET' ,
81+ )
82+ self .current_user_model = json .loads (resp .body .decode ('utf-8' ))
83+
84+ return self .current_user_model
85+
5286 return providers [provider_prefix ](
53- config = self .settings ['traitlets_config' ],
54- spec = spec ,
55- handler = self )
87+ config = self .settings ['traitlets_config' ],
88+ spec = spec ,
89+ user_model = await get_current_user_model ()
90+ )
5691
5792 def get_badge_base_url (self ):
5893 badge_base_url = self .settings ['badge_base_url' ]
0 commit comments