2
2
3
3
import json
4
4
from ipaddress import ip_address
5
+ import os
5
6
6
7
from http .client import responses
7
8
from tornado import web
8
9
from tornado .log import app_log
10
+ from tornado .httpclient import AsyncHTTPClient , HTTPRequest , HTTPError
11
+
9
12
from jupyterhub .services .auth import HubOAuthenticated , HubOAuth
10
13
11
14
from . import __version__ as binder_version
@@ -19,6 +22,7 @@ def initialize(self):
19
22
super ().initialize ()
20
23
if self .settings ['auth_enabled' ]:
21
24
self .hub_auth = HubOAuth .instance (config = self .settings ['traitlets_config' ])
25
+ self .current_user_model = None
22
26
23
27
def prepare (self ):
24
28
super ().prepare ()
@@ -71,16 +75,46 @@ def get_spec_from_request(self, prefix):
71
75
spec = self .request .path [idx + len (prefix ) + 1 :]
72
76
return spec
73
77
74
- def get_provider (self , provider_prefix , spec ):
78
+ async def get_provider (self , provider_prefix , spec ):
75
79
"""Construct a provider object"""
76
80
providers = self .settings ['repo_providers' ]
77
81
if provider_prefix not in providers :
78
82
raise web .HTTPError (404 , "No provider found for prefix %s" % provider_prefix )
79
83
84
+ async def api_request (url , * args , ** kwargs ):
85
+ headers = kwargs .setdefault ('headers' , {})
86
+ headers .update ({'Authorization' : 'token %s' % self .hub_auth .api_token })
87
+ hub_api_url = os .getenv ('JUPYTERHUB_API_URL' , '' ) or self .hub_auth .api_url
88
+ request_url = hub_api_url + url
89
+ req = HTTPRequest (request_url , * args , ** kwargs )
90
+
91
+ try :
92
+ return await AsyncHTTPClient ().fetch (req )
93
+ except HTTPError as e :
94
+ app_log .error ("Error accessing Hub API (using %s): %s" , request_url , e )
95
+
96
+ async def get_current_user_model ():
97
+ """Get the current user model.
98
+ The user auth_state is only accessible to admin users.
99
+ """
100
+ if not self .settings ['auth_enabled' ]:
101
+ return None
102
+
103
+ if self .current_user_model is None :
104
+ username = self .get_current_user ()['name' ]
105
+ resp = await api_request (
106
+ f'/users/{ username } ' ,
107
+ method = 'GET' ,
108
+ )
109
+ self .current_user_model = json .loads (resp .body .decode ('utf-8' ))
110
+
111
+ return self .current_user_model
112
+
80
113
return providers [provider_prefix ](
81
- config = self .settings ['traitlets_config' ],
82
- spec = spec ,
83
- handler = self )
114
+ config = self .settings ['traitlets_config' ],
115
+ spec = spec ,
116
+ user_model = await get_current_user_model ()
117
+ )
84
118
85
119
def get_badge_base_url (self ):
86
120
badge_base_url = self .settings ['badge_base_url' ]
0 commit comments