Skip to content

Commit

Permalink
deprecate LoginHandler methods moving to IdentityProvider
Browse files Browse the repository at this point in the history
keep them in place to allow deprecated super() calls
  • Loading branch information
minrk committed May 4, 2022
1 parent 136dc59 commit 0a1fc22
Showing 1 changed file with 48 additions and 36 deletions.
84 changes: 48 additions & 36 deletions jupyter_server/auth/login.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import os
import re
import uuid
import warnings
from functools import wraps
from urllib.parse import urlparse

from tornado.escape import url_escape
Expand All @@ -12,6 +14,31 @@
from .security import passwd_check, set_password


def _moved_to_identity_provider(new_name_or_method):
"""Warn about deprecated LoginHandler methods that have been moved to IdentityProvider"""

def decorator(method):
name = method.__name__

@wraps(method)
def wrapped(*args, **kwargs):
warnings.warn(
f"LoginHandler.{name} is deprecated in jupyter-server 2.0. Use IdentityProvider.{new_name}",
DeprecationWarning,
stacklevel=3,
)
return method(*args, **kwargs)

if isinstance(new_name_or_method, str):
# called with an arg
new_name = new_name_or_method
return decorator
else:
method = new_name_or_method
new_name = method.__name__
return decorator(method)


class LoginHandler(JupyterHandler):
"""The basic tornado login handler
Expand Down Expand Up @@ -67,9 +94,11 @@ def get(self):
self._render()

@property
# @_moved_to_identity_provider("password")
def hashed_password(self):
return self.password_from_settings(self.settings)

@_moved_to_identity_provider
def passwd_check(self, a, b):
return passwd_check(a, b)

Expand All @@ -96,6 +125,7 @@ def post(self):
self._redirect_safe(next_url)

@classmethod
@_moved_to_identity_provider
def set_login_cookie(cls, handler, user_id=None):
"""Call this on handlers to set the login cookie for success"""
cookie_options = handler.settings.get("cookie_options", {})
Expand All @@ -111,6 +141,7 @@ def set_login_cookie(cls, handler, user_id=None):
auth_header_pat = re.compile(r"token\s+(.+)", re.IGNORECASE)

@classmethod
@_moved_to_identity_provider
def get_token(cls, handler):
"""Get the user token from a request
Expand All @@ -129,38 +160,24 @@ def get_token(cls, handler):
return user_token

@classmethod
@_moved_to_identity_provider
def should_check_origin(cls, handler):
"""Should the Handler check for CORS origin validation?
Origin check should be skipped for token-authenticated requests.
Returns:
- True, if Handler must check for valid CORS origin.
- False, if Handler should skip origin check since requests are token-authenticated.
"""
"""DEPRECATED in 2.0, use IdentityProvider API"""
return not cls.is_token_authenticated(handler)

@classmethod
@_moved_to_identity_provider
def is_token_authenticated(cls, handler):
"""Returns True if handler has been token authenticated. Otherwise, False.
Login with a token is used to signal certain things, such as:
- permit access to REST API
- xsrf protection
- skip origin-checks for scripts
"""
"""DEPRECATED in 2.0, use IdentityProvider API"""
if getattr(handler, "_user_id", None) is None:
# ensure get_user has been called, so we know if we're token-authenticated
handler.current_user
return getattr(handler, "_token_authenticated", False)

@classmethod
@_moved_to_identity_provider
def get_user(cls, handler):
"""Called by handlers.get_current_user for identifying the current user.
See tornado.web.RequestHandler.get_current_user for details.
"""
"""DEPRECATED in 2.0, use IdentityProvider API"""
# Can't call this get_current_user because it will collide when
# called on LoginHandler itself.
if getattr(handler, "_user_id", None):
Expand Down Expand Up @@ -196,22 +213,19 @@ def get_user(cls, handler):
return user_id

@classmethod
@_moved_to_identity_provider
def get_user_cookie(cls, handler):
"""Get user-id from a cookie"""
"""DEPRECATED in 2.0, use IdentityProvider API"""
get_secure_cookie_kwargs = handler.settings.get("get_secure_cookie_kwargs", {})
user_id = handler.get_secure_cookie(handler.cookie_name, **get_secure_cookie_kwargs)
if user_id:
user_id = user_id.decode()
return user_id

@classmethod
@_moved_to_identity_provider
def get_user_token(cls, handler):
"""Identify the user based on a token in the URL or Authorization header
Returns:
- uuid if authenticated
- None if not
"""
"""DEPRECATED in 2.0, use IdentityProvider API"""
token = handler.token
if not token:
return
Expand Down Expand Up @@ -242,11 +256,9 @@ def get_user_token(cls, handler):
return None

@classmethod
@_moved_to_identity_provider
def validate_security(cls, app, ssl_options=None):
"""Check the application's security.
Show messages, or abort if necessary, based on the security configuration.
"""
"""DEPRECATED in 2.0, use IdentityProvider API"""
if not app.ip:
warning = "WARNING: The Jupyter server is listening on all IP addresses"
if ssl_options is None:
Expand All @@ -264,14 +276,14 @@ def validate_security(cls, app, ssl_options=None):
)

@classmethod
@_moved_to_identity_provider
def password_from_settings(cls, settings):
"""Return the hashed password from the tornado settings.
If there is no configured password, an empty string will be returned.
"""
"""DEPRECATED in 2.0, use IdentityProvider API"""
return settings.get("password", "")

@classmethod
@_moved_to_identity_provider
def get_login_available(cls, settings):
"""Whether this LoginHandler is needed - and therefore whether the login page should be displayed."""
"""DEPRECATED in 2.0, use IdentityProvider API"""

return bool(cls.password_from_settings(settings) or settings.get("token"))

0 comments on commit 0a1fc22

Please sign in to comment.