Merge pull request #2268 from vilhelmen/auth_data_sharing

Share authenticated dict with auth functions
This commit is contained in:
Min RK
2019-02-15 15:33:36 +01:00
committed by GitHub
3 changed files with 72 additions and 11 deletions

View File

@@ -4,11 +4,13 @@
# Distributed under the terms of the Modified BSD License.
from concurrent.futures import ThreadPoolExecutor
import inspect
import pipes
import re
from shutil import which
import sys
from subprocess import Popen, PIPE, STDOUT
import warnings
try:
import pamela
@@ -214,6 +216,38 @@ class Authenticator(LoggingConfigurable):
"""
)
def __init__(self, **kwargs):
super().__init__(**kwargs)
for method_name in ('check_whitelist', 'check_blacklist', 'check_group_whitelist'):
original_method = getattr(self, method_name, None)
if original_method is None:
# no such method (check_group_whitelist is optional)
continue
signature = inspect.signature(original_method)
if 'authentication' not in signature.parameters:
# adapt to pre-1.0 signature for compatibility
warnings.warn(
"""
{0}.{1} does not support the authentication argument,
added in JupyterHub 1.0.
It should have the signature:
def {1}(self, username, authentication=None):
...
Adapting for compatibility.
""".format(
self.__class__.__name__,
method_name,
),
DeprecationWarning
)
def wrapped_method(username, authentication=None, **kwargs):
return original_method(username, **kwargs)
setattr(self, method_name, wrapped_method)
def normalize_username(self, username):
"""Normalize the given username and return it
@@ -226,20 +260,23 @@ class Authenticator(LoggingConfigurable):
username = self.username_map.get(username, username)
return username
def check_whitelist(self, username):
def check_whitelist(self, username, authentication=None):
"""Check if a username is allowed to authenticate based on whitelist configuration
Return True if username is allowed, False otherwise.
No whitelist means any username is allowed.
Names are normalized *before* being checked against the whitelist.
.. versionchanged:: 1.0
Signature updated to accept authentication data and any future changes
"""
if not self.whitelist:
# No whitelist means any name is allowed
return True
return username in self.whitelist
def check_blacklist(self, username):
def check_blacklist(self, username, authentication=None):
"""Check if a username is blocked to authenticate based on blacklist configuration
Return True if username is allowed, False otherwise.
@@ -248,6 +285,9 @@ class Authenticator(LoggingConfigurable):
Names are normalized *before* being checked against the blacklist.
.. versionadded: 0.9
.. versionchanged:: 1.0
Signature updated to accept authentication data as second argument
"""
if not self.blacklist:
# No blacklist means any name is allowed
@@ -294,8 +334,9 @@ class Authenticator(LoggingConfigurable):
self.log.warning("Disallowing invalid username %r.", username)
return
blacklist_pass = await maybe_future(self.check_blacklist(username))
whitelist_pass = await maybe_future(self.check_whitelist(username))
blacklist_pass = await maybe_future(self.check_blacklist(username, authenticated))
whitelist_pass = await maybe_future(self.check_whitelist(username, authenticated))
if blacklist_pass:
pass
else:
@@ -351,7 +392,7 @@ class Authenticator(LoggingConfigurable):
authentication: The authetication dict generated by `authenticate`.
Returns:
admin_status (Bool or None):
The admin status of the user, or None if it could not be
The admin status of the user, or None if it could not be
determined or should not change.
"""
return True if authentication['name'] in self.admin_users else None
@@ -562,13 +603,13 @@ class LocalAuthenticator(Authenticator):
"Ignoring username whitelist because group whitelist supplied!"
)
def check_whitelist(self, username):
def check_whitelist(self, username, authentication=None):
if self.group_whitelist:
return self.check_group_whitelist(username)
return self.check_group_whitelist(username, authentication)
else:
return super().check_whitelist(username)
return super().check_whitelist(username, authentication)
def check_group_whitelist(self, username):
def check_group_whitelist(self, username, authentication=None):
"""
If group_whitelist is configured, check if authenticating user is part of group.
"""