12
12
from .security import passwd_check , set_password
13
13
14
14
15
- class LoginHandler (JupyterHandler ):
15
+ class LoginFormHandler (JupyterHandler ):
16
16
"""The basic tornado login handler
17
17
18
- authenticates with a hashed password from the configuration .
18
+ accepts login form, passed to IdentityProvider.process_login_form .
19
19
"""
20
20
21
21
def _render (self , message = None ):
@@ -66,6 +66,26 @@ def get(self):
66
66
else :
67
67
self ._render ()
68
68
69
+ def post (self ):
70
+ user = self .current_user = self .identity_provider .process_login_form (self )
71
+ if user is None :
72
+ self .set_status (401 )
73
+ self ._render (message = {"error" : "Invalid credentials" })
74
+ return
75
+
76
+ self .log .info (f"User { user .username } logged in." )
77
+ self .identity_provider .set_login_cookie (self , user )
78
+ next_url = self .get_argument ("next" , default = self .base_url )
79
+ self ._redirect_safe (next_url )
80
+
81
+
82
+ class LegacyLoginHandler (LoginFormHandler ):
83
+ """Legacy LoginHandler, implementing most custom auth configuration.
84
+
85
+ Deprecated in jupyter-server 2.0.
86
+ Login configuration has moved to IdentityProvider.
87
+ """
88
+
69
89
@property
70
90
def hashed_password (self ):
71
91
return self .password_from_settings (self .settings )
@@ -74,6 +94,7 @@ def passwd_check(self, a, b):
74
94
return passwd_check (a , b )
75
95
76
96
def post (self ):
97
+
77
98
typed_password = self .get_argument ("password" , default = "" )
78
99
new_password = self .get_argument ("new_password" , default = "" )
79
100
@@ -130,37 +151,20 @@ def get_token(cls, handler):
130
151
131
152
@classmethod
132
153
def should_check_origin (cls , handler ):
133
- """Should the Handler check for CORS origin validation?
134
-
135
- Origin check should be skipped for token-authenticated requests.
136
-
137
- Returns:
138
- - True, if Handler must check for valid CORS origin.
139
- - False, if Handler should skip origin check since requests are token-authenticated.
140
- """
154
+ """DEPRECATED in 2.0, use IdentityProvider API"""
141
155
return not cls .is_token_authenticated (handler )
142
156
143
157
@classmethod
144
158
def is_token_authenticated (cls , handler ):
145
- """Returns True if handler has been token authenticated. Otherwise, False.
146
-
147
- Login with a token is used to signal certain things, such as:
148
-
149
- - permit access to REST API
150
- - xsrf protection
151
- - skip origin-checks for scripts
152
- """
159
+ """DEPRECATED in 2.0, use IdentityProvider API"""
153
160
if getattr (handler , "_user_id" , None ) is None :
154
161
# ensure get_user has been called, so we know if we're token-authenticated
155
162
handler .current_user
156
163
return getattr (handler , "_token_authenticated" , False )
157
164
158
165
@classmethod
159
166
def get_user (cls , handler ):
160
- """Called by handlers.get_current_user for identifying the current user.
161
-
162
- See tornado.web.RequestHandler.get_current_user for details.
163
- """
167
+ """DEPRECATED in 2.0, use IdentityProvider API"""
164
168
# Can't call this get_current_user because it will collide when
165
169
# called on LoginHandler itself.
166
170
if getattr (handler , "_user_id" , None ):
@@ -197,7 +201,7 @@ def get_user(cls, handler):
197
201
198
202
@classmethod
199
203
def get_user_cookie (cls , handler ):
200
- """Get user-id from a cookie """
204
+ """DEPRECATED in 2.0, use IdentityProvider API """
201
205
get_secure_cookie_kwargs = handler .settings .get ("get_secure_cookie_kwargs" , {})
202
206
user_id = handler .get_secure_cookie (handler .cookie_name , ** get_secure_cookie_kwargs )
203
207
if user_id :
@@ -206,12 +210,7 @@ def get_user_cookie(cls, handler):
206
210
207
211
@classmethod
208
212
def get_user_token (cls , handler ):
209
- """Identify the user based on a token in the URL or Authorization header
210
-
211
- Returns:
212
- - uuid if authenticated
213
- - None if not
214
- """
213
+ """DEPRECATED in 2.0, use IdentityProvider API"""
215
214
token = handler .token
216
215
if not token :
217
216
return
@@ -243,10 +242,7 @@ def get_user_token(cls, handler):
243
242
244
243
@classmethod
245
244
def validate_security (cls , app , ssl_options = None ):
246
- """Check the application's security.
247
-
248
- Show messages, or abort if necessary, based on the security configuration.
249
- """
245
+ """DEPRECATED in 2.0, use IdentityProvider API"""
250
246
if not app .ip :
251
247
warning = "WARNING: The Jupyter server is listening on all IP addresses"
252
248
if ssl_options is None :
@@ -265,13 +261,15 @@ def validate_security(cls, app, ssl_options=None):
265
261
266
262
@classmethod
267
263
def password_from_settings (cls , settings ):
268
- """Return the hashed password from the tornado settings.
269
-
270
- If there is no configured password, an empty string will be returned.
271
- """
264
+ """DEPRECATED in 2.0, use IdentityProvider API"""
272
265
return settings .get ("password" , "" )
273
266
274
267
@classmethod
275
268
def get_login_available (cls , settings ):
276
- """Whether this LoginHandler is needed - and therefore whether the login page should be displayed."""
269
+ """DEPRECATED in 2.0, use IdentityProvider API"""
270
+
277
271
return bool (cls .password_from_settings (settings ) or settings .get ("token" ))
272
+
273
+
274
+ # deprecated import, so deprecated implementations get the Legacy class instead
275
+ LoginHandler = LegacyLoginHandler
0 commit comments