Allow disabling user creation on login

This forces admins to create users manually - via config
or the admin panel, before they can log in.
This commit is contained in:
yuvipanda 2018-07-03 16:07:42 -07:00
parent 7e8b97ce4e
commit 4f87418efc
2 changed files with 46 additions and 12 deletions

View file

@ -1,10 +1,10 @@
# JupyterHub First Use Authenticator #
A [JupyterHub](https://jupyterhub.readthedocs.io) authenticator that helps new users set their password on their first login to JupyterHub.
A [JupyterHub](https://jupyterhub.readthedocs.io) authenticator that helps new users set their password on their first login to JupyterHub.
**Are you running a workshop from a single physical location, such as a university seminar or a user group?**
JupyterHub First Use Authenticator can simplify the user set up for you. It's very useful when using transient
JupyterHub First Use Authenticator can simplify the user set up for you. It's very useful when using transient
JupyterHub instances in a single physical location. It allows multiple users to log in, but you do not have install a pre-existing authentication setup. With this authenticator, users can just pick a username and password and get to work!
## Installation ##
@ -23,10 +23,18 @@ c.JupyterHub.authenticator_class = 'firstuseauthenticator.FirstUseAuthenticator'
## Configuration ##
It works out of the box as advertised. There is one configuration parameter, `dbm_path`, which you can tweak.
### FirstUseAuthenticator.dbm_path ###
Path to the [dbm](https://docs.python.org/3.5/library/dbm.html) file, or a UNIX database file such as `passwords.dbm`, used to store usernames and passwords. The dbm file should be put where regular users do not have read/write access to it.
This authenticator's default setting for the path to the `passwords.dbm` is the current directory from which JupyterHub is spawned.
### FirstUseAuthenticator.create_users ###
Create users if they do not exist already.
When set to False, users would have to be explicitly created before
they can log in. Users can be created via the admin panel or by setting
whitelist / admin list.
Defaults to True.

View file

@ -7,9 +7,10 @@ locally in a dbm file, and checked next time they log in.
"""
import dbm
from jupyterhub.auth import Authenticator
from jupyterhub.orm import User
from tornado import gen
from traitlets.traitlets import Unicode
from traitlets.traitlets import Unicode, Bool
import bcrypt
@ -26,16 +27,41 @@ class FirstUseAuthenticator(Authenticator):
"""
)
create_users = Bool(
True,
config=True,
help="""
Create users if they do not exist already.
When set to false, users would have to be explicitly created before
they can log in. Users can be created via the admin panel or by setting
whitelist / admin list.
"""
)
def _user_exists(self, username):
"""
Return true if given user already exists.
Note: Depends on internal details of JupyterHub that might change
across versions. Tested with v0.9
"""
return self.db.query(User).filter_by(name=username).first() is not None
@gen.coroutine
def authenticate(self, handler, data):
# Move everything to bytes
username = data['username'].encode('utf-8')
password = data['password'].encode('utf-8')
username = data['username']
if not self.create_users:
if not self._user_exists(username):
return None
password = data['password']
with dbm.open(self.dbm_path, 'c', 0o600) as db:
stored_pw = db.get(username, None)
stored_pw = db.get(username.encode(), None)
if stored_pw is not None:
if bcrypt.hashpw(password, stored_pw) != stored_pw:
if bcrypt.hashpw(password.encode(), stored_pw) != stored_pw:
return None
else:
db[username] = bcrypt.hashpw(password, bcrypt.gensalt())
return data['username']
db[username] = bcrypt.hashpw(password.encode(), bcrypt.gensalt())
return username