mirror of
https://github.com/jupyterhub/jupyterhub.git
synced 2025-10-19 07:53:00 +00:00
Add Authenticator.add_user hook
and .delete_user This hook can be used to trigger events, such as user validation, or creating of system users. Adds a LocalAuthenticator class that implements checking for and rudimentary creation of system users.
This commit is contained in:
@@ -3,11 +3,14 @@
|
||||
# Copyright (c) IPython Development Team.
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
import pwd
|
||||
from subprocess import check_call, check_output, CalledProcessError
|
||||
|
||||
from tornado import gen
|
||||
import simplepam
|
||||
|
||||
from IPython.config import LoggingConfigurable
|
||||
from IPython.utils.traitlets import Unicode, Set
|
||||
from IPython.utils.traitlets import Bool, Set, Unicode
|
||||
|
||||
from .utils import url_path_join
|
||||
|
||||
@@ -35,6 +38,25 @@ class Authenticator(LoggingConfigurable):
|
||||
and return None on failed authentication.
|
||||
"""
|
||||
|
||||
def add_user(self, user):
|
||||
"""Add a new user
|
||||
|
||||
By default, this just adds the user to the whitelist.
|
||||
|
||||
Subclasses may do more extensive things,
|
||||
such as adding actual unix users.
|
||||
"""
|
||||
if self.whitelist:
|
||||
self.whitelist.add(user.name)
|
||||
|
||||
def delete_user(self, user):
|
||||
"""Triggered when a user is deleted.
|
||||
|
||||
Removes the user from the whitelist.
|
||||
"""
|
||||
if user.name in self.whitelist:
|
||||
self.whitelist.remove(user.name)
|
||||
|
||||
def login_url(self, base_url):
|
||||
"""Override to register a custom login handler"""
|
||||
return url_path_join(base_url, 'login')
|
||||
@@ -50,10 +72,66 @@ class Authenticator(LoggingConfigurable):
|
||||
"""
|
||||
return []
|
||||
|
||||
class LocalAuthenticator(Authenticator):
|
||||
"""Base class for Authenticators that work with local *ix users
|
||||
|
||||
Checks for local users, and can attempt to create them if they exist.
|
||||
"""
|
||||
|
||||
create_system_users = Bool(False, config=True,
|
||||
help="""If a user is added that doesn't exist on the system,
|
||||
should I try to create the system user?
|
||||
"""
|
||||
)
|
||||
|
||||
def add_user(self, user):
|
||||
"""Add a new user
|
||||
|
||||
By default, this just adds the user to the whitelist.
|
||||
|
||||
Subclasses may do more extensive things,
|
||||
such as adding actual unix users.
|
||||
"""
|
||||
if not self.system_user_exists(user):
|
||||
if self.create_system_users:
|
||||
self.add_system_user(user)
|
||||
else:
|
||||
raise KeyError("User %s does not exist." % user.name)
|
||||
|
||||
super(LocalAuthenticator, self).add_user(user)
|
||||
|
||||
def system_user_exists(self, user):
|
||||
"""Check if the user exists on the system"""
|
||||
try:
|
||||
pwd.getpwnam(user.name)
|
||||
except KeyError:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
def add_system_user(user):
|
||||
"""Create a new *ix user on the system. Works on FreeBSD and Linux, at least."""
|
||||
name = user.name
|
||||
for useradd in (
|
||||
['pw', 'useradd', '-m'],
|
||||
['useradd', '-m'],
|
||||
):
|
||||
try:
|
||||
check_output(['which', useradd[0]])
|
||||
except CalledProcessError:
|
||||
continue
|
||||
else:
|
||||
break
|
||||
else:
|
||||
raise RuntimeError("I don't know how to add users on this system.")
|
||||
|
||||
check_call(useradd + [name])
|
||||
|
||||
class PAMAuthenticator(Authenticator):
|
||||
|
||||
class PAMAuthenticator(LocalAuthenticator):
|
||||
"""Authenticate local *ix users with PAM"""
|
||||
encoding = Unicode('utf8', config=True,
|
||||
help="""The encoding to use for PAM """
|
||||
help="""The encoding to use for PAM"""
|
||||
)
|
||||
service = Unicode('login', config=True,
|
||||
help="""The PAM service to use for authentication."""
|
||||
|
Reference in New Issue
Block a user