39
39
40
40
_undefined = object ()
41
41
42
+
42
43
class UaPyJWKClient (_jwt .PyJWKClient ):
43
44
def fetch_data (self ) -> Any :
44
45
with _urllib .request .urlopen (
@@ -98,18 +99,30 @@ def create_logout_button(label="Logout", style=None):
98
99
)
99
100
100
101
101
- def _raise_context_error ():
102
+ def is_jupyter_kernel ():
103
+ """Check if the current environment is a Jupyter kernel."""
102
104
try :
103
- is_jupyter_kernel = (
104
- get_ipython ().__class__ .__name__ == "ZMQInteractiveShell" # type: ignore
105
- )
105
+ return get_ipython ().__class__ .__name__ == "ZMQInteractiveShell" # type: ignore
106
106
except NameError :
107
- is_jupyter_kernel = False
107
+ return False
108
108
109
+
110
+ def _raise_context_error ():
111
+ notebook_specific_error = (
112
+ (
113
+ "Could not get user token from the Jupyter kernel. Try closing and re-opening your notebook. \n "
114
+ "This codeblock will still run correctly in your App Studio preview or deployed Dash app."
115
+ )
116
+ if _os .getenv ("DASH_ENTERPRISE_ENV" )
117
+ else (
118
+ "Could not get user token from the Jupyter kernel.\n "
119
+ "dash-enterprise-auth methods cannot be called in a notebook cell outside of a Dash Enterprise workspace.\n "
120
+ "This codeblock will still run correctly in your App Studio preview or deployed Dash app."
121
+ )
122
+ )
109
123
raise RuntimeError (
110
- "dash-enterprise-auth functions should be called in a flask request context or dash callback and will not run in a notebook cell.\n "
111
- "This codeblock will still run correctly in your App Studio preview or deployed Dash app."
112
- if is_jupyter_kernel
124
+ notebook_specific_error
125
+ if is_jupyter_kernel ()
113
126
else "Could not find user token from the context.\n "
114
127
"Make sure you are running inside a flask request or a dash callback."
115
128
)
@@ -139,7 +152,11 @@ def get_user_data():
139
152
try :
140
153
jwks_client = UaPyJWKClient (jwks_url )
141
154
142
- token = _get_decoded_token ("kcIdToken" )
155
+ # In workspace, the user token is stored via the dash_user_token environment
156
+ # variable to make it available in the Jupyter kernel.
157
+ dash_user_token = is_jupyter_kernel () and _os .getenv ("DASH_USER_TOKEN" )
158
+
159
+ token = dash_user_token or _get_decoded_token ("kcIdToken" )
143
160
144
161
if not token :
145
162
return {}
@@ -150,12 +167,16 @@ def get_user_data():
150
167
token ,
151
168
signing_key .key ,
152
169
algorithms = [signing_key ._jwk_data .get ("alg" , "RSA256" )],
153
- audience = _os .getenv ("DASH_AUD" , "dash" ),
170
+ # This is fine because the token is already present in the client's cookies
171
+ # in the workspace.
172
+ audience = "account"
173
+ if is_jupyter_kernel ()
174
+ else _os .getenv ("DASH_AUD" , "dash" ),
154
175
options = {"verify_exp" : True },
155
176
)
156
177
if info_url :
157
- tok = _get_decoded_token ("kcToken" )
158
- authorization = f"Bearer { tok .decode ()} "
178
+ tok = dash_user_token or _get_decoded_token ("kcToken" )
179
+ authorization = f"Bearer { dash_user_token or tok .decode ()} "
159
180
response = _requests .get (
160
181
info_url ,
161
182
headers = {
0 commit comments