mirror of
https://github.com/jupyterhub/jupyterhub.git
synced 2025-10-08 18:44:10 +00:00
Resolves sql warnings on 3.6 and fixes for scope expansion bug
This commit is contained in:
@@ -1960,7 +1960,7 @@ class JupyterHub(Application):
|
|||||||
user = orm.User.find(self.db, name=username)
|
user = orm.User.find(self.db, name=username)
|
||||||
if user is None:
|
if user is None:
|
||||||
if not self.authenticator.validate_username(username):
|
if not self.authenticator.validate_username(username):
|
||||||
raise ValueError("Group username %r is not valid" % username)
|
raise ValueError("Username %r is not valid" % username)
|
||||||
self.log.info(f"Creating user {username}")
|
self.log.info(f"Creating user {username}")
|
||||||
user = orm.User(name=username)
|
user = orm.User(name=username)
|
||||||
self.db.add(user)
|
self.db.add(user)
|
||||||
@@ -2301,15 +2301,18 @@ class JupyterHub(Application):
|
|||||||
service.orm.server = None
|
service.orm.server = None
|
||||||
|
|
||||||
if service.oauth_available:
|
if service.oauth_available:
|
||||||
|
allowed_roles = []
|
||||||
|
if service.oauth_roles:
|
||||||
|
allowed_roles = list(
|
||||||
|
self.db.query(orm.Role).filter(
|
||||||
|
orm.Role.name.in_(service.oauth_roles)
|
||||||
|
)
|
||||||
|
)
|
||||||
oauth_client = self.oauth_provider.add_client(
|
oauth_client = self.oauth_provider.add_client(
|
||||||
client_id=service.oauth_client_id,
|
client_id=service.oauth_client_id,
|
||||||
client_secret=service.api_token,
|
client_secret=service.api_token,
|
||||||
redirect_uri=service.oauth_redirect_uri,
|
redirect_uri=service.oauth_redirect_uri,
|
||||||
allowed_roles=list(
|
allowed_roles=allowed_roles,
|
||||||
self.db.query(orm.Role).filter(
|
|
||||||
orm.Role.name.in_(service.oauth_roles)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
description="JupyterHub service %s" % service.name,
|
description="JupyterHub service %s" % service.name,
|
||||||
)
|
)
|
||||||
service.orm.oauth_client = oauth_client
|
service.orm.oauth_client = oauth_client
|
||||||
|
@@ -717,7 +717,7 @@ class APIToken(Hashed, Base):
|
|||||||
|
|
||||||
db.add(orm_token)
|
db.add(orm_token)
|
||||||
if not Role.find(db, 'token'):
|
if not Role.find(db, 'token'):
|
||||||
raise AttributeError("Default token role has not been created")
|
raise RuntimeError("Default token role has not been created")
|
||||||
try:
|
try:
|
||||||
if roles is not None:
|
if roles is not None:
|
||||||
update_roles(db, entity=orm_token, roles=roles)
|
update_roles(db, entity=orm_token, roles=roles)
|
||||||
|
@@ -183,9 +183,8 @@ def _get_subscopes(*roles, owner=None):
|
|||||||
scopes.update(role.scopes)
|
scopes.update(role.scopes)
|
||||||
|
|
||||||
expanded_scopes = set(chain.from_iterable(list(map(_expand_scope, scopes))))
|
expanded_scopes = set(chain.from_iterable(list(map(_expand_scope, scopes))))
|
||||||
|
|
||||||
# transform !user filter to !user=ownername
|
# transform !user filter to !user=ownername
|
||||||
for scope in expanded_scopes:
|
for scope in expanded_scopes.copy():
|
||||||
base_scope, _, filter = scope.partition('!')
|
base_scope, _, filter = scope.partition('!')
|
||||||
if filter == 'user':
|
if filter == 'user':
|
||||||
expanded_scopes.remove(scope)
|
expanded_scopes.remove(scope)
|
||||||
@@ -198,7 +197,6 @@ def _get_subscopes(*roles, owner=None):
|
|||||||
name = owner.name
|
name = owner.name
|
||||||
trans_scope = f'{base_scope}!user={name}'
|
trans_scope = f'{base_scope}!user={name}'
|
||||||
expanded_scopes.add(trans_scope)
|
expanded_scopes.add(trans_scope)
|
||||||
|
|
||||||
if 'self' in expanded_scopes:
|
if 'self' in expanded_scopes:
|
||||||
expanded_scopes.remove('self')
|
expanded_scopes.remove('self')
|
||||||
if owner and isinstance(owner, orm.User):
|
if owner and isinstance(owner, orm.User):
|
||||||
@@ -232,7 +230,7 @@ def _check_scopes(*args, rolename=None):
|
|||||||
raise NameError(f"Scope '{scope}' {log_role} does not exist")
|
raise NameError(f"Scope '{scope}' {log_role} does not exist")
|
||||||
if filter_:
|
if filter_:
|
||||||
full_filter = f"!{filter_}"
|
full_filter = f"!{filter_}"
|
||||||
if not any(full_filter in scope for full_filter in allowed_filters):
|
if not any(f in scope for f in allowed_filters):
|
||||||
raise NameError(
|
raise NameError(
|
||||||
f"Scope filter '{full_filter}' in scope '{scope}' {log_role} does not exist"
|
f"Scope filter '{full_filter}' in scope '{scope}' {log_role} does not exist"
|
||||||
)
|
)
|
||||||
@@ -454,7 +452,8 @@ def assign_default_roles(db, entity):
|
|||||||
db.commit()
|
db.commit()
|
||||||
# users and services can have 'user' or 'admin' roles as default
|
# users and services can have 'user' or 'admin' roles as default
|
||||||
else:
|
else:
|
||||||
app_log.debug('Assigning default roles to %s', type(entity).__name__)
|
kind = type(entity).__name__
|
||||||
|
app_log.debug(f'Assigning default roles to {kind} {entity.name}')
|
||||||
_switch_default_role(db, entity, entity.admin)
|
_switch_default_role(db, entity, entity.admin)
|
||||||
|
|
||||||
|
|
||||||
|
@@ -143,7 +143,7 @@ async def test_delete_named_server(app, named_servers):
|
|||||||
username = 'donaar'
|
username = 'donaar'
|
||||||
user = add_user(app.db, app, name=username)
|
user = add_user(app.db, app, name=username)
|
||||||
assert user.allow_named_servers
|
assert user.allow_named_servers
|
||||||
cookies = app.login_user(username)
|
cookies = await app.login_user(username)
|
||||||
servername = 'splugoth'
|
servername = 'splugoth'
|
||||||
r = await api_request(app, 'users', username, 'servers', servername, method='post')
|
r = await api_request(app, 'users', username, 'servers', servername, method='post')
|
||||||
r.raise_for_status()
|
r.raise_for_status()
|
||||||
|
@@ -788,6 +788,19 @@ async def test_user_filter_expansion(app, scope_list, kind, test_for_token):
|
|||||||
app.db.delete(test_role)
|
app.db.delete(test_role)
|
||||||
|
|
||||||
|
|
||||||
|
async def test_large_filter_expansion(app, create_temp_role, create_user_with_scopes):
|
||||||
|
scope_list = roles.expand_self_scope('==')
|
||||||
|
# Mimic the role 'self' based on '!user' filter for tokens
|
||||||
|
scope_list = [scope.rstrip("=") for scope in scope_list]
|
||||||
|
filtered_role = create_temp_role(scope_list)
|
||||||
|
user = create_user_with_scopes('self')
|
||||||
|
user.new_api_token(roles=[filtered_role.name])
|
||||||
|
user.new_api_token(roles=['token'])
|
||||||
|
manual_scope_set = get_scopes_for(user.api_tokens[0])
|
||||||
|
auto_scope_set = get_scopes_for(user.api_tokens[1])
|
||||||
|
assert manual_scope_set == auto_scope_set
|
||||||
|
|
||||||
|
|
||||||
@mark.role
|
@mark.role
|
||||||
@mark.parametrize(
|
@mark.parametrize(
|
||||||
"name, valid",
|
"name, valid",
|
||||||
@@ -849,6 +862,8 @@ async def test_server_role_api_calls(
|
|||||||
):
|
):
|
||||||
user = add_user(app.db, app, name='test_user')
|
user = add_user(app.db, app, name='test_user')
|
||||||
roles.grant_role(app.db, user, 'user')
|
roles.grant_role(app.db, user, 'user')
|
||||||
|
app_log.debug(user.roles)
|
||||||
|
app_log.debug(roles.expand_roles_to_scopes(user.orm_user))
|
||||||
if token_role == 'no_role':
|
if token_role == 'no_role':
|
||||||
api_token = user.new_api_token(roles=[])
|
api_token = user.new_api_token(roles=[])
|
||||||
else:
|
else:
|
||||||
|
Reference in New Issue
Block a user