mirror of
https://github.com/jupyterhub/jupyterhub.git
synced 2025-10-17 15:03:02 +00:00
call it allowed_users
be clearer since it's users vs groups, etc.
This commit is contained in:
@@ -7,20 +7,20 @@ with an account and password on the system will be allowed to login.
|
|||||||
## Create a set of allowed users
|
## Create a set of allowed users
|
||||||
|
|
||||||
You can restrict which users are allowed to login with a set,
|
You can restrict which users are allowed to login with a set,
|
||||||
`Authenticator.allowed`:
|
`Authenticator.allowed_users`:
|
||||||
|
|
||||||
|
|
||||||
```python
|
```python
|
||||||
c.Authenticator.allowed = {'mal', 'zoe', 'inara', 'kaylee'}
|
c.Authenticator.allowed_users = {'mal', 'zoe', 'inara', 'kaylee'}
|
||||||
```
|
```
|
||||||
|
|
||||||
Users in the allowed set are added to the Hub database when the Hub is
|
Users in the `allowed_users` set are added to the Hub database when the Hub is
|
||||||
started.
|
started.
|
||||||
|
|
||||||
## Configure admins (`admin_users`)
|
## Configure admins (`admin_users`)
|
||||||
|
|
||||||
Admin users of JupyterHub, `admin_users`, can add and remove users from
|
Admin users of JupyterHub, `admin_users`, can add and remove users from
|
||||||
the user `allowed` set. `admin_users` can take actions on other users'
|
the user `allowed_users` set. `admin_users` can take actions on other users'
|
||||||
behalf, such as stopping and restarting their servers.
|
behalf, such as stopping and restarting their servers.
|
||||||
|
|
||||||
A set of initial admin users, `admin_users` can configured be as follows:
|
A set of initial admin users, `admin_users` can configured be as follows:
|
||||||
@@ -28,7 +28,7 @@ A set of initial admin users, `admin_users` can configured be as follows:
|
|||||||
```python
|
```python
|
||||||
c.Authenticator.admin_users = {'mal', 'zoe'}
|
c.Authenticator.admin_users = {'mal', 'zoe'}
|
||||||
```
|
```
|
||||||
Users in the admin set are automatically added to the user `allowed` set,
|
Users in the admin set are automatically added to the user `allowed_users` set,
|
||||||
if they are not already present.
|
if they are not already present.
|
||||||
|
|
||||||
Each authenticator may have different ways of determining whether a user is an
|
Each authenticator may have different ways of determining whether a user is an
|
||||||
@@ -53,12 +53,12 @@ sure your users know if admin_access is enabled.**
|
|||||||
|
|
||||||
Users can be added to and removed from the Hub via either the admin
|
Users can be added to and removed from the Hub via either the admin
|
||||||
panel or the REST API. When a user is **added**, the user will be
|
panel or the REST API. When a user is **added**, the user will be
|
||||||
automatically added to the allowed set and database. Restarting the Hub
|
automatically added to the allowed users set and database. Restarting the Hub
|
||||||
will not require manually updating the allowed set in your config file,
|
will not require manually updating the allowed users set in your config file,
|
||||||
as the users will be loaded from the database.
|
as the users will be loaded from the database.
|
||||||
|
|
||||||
After starting the Hub once, it is not sufficient to **remove** a user
|
After starting the Hub once, it is not sufficient to **remove** a user
|
||||||
from the allowed set in your config file. You must also remove the user
|
from the allowed users set in your config file. You must also remove the user
|
||||||
from the Hub's database, either by deleting the user from JupyterHub's
|
from the Hub's database, either by deleting the user from JupyterHub's
|
||||||
admin page, or you can clear the `jupyterhub.sqlite` database and start
|
admin page, or you can clear the `jupyterhub.sqlite` database and start
|
||||||
fresh.
|
fresh.
|
||||||
|
@@ -52,7 +52,7 @@ c.GitHubOAuthenticator.oauth_callback_url = os.environ['OAUTH_CALLBACK_URL']
|
|||||||
c.LocalAuthenticator.create_system_users = True
|
c.LocalAuthenticator.create_system_users = True
|
||||||
|
|
||||||
# specify users and admin
|
# specify users and admin
|
||||||
c.Authenticator.allowed = {'rgbkrk', 'minrk', 'jhamrick'}
|
c.Authenticator.allowed_users = {'rgbkrk', 'minrk', 'jhamrick'}
|
||||||
c.Authenticator.admin_users = {'jhamrick', 'rgbkrk'}
|
c.Authenticator.admin_users = {'jhamrick', 'rgbkrk'}
|
||||||
|
|
||||||
# uses the default spawner
|
# uses the default spawner
|
||||||
|
@@ -1689,22 +1689,22 @@ class JupyterHub(Application):
|
|||||||
# the admin_users config variable will never be used after this point.
|
# the admin_users config variable will never be used after this point.
|
||||||
# only the database values will be referenced.
|
# only the database values will be referenced.
|
||||||
|
|
||||||
allowed = [
|
allowed_users = [
|
||||||
self.authenticator.normalize_username(name)
|
self.authenticator.normalize_username(name)
|
||||||
for name in self.authenticator.allowed
|
for name in self.authenticator.allowed_users
|
||||||
]
|
]
|
||||||
self.authenticator.allowed = set(allowed) # force normalization
|
self.authenticator.allowed_users = set(allowed_users) # force normalization
|
||||||
for username in allowed:
|
for username in allowed_users:
|
||||||
if not self.authenticator.validate_username(username):
|
if not self.authenticator.validate_username(username):
|
||||||
raise ValueError("username %r is not valid" % username)
|
raise ValueError("username %r is not valid" % username)
|
||||||
|
|
||||||
if not allowed:
|
if not allowed_users:
|
||||||
self.log.info(
|
self.log.info(
|
||||||
"Not using allowed user list. Any authenticated user will be allowed."
|
"Not using allowed_users. Any authenticated user will be allowed."
|
||||||
)
|
)
|
||||||
|
|
||||||
# add allowed users to the db
|
# add allowed users to the db
|
||||||
for name in allowed:
|
for name in allowed_users:
|
||||||
user = orm.User.find(db, name)
|
user = orm.User.find(db, name)
|
||||||
if user is None:
|
if user is None:
|
||||||
user = orm.User(name=name)
|
user = orm.User(name=name)
|
||||||
@@ -1714,9 +1714,9 @@ class JupyterHub(Application):
|
|||||||
db.commit()
|
db.commit()
|
||||||
|
|
||||||
# Notify authenticator of all users.
|
# Notify authenticator of all users.
|
||||||
# This ensures Authenticator.allowed is up-to-date with the database.
|
# This ensures Authenticator.allowed_users is up-to-date with the database.
|
||||||
# This lets .allowed be used to set up initial list,
|
# This lets .allowed_users be used to set up initial list,
|
||||||
# but changes to the allowed list can occur in the database,
|
# but changes to the allowed_users set can occur in the database,
|
||||||
# and persist across sessions.
|
# and persist across sessions.
|
||||||
total_users = 0
|
total_users = 0
|
||||||
for user in db.query(orm.User):
|
for user in db.query(orm.User):
|
||||||
@@ -1753,9 +1753,9 @@ class JupyterHub(Application):
|
|||||||
user.created = user.last_activity or datetime.utcnow()
|
user.created = user.last_activity or datetime.utcnow()
|
||||||
db.commit()
|
db.commit()
|
||||||
|
|
||||||
# The allowed set and the users in the db are now the same.
|
# The allowed_users set and the users in the db are now the same.
|
||||||
# From this point on, any user changes should be done simultaneously
|
# From this point on, any user changes should be done simultaneously
|
||||||
# to the allowed set and user db, unless the allowed set is empty (all users allowed).
|
# to the allowed_users set and user db, unless the allowed set is empty (all users allowed).
|
||||||
|
|
||||||
TOTAL_USERS.set(total_users)
|
TOTAL_USERS.set(total_users)
|
||||||
|
|
||||||
@@ -1773,7 +1773,7 @@ class JupyterHub(Application):
|
|||||||
await maybe_future(self.authenticator.check_allowed(username, None))
|
await maybe_future(self.authenticator.check_allowed(username, None))
|
||||||
):
|
):
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"Username %r is not in Authenticator.allowed" % username
|
"Username %r is not in Authenticator.allowed_users" % username
|
||||||
)
|
)
|
||||||
user = orm.User.find(db, name=username)
|
user = orm.User.find(db, name=username)
|
||||||
if user is None:
|
if user is None:
|
||||||
@@ -1801,7 +1801,8 @@ class JupyterHub(Application):
|
|||||||
await maybe_future(self.authenticator.check_allowed(name, None))
|
await maybe_future(self.authenticator.check_allowed(name, None))
|
||||||
):
|
):
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"Token user name %r is not in Authenticator.allowed" % name
|
"Token user name %r is not in Authenticator.allowed_users"
|
||||||
|
% name
|
||||||
)
|
)
|
||||||
if not self.authenticator.validate_username(name):
|
if not self.authenticator.validate_username(name):
|
||||||
raise ValueError("Token user name %r is not valid" % name)
|
raise ValueError("Token user name %r is not valid" % name)
|
||||||
|
@@ -101,9 +101,9 @@ class Authenticator(LoggingConfigurable):
|
|||||||
"""
|
"""
|
||||||
).tag(config=True)
|
).tag(config=True)
|
||||||
|
|
||||||
whitelist = Set(help="Deprecated, use `Authenticator.allowed`", config=True,)
|
whitelist = Set(help="Deprecated, use `Authenticator.allowed_users`", config=True,)
|
||||||
|
|
||||||
allowed = Set(
|
allowed_users = Set(
|
||||||
help="""
|
help="""
|
||||||
Set of usernames that are allowed to log in.
|
Set of usernames that are allowed to log in.
|
||||||
|
|
||||||
@@ -114,11 +114,11 @@ class Authenticator(LoggingConfigurable):
|
|||||||
If empty, does not perform any additional restriction.
|
If empty, does not perform any additional restriction.
|
||||||
|
|
||||||
.. versionchanged:: 1.2
|
.. versionchanged:: 1.2
|
||||||
`Authenticator.whitelist` renamed to `allowed`
|
`Authenticator.whitelist` renamed to `allowed_users`
|
||||||
"""
|
"""
|
||||||
).tag(config=True)
|
).tag(config=True)
|
||||||
|
|
||||||
blocked = Set(
|
blocked_users = Set(
|
||||||
help="""
|
help="""
|
||||||
Set of usernames that are not allowed to log in.
|
Set of usernames that are not allowed to log in.
|
||||||
|
|
||||||
@@ -131,13 +131,13 @@ class Authenticator(LoggingConfigurable):
|
|||||||
.. versionadded: 0.9
|
.. versionadded: 0.9
|
||||||
|
|
||||||
.. versionchanged:: 1.2
|
.. versionchanged:: 1.2
|
||||||
`Authenticator.blacklist` renamed to `blocked`
|
`Authenticator.blacklist` renamed to `blocked_users`
|
||||||
"""
|
"""
|
||||||
).tag(config=True)
|
).tag(config=True)
|
||||||
|
|
||||||
_deprecated_aliases = {
|
_deprecated_aliases = {
|
||||||
"whitelist": ("allowed", "1.2"),
|
"whitelist": ("allowed_users", "1.2"),
|
||||||
"blacklist": ("blocked", "1.2"),
|
"blacklist": ("blocked_users", "1.2"),
|
||||||
}
|
}
|
||||||
|
|
||||||
@observe(*list(_deprecated_aliases))
|
@observe(*list(_deprecated_aliases))
|
||||||
@@ -160,15 +160,15 @@ class Authenticator(LoggingConfigurable):
|
|||||||
)
|
)
|
||||||
setattr(self, new_attr, change.new)
|
setattr(self, new_attr, change.new)
|
||||||
|
|
||||||
@observe('allowed')
|
@observe('allowed_users')
|
||||||
def _check_allowed(self, change):
|
def _check_allowed_users(self, change):
|
||||||
short_names = [name for name in change['new'] if len(name) <= 1]
|
short_names = [name for name in change['new'] if len(name) <= 1]
|
||||||
if short_names:
|
if short_names:
|
||||||
sorted_names = sorted(short_names)
|
sorted_names = sorted(short_names)
|
||||||
single = ''.join(sorted_names)
|
single = ''.join(sorted_names)
|
||||||
string_set_typo = "set('%s')" % single
|
string_set_typo = "set('%s')" % single
|
||||||
self.log.warning(
|
self.log.warning(
|
||||||
"Allowed list contains single-character names: %s; did you mean set([%r]) instead of %s?",
|
"Allowed set contains single-character names: %s; did you mean set([%r]) instead of %s?",
|
||||||
sorted_names[:8],
|
sorted_names[:8],
|
||||||
single,
|
single,
|
||||||
string_set_typo,
|
string_set_typo,
|
||||||
@@ -301,7 +301,7 @@ class Authenticator(LoggingConfigurable):
|
|||||||
# with correct subclass override priority!
|
# with correct subclass override priority!
|
||||||
for old_name, new_name in (
|
for old_name, new_name in (
|
||||||
('check_whitelist', 'check_allowed'),
|
('check_whitelist', 'check_allowed'),
|
||||||
('check_blacklist', 'check_blocked'),
|
('check_blacklist', 'check_blocked_users'),
|
||||||
('check_group_whitelist', 'check_allowed_groups'),
|
('check_group_whitelist', 'check_allowed_groups'),
|
||||||
):
|
):
|
||||||
old_method = getattr(self, old_name, None)
|
old_method = getattr(self, old_name, None)
|
||||||
@@ -399,7 +399,7 @@ class Authenticator(LoggingConfigurable):
|
|||||||
"""Check if a username is allowed to authenticate based on configuration
|
"""Check if a username is allowed to authenticate based on configuration
|
||||||
|
|
||||||
Return True if username is allowed, False otherwise.
|
Return True if username is allowed, False otherwise.
|
||||||
No allowed set means any username is allowed.
|
No allowed_users set means any username is allowed.
|
||||||
|
|
||||||
Names are normalized *before* being checked against the allowed set.
|
Names are normalized *before* being checked against the allowed set.
|
||||||
|
|
||||||
@@ -409,12 +409,12 @@ class Authenticator(LoggingConfigurable):
|
|||||||
.. versionchanged:: 1.2
|
.. versionchanged:: 1.2
|
||||||
Renamed check_whitelist to check_allowed
|
Renamed check_whitelist to check_allowed
|
||||||
"""
|
"""
|
||||||
if not self.allowed:
|
if not self.allowed_users:
|
||||||
# No allowed set means any name is allowed
|
# No allowed set means any name is allowed
|
||||||
return True
|
return True
|
||||||
return username in self.allowed
|
return username in self.allowed_users
|
||||||
|
|
||||||
def check_blocked(self, username, authentication=None):
|
def check_blocked_users(self, username, authentication=None):
|
||||||
"""Check if a username is blocked to authenticate based on Authenticator.blocked configuration
|
"""Check if a username is blocked to authenticate based on Authenticator.blocked configuration
|
||||||
|
|
||||||
Return True if username is allowed, False otherwise.
|
Return True if username is allowed, False otherwise.
|
||||||
@@ -428,12 +428,12 @@ class Authenticator(LoggingConfigurable):
|
|||||||
Signature updated to accept authentication data as second argument
|
Signature updated to accept authentication data as second argument
|
||||||
|
|
||||||
.. versionchanged:: 1.2
|
.. versionchanged:: 1.2
|
||||||
Renamed check_blacklist to check_blocked
|
Renamed check_blacklist to check_blocked_users
|
||||||
"""
|
"""
|
||||||
if not self.blocked:
|
if not self.blocked_users:
|
||||||
# No block list means any name is allowed
|
# No block list means any name is allowed
|
||||||
return True
|
return True
|
||||||
return username not in self.blocked
|
return username not in self.blocked_users
|
||||||
|
|
||||||
async def get_authenticated_user(self, handler, data):
|
async def get_authenticated_user(self, handler, data):
|
||||||
"""Authenticate the user who is attempting to log in
|
"""Authenticate the user who is attempting to log in
|
||||||
@@ -450,7 +450,7 @@ class Authenticator(LoggingConfigurable):
|
|||||||
The various stages can be overridden separately:
|
The various stages can be overridden separately:
|
||||||
- `authenticate` turns formdata into a username
|
- `authenticate` turns formdata into a username
|
||||||
- `normalize_username` normalizes the username
|
- `normalize_username` normalizes the username
|
||||||
- `check_allowed` checks against the user allowed
|
- `check_allowed` checks against the allowed usernames
|
||||||
|
|
||||||
.. versionchanged:: 0.8
|
.. versionchanged:: 0.8
|
||||||
return dict instead of username
|
return dict instead of username
|
||||||
@@ -475,7 +475,9 @@ class Authenticator(LoggingConfigurable):
|
|||||||
self.log.warning("Disallowing invalid username %r.", username)
|
self.log.warning("Disallowing invalid username %r.", username)
|
||||||
return
|
return
|
||||||
|
|
||||||
blocked_pass = await maybe_future(self.check_blocked(username, authenticated))
|
blocked_pass = await maybe_future(
|
||||||
|
self.check_blocked_users(username, authenticated)
|
||||||
|
)
|
||||||
allowed_pass = await maybe_future(self.check_allowed(username, authenticated))
|
allowed_pass = await maybe_future(self.check_allowed(username, authenticated))
|
||||||
|
|
||||||
if blocked_pass:
|
if blocked_pass:
|
||||||
@@ -550,7 +552,7 @@ class Authenticator(LoggingConfigurable):
|
|||||||
It must return the username on successful authentication,
|
It must return the username on successful authentication,
|
||||||
and return None on failed authentication.
|
and return None on failed authentication.
|
||||||
|
|
||||||
Checking allowed/blocked is handled separately by the caller.
|
Checking allowed_users/blocked_users is handled separately by the caller.
|
||||||
|
|
||||||
.. versionchanged:: 0.8
|
.. versionchanged:: 0.8
|
||||||
Allow `authenticate` to return a dict containing auth_state.
|
Allow `authenticate` to return a dict containing auth_state.
|
||||||
@@ -591,10 +593,10 @@ class Authenticator(LoggingConfigurable):
|
|||||||
|
|
||||||
This method may be a coroutine.
|
This method may be a coroutine.
|
||||||
|
|
||||||
By default, this just adds the user to the allowed set.
|
By default, this just adds the user to the allowed_users set.
|
||||||
|
|
||||||
Subclasses may do more extensive things, such as adding actual unix users,
|
Subclasses may do more extensive things, such as adding actual unix users,
|
||||||
but they should call super to ensure the allowed set is updated.
|
but they should call super to ensure the allowed_users set is updated.
|
||||||
|
|
||||||
Note that this should be idempotent, since it is called whenever the hub restarts
|
Note that this should be idempotent, since it is called whenever the hub restarts
|
||||||
for all users.
|
for all users.
|
||||||
@@ -604,19 +606,19 @@ class Authenticator(LoggingConfigurable):
|
|||||||
"""
|
"""
|
||||||
if not self.validate_username(user.name):
|
if not self.validate_username(user.name):
|
||||||
raise ValueError("Invalid username: %s" % user.name)
|
raise ValueError("Invalid username: %s" % user.name)
|
||||||
if self.allowed:
|
if self.allowed_users:
|
||||||
self.allowed.add(user.name)
|
self.allowed_users.add(user.name)
|
||||||
|
|
||||||
def delete_user(self, user):
|
def delete_user(self, user):
|
||||||
"""Hook called when a user is deleted
|
"""Hook called when a user is deleted
|
||||||
|
|
||||||
Removes the user from the allowed set.
|
Removes the user from the allowed_users set.
|
||||||
Subclasses should call super to ensure the allowed set is updated.
|
Subclasses should call super to ensure the allowed_users set is updated.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
user (User): The User wrapper object
|
user (User): The User wrapper object
|
||||||
"""
|
"""
|
||||||
self.allowed.discard(user.name)
|
self.allowed_users.discard(user.name)
|
||||||
|
|
||||||
auto_login = Bool(
|
auto_login = Bool(
|
||||||
False,
|
False,
|
||||||
@@ -709,7 +711,7 @@ import types
|
|||||||
# deprecate white/blacklist method names
|
# deprecate white/blacklist method names
|
||||||
for _old_name, _new_name, _version in [
|
for _old_name, _new_name, _version in [
|
||||||
("check_whitelist", "check_allowed", "1.2"),
|
("check_whitelist", "check_allowed", "1.2"),
|
||||||
("check_blacklist", "check_blocked", "1.2"),
|
("check_blacklist", "check_blocked_users", "1.2"),
|
||||||
]:
|
]:
|
||||||
setattr(
|
setattr(
|
||||||
Authenticator, _old_name, _deprecated_method(_old_name, _new_name, _version),
|
Authenticator, _old_name, _deprecated_method(_old_name, _new_name, _version),
|
||||||
@@ -788,9 +790,9 @@ class LocalAuthenticator(Authenticator):
|
|||||||
@observe('allowed_groups')
|
@observe('allowed_groups')
|
||||||
def _allowed_groups_changed(self, change):
|
def _allowed_groups_changed(self, change):
|
||||||
"""Log a warning if mutually exclusive user and group allowed sets are specified."""
|
"""Log a warning if mutually exclusive user and group allowed sets are specified."""
|
||||||
if self.allowed:
|
if self.allowed_users:
|
||||||
self.log.warning(
|
self.log.warning(
|
||||||
"Ignoring Authenticator.allowed set because Authenticator.allowed_groups supplied!"
|
"Ignoring Authenticator.allowed_users set because Authenticator.allowed_groups supplied!"
|
||||||
)
|
)
|
||||||
|
|
||||||
def check_allowed(self, username, authentication=None):
|
def check_allowed(self, username, authentication=None):
|
||||||
|
@@ -93,7 +93,7 @@ def test_generate_config():
|
|||||||
os.remove(cfg_file)
|
os.remove(cfg_file)
|
||||||
assert cfg_file in out
|
assert cfg_file in out
|
||||||
assert 'Spawner.cmd' in cfg_text
|
assert 'Spawner.cmd' in cfg_text
|
||||||
assert 'Authenticator.allowed' in cfg_text
|
assert 'Authenticator.allowed_users' in cfg_text
|
||||||
|
|
||||||
|
|
||||||
async def test_init_tokens(request):
|
async def test_init_tokens(request):
|
||||||
|
@@ -141,7 +141,7 @@ async def test_pam_auth_admin_groups():
|
|||||||
|
|
||||||
|
|
||||||
async def test_pam_auth_allowed():
|
async def test_pam_auth_allowed():
|
||||||
authenticator = MockPAMAuthenticator(allowed={'wash', 'kaylee'})
|
authenticator = MockPAMAuthenticator(allowed_users={'wash', 'kaylee'})
|
||||||
authorized = await authenticator.get_authenticated_user(
|
authorized = await authenticator.get_authenticated_user(
|
||||||
None, {'username': 'kaylee', 'password': 'kaylee'}
|
None, {'username': 'kaylee', 'password': 'kaylee'}
|
||||||
)
|
)
|
||||||
@@ -186,41 +186,51 @@ async def test_pam_auth_blocked():
|
|||||||
assert authorized['name'] == 'wash'
|
assert authorized['name'] == 'wash'
|
||||||
|
|
||||||
# Blacklist basics
|
# Blacklist basics
|
||||||
authenticator = MockPAMAuthenticator(blocked={'wash'})
|
authenticator = MockPAMAuthenticator(blocked_users={'wash'})
|
||||||
authorized = await authenticator.get_authenticated_user(
|
authorized = await authenticator.get_authenticated_user(
|
||||||
None, {'username': 'wash', 'password': 'wash'}
|
None, {'username': 'wash', 'password': 'wash'}
|
||||||
)
|
)
|
||||||
assert authorized is None
|
assert authorized is None
|
||||||
|
|
||||||
# User in both allowed and blocked: default deny. Make error someday?
|
# User in both allowed and blocked: default deny. Make error someday?
|
||||||
authenticator = MockPAMAuthenticator(blocked={'wash'}, allowed={'wash', 'kaylee'})
|
authenticator = MockPAMAuthenticator(
|
||||||
|
blocked_users={'wash'}, allowed_users={'wash', 'kaylee'}
|
||||||
|
)
|
||||||
authorized = await authenticator.get_authenticated_user(
|
authorized = await authenticator.get_authenticated_user(
|
||||||
None, {'username': 'wash', 'password': 'wash'}
|
None, {'username': 'wash', 'password': 'wash'}
|
||||||
)
|
)
|
||||||
assert authorized is None
|
assert authorized is None
|
||||||
|
|
||||||
# User not in blocked set can log in
|
# User not in blocked set can log in
|
||||||
authenticator = MockPAMAuthenticator(blocked={'wash'}, allowed={'wash', 'kaylee'})
|
authenticator = MockPAMAuthenticator(
|
||||||
|
blocked_users={'wash'}, allowed_users={'wash', 'kaylee'}
|
||||||
|
)
|
||||||
authorized = await authenticator.get_authenticated_user(
|
authorized = await authenticator.get_authenticated_user(
|
||||||
None, {'username': 'kaylee', 'password': 'kaylee'}
|
None, {'username': 'kaylee', 'password': 'kaylee'}
|
||||||
)
|
)
|
||||||
assert authorized['name'] == 'kaylee'
|
assert authorized['name'] == 'kaylee'
|
||||||
|
|
||||||
# User in allowed, blocked irrelevent
|
# User in allowed, blocked irrelevent
|
||||||
authenticator = MockPAMAuthenticator(blocked={'mal'}, allowed={'wash', 'kaylee'})
|
authenticator = MockPAMAuthenticator(
|
||||||
|
blocked_users={'mal'}, allowed_users={'wash', 'kaylee'}
|
||||||
|
)
|
||||||
authorized = await authenticator.get_authenticated_user(
|
authorized = await authenticator.get_authenticated_user(
|
||||||
None, {'username': 'wash', 'password': 'wash'}
|
None, {'username': 'wash', 'password': 'wash'}
|
||||||
)
|
)
|
||||||
assert authorized['name'] == 'wash'
|
assert authorized['name'] == 'wash'
|
||||||
|
|
||||||
# User in neither list
|
# User in neither list
|
||||||
authenticator = MockPAMAuthenticator(blocked={'mal'}, allowed={'wash', 'kaylee'})
|
authenticator = MockPAMAuthenticator(
|
||||||
|
blocked_users={'mal'}, allowed_users={'wash', 'kaylee'}
|
||||||
|
)
|
||||||
authorized = await authenticator.get_authenticated_user(
|
authorized = await authenticator.get_authenticated_user(
|
||||||
None, {'username': 'simon', 'password': 'simon'}
|
None, {'username': 'simon', 'password': 'simon'}
|
||||||
)
|
)
|
||||||
assert authorized is None
|
assert authorized is None
|
||||||
|
|
||||||
authenticator = MockPAMAuthenticator(blocked=set(), allowed={'wash', 'kaylee'})
|
authenticator = MockPAMAuthenticator(
|
||||||
|
blocked_users=set(), allowed_users={'wash', 'kaylee'}
|
||||||
|
)
|
||||||
authorized = await authenticator.get_authenticated_user(
|
authorized = await authenticator.get_authenticated_user(
|
||||||
None, {'username': 'kaylee', 'password': 'kaylee'}
|
None, {'username': 'kaylee', 'password': 'kaylee'}
|
||||||
)
|
)
|
||||||
@@ -256,7 +266,7 @@ async def test_pam_auth_no_such_group():
|
|||||||
|
|
||||||
async def test_wont_add_system_user():
|
async def test_wont_add_system_user():
|
||||||
user = orm.User(name='lioness4321')
|
user = orm.User(name='lioness4321')
|
||||||
authenticator = auth.PAMAuthenticator(allowed={'mal'})
|
authenticator = auth.PAMAuthenticator(allowed_users={'mal'})
|
||||||
authenticator.create_system_users = False
|
authenticator.create_system_users = False
|
||||||
with pytest.raises(KeyError):
|
with pytest.raises(KeyError):
|
||||||
await authenticator.add_user(user)
|
await authenticator.add_user(user)
|
||||||
@@ -264,7 +274,7 @@ async def test_wont_add_system_user():
|
|||||||
|
|
||||||
async def test_cant_add_system_user():
|
async def test_cant_add_system_user():
|
||||||
user = orm.User(name='lioness4321')
|
user = orm.User(name='lioness4321')
|
||||||
authenticator = auth.PAMAuthenticator(allowed={'mal'})
|
authenticator = auth.PAMAuthenticator(allowed_users={'mal'})
|
||||||
authenticator.add_user_cmd = ['jupyterhub-fake-command']
|
authenticator.add_user_cmd = ['jupyterhub-fake-command']
|
||||||
authenticator.create_system_users = True
|
authenticator.create_system_users = True
|
||||||
|
|
||||||
@@ -290,7 +300,7 @@ async def test_cant_add_system_user():
|
|||||||
|
|
||||||
async def test_add_system_user():
|
async def test_add_system_user():
|
||||||
user = orm.User(name='lioness4321')
|
user = orm.User(name='lioness4321')
|
||||||
authenticator = auth.PAMAuthenticator(allowed={'mal'})
|
authenticator = auth.PAMAuthenticator(allowed_users={'mal'})
|
||||||
authenticator.create_system_users = True
|
authenticator.create_system_users = True
|
||||||
authenticator.add_user_cmd = ['echo', '/home/USERNAME']
|
authenticator.add_user_cmd = ['echo', '/home/USERNAME']
|
||||||
|
|
||||||
@@ -311,13 +321,13 @@ async def test_add_system_user():
|
|||||||
|
|
||||||
async def test_delete_user():
|
async def test_delete_user():
|
||||||
user = orm.User(name='zoe')
|
user = orm.User(name='zoe')
|
||||||
a = MockPAMAuthenticator(allowed={'mal'})
|
a = MockPAMAuthenticator(allowed_users={'mal'})
|
||||||
|
|
||||||
assert 'zoe' not in a.allowed
|
assert 'zoe' not in a.allowed_users
|
||||||
await a.add_user(user)
|
await a.add_user(user)
|
||||||
assert 'zoe' in a.allowed
|
assert 'zoe' in a.allowed_users
|
||||||
a.delete_user(user)
|
a.delete_user(user)
|
||||||
assert 'zoe' not in a.allowed
|
assert 'zoe' not in a.allowed_users
|
||||||
|
|
||||||
|
|
||||||
def test_urls():
|
def test_urls():
|
||||||
@@ -472,10 +482,10 @@ def test_deprecated_config(caplog):
|
|||||||
log.name,
|
log.name,
|
||||||
logging.WARNING,
|
logging.WARNING,
|
||||||
'Authenticator.whitelist is deprecated in JupyterHub 1.2, use '
|
'Authenticator.whitelist is deprecated in JupyterHub 1.2, use '
|
||||||
'Authenticator.allowed instead',
|
'Authenticator.allowed_users instead',
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
assert authenticator.allowed == {'user'}
|
assert authenticator.allowed_users == {'user'}
|
||||||
|
|
||||||
|
|
||||||
def test_deprecated_methods():
|
def test_deprecated_methods():
|
||||||
@@ -496,7 +506,7 @@ def test_deprecated_config_subclass():
|
|||||||
cfg.MyAuthenticator.whitelist = {'user'}
|
cfg.MyAuthenticator.whitelist = {'user'}
|
||||||
with pytest.deprecated_call():
|
with pytest.deprecated_call():
|
||||||
authenticator = MyAuthenticator(config=cfg)
|
authenticator = MyAuthenticator(config=cfg)
|
||||||
assert authenticator.allowed == {'user'}
|
assert authenticator.allowed_users == {'user'}
|
||||||
|
|
||||||
|
|
||||||
def test_deprecated_methods_subclass():
|
def test_deprecated_methods_subclass():
|
||||||
|
Reference in New Issue
Block a user