From 33a4f315205d28c96b2b2642bc53ce2eea27f286 Mon Sep 17 00:00:00 2001 From: Scott Sanderson Date: Wed, 18 Mar 2015 19:20:10 -0400 Subject: [PATCH 1/3] DEV: Allow setting a whitelist_group on LocalAuthenticator. Any user in the group is considered in the whitelist. --- jupyterhub/auth.py | 38 +++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/jupyterhub/auth.py b/jupyterhub/auth.py index 7daa97bb..f7c99528 100644 --- a/jupyterhub/auth.py +++ b/jupyterhub/auth.py @@ -3,6 +3,7 @@ # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. +from grp import getgrnam import pwd from subprocess import check_call, check_output, CalledProcessError @@ -39,7 +40,14 @@ class Authenticator(LoggingConfigurable): It must return the username on successful authentication, and return None on failed authentication. """ - + + def check_whitelist(self, user): + """ + Return True if the whitelist is empty or user is in the whitelist. + """ + # Parens aren't necessary here, but they make this easier to parse. + return (not self.whitelist) or (user in self.whitelist) + def add_user(self, user): """Add a new user @@ -56,8 +64,7 @@ class Authenticator(LoggingConfigurable): Removes the user from the whitelist. """ - if user.name in self.whitelist: - self.whitelist.remove(user.name) + self.whitelist.discard(user.name) def login_url(self, base_url): """Override to register a custom login handler""" @@ -87,7 +94,28 @@ class LocalAuthenticator(Authenticator): should I try to create the system user? """ ) - + + whitelist_group = Unicode( + config=True, + help="Automatically whitelist anyone in this group.", + ) + + def check_whitelist(self, username): + return ( + super().check_whitelist(username) or + self.check_whitelist_group(username) + ) + + def check_whitelist_group(self, username): + if not self.whitelist_group: + return False + try: + group = getgrnam(self.whitelist_group) + except KeyError: + self.log.error('No such group: [%s]' % self.whitelist_group) + return False + return username in group.gr_mem + @gen.coroutine def add_user(self, user): """Add a new user @@ -152,7 +180,7 @@ class PAMAuthenticator(LocalAuthenticator): Return None otherwise. """ username = data['username'] - if self.whitelist and username not in self.whitelist: + if not self.check_whitelist(username): return # simplepam wants bytes, not unicode # see simplepam#3 From 77c66d8b275b0abe1149685b39d432cef95a630c Mon Sep 17 00:00:00 2001 From: Scott Sanderson Date: Thu, 19 Mar 2015 10:42:55 -0400 Subject: [PATCH 2/3] DEV: Make group/user whitelist mutually exclusive. If group whitelist is provided, it takes precedence. --- jupyterhub/auth.py | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/jupyterhub/auth.py b/jupyterhub/auth.py index f7c99528..a72b5f97 100644 --- a/jupyterhub/auth.py +++ b/jupyterhub/auth.py @@ -95,24 +95,30 @@ class LocalAuthenticator(Authenticator): """ ) - whitelist_group = Unicode( + group_whitelist = Set( config=True, help="Automatically whitelist anyone in this group.", ) - def check_whitelist(self, username): - return ( - super().check_whitelist(username) or - self.check_whitelist_group(username) - ) + def _group_whitelist_changed(self, name, old, new): + if self.whitelist: + self.log.warn( + "Ignoring username whitelist because group whitelist supplied!" + ) - def check_whitelist_group(self, username): - if not self.whitelist_group: + def check_whitelist(self, username): + if self.group_whitelist: + return self.check_group_whitelist(username) + else: + return super().check_whitelist(username) + + def check_group_whitelist(self, username): + if not self.group_whitelist: return False try: - group = getgrnam(self.whitelist_group) + group = getgrnam(self.group_whitelist) except KeyError: - self.log.error('No such group: [%s]' % self.whitelist_group) + self.log.error('No such group: [%s]' % self.group_whitelist) return False return username in group.gr_mem From ed94c2d77478d1eac7331dac305e36218c713135 Mon Sep 17 00:00:00 2001 From: Scott Sanderson Date: Sun, 22 Mar 2015 14:51:10 -0400 Subject: [PATCH 3/3] BUG: group_whitelist is a set, not a scalar. --- jupyterhub/auth.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/jupyterhub/auth.py b/jupyterhub/auth.py index a72b5f97..67ab8c51 100644 --- a/jupyterhub/auth.py +++ b/jupyterhub/auth.py @@ -115,12 +115,15 @@ class LocalAuthenticator(Authenticator): def check_group_whitelist(self, username): if not self.group_whitelist: return False - try: - group = getgrnam(self.group_whitelist) - except KeyError: - self.log.error('No such group: [%s]' % self.group_whitelist) - return False - return username in group.gr_mem + for group in self.group_whitelist: + try: + group = getgrnam(self.group_whitelist) + except KeyError: + self.log.error('No such group: [%s]' % self.group_whitelist) + continue + if username in group.gr_mem: + return True + return False @gen.coroutine def add_user(self, user):