Resolves sql warnings on 3.6 and fixes for scope expansion bug

This commit is contained in:
0mar
2021-06-17 12:45:54 +02:00
parent 0381b51648
commit 2f8f7ad0b0
5 changed files with 30 additions and 13 deletions

View File

@@ -1960,7 +1960,7 @@ class JupyterHub(Application):
user = orm.User.find(self.db, name=username)
if user is None:
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}")
user = orm.User(name=username)
self.db.add(user)
@@ -2301,15 +2301,18 @@ class JupyterHub(Application):
service.orm.server = None
if service.oauth_available:
oauth_client = self.oauth_provider.add_client(
client_id=service.oauth_client_id,
client_secret=service.api_token,
redirect_uri=service.oauth_redirect_uri,
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(
client_id=service.oauth_client_id,
client_secret=service.api_token,
redirect_uri=service.oauth_redirect_uri,
allowed_roles=allowed_roles,
description="JupyterHub service %s" % service.name,
)
service.orm.oauth_client = oauth_client

View File

@@ -717,7 +717,7 @@ class APIToken(Hashed, Base):
db.add(orm_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:
if roles is not None:
update_roles(db, entity=orm_token, roles=roles)

View File

@@ -183,9 +183,8 @@ def _get_subscopes(*roles, owner=None):
scopes.update(role.scopes)
expanded_scopes = set(chain.from_iterable(list(map(_expand_scope, scopes))))
# transform !user filter to !user=ownername
for scope in expanded_scopes:
for scope in expanded_scopes.copy():
base_scope, _, filter = scope.partition('!')
if filter == 'user':
expanded_scopes.remove(scope)
@@ -198,7 +197,6 @@ def _get_subscopes(*roles, owner=None):
name = owner.name
trans_scope = f'{base_scope}!user={name}'
expanded_scopes.add(trans_scope)
if 'self' in expanded_scopes:
expanded_scopes.remove('self')
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")
if 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(
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()
# users and services can have 'user' or 'admin' roles as default
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)

View File

@@ -143,7 +143,7 @@ async def test_delete_named_server(app, named_servers):
username = 'donaar'
user = add_user(app.db, app, name=username)
assert user.allow_named_servers
cookies = app.login_user(username)
cookies = await app.login_user(username)
servername = 'splugoth'
r = await api_request(app, 'users', username, 'servers', servername, method='post')
r.raise_for_status()

View File

@@ -788,6 +788,19 @@ async def test_user_filter_expansion(app, scope_list, kind, test_for_token):
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.parametrize(
"name, valid",
@@ -849,6 +862,8 @@ async def test_server_role_api_calls(
):
user = add_user(app.db, app, name='test_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':
api_token = user.new_api_token(roles=[])
else: