mirror of
https://github.com/jupyterhub/jupyterhub.git
synced 2025-10-19 16:03:00 +00:00
Implemented filter list skeleton
This commit is contained in:
@@ -35,10 +35,12 @@ class _GroupAPIHandler(APIHandler):
|
|||||||
|
|
||||||
|
|
||||||
class GroupListAPIHandler(_GroupAPIHandler):
|
class GroupListAPIHandler(_GroupAPIHandler):
|
||||||
@needs_scope('read:groups') # Todo: Apply filter on results
|
@needs_scope('read:groups')
|
||||||
def get(self):
|
def get(self, scope_filter=None):
|
||||||
"""List groups"""
|
"""List groups"""
|
||||||
groups = self.db.query(orm.Group)
|
groups = self.db.query(orm.Group)
|
||||||
|
if scope_filter is not None:
|
||||||
|
groups.filter(orm.Group.name._in(scope_filter))
|
||||||
data = [self.group_model(g) for g in groups]
|
data = [self.group_model(g) for g in groups]
|
||||||
self.write(json.dumps(data))
|
self.write(json.dumps(data))
|
||||||
|
|
||||||
|
@@ -31,8 +31,10 @@ def service_model(service):
|
|||||||
|
|
||||||
class ServiceListAPIHandler(APIHandler):
|
class ServiceListAPIHandler(APIHandler):
|
||||||
@needs_scope('read:services')
|
@needs_scope('read:services')
|
||||||
def get(self):
|
def get(self, scope_filter=None):
|
||||||
data = {name: service_model(service) for name, service in self.services.items()}
|
data = {name: service_model(service) for name, service in self.services.items()}
|
||||||
|
if scope_filter is not None:
|
||||||
|
data = dict(filter(lambda tup: tup[0] in scope_filter))
|
||||||
self.write(json.dumps(data))
|
self.write(json.dumps(data))
|
||||||
|
|
||||||
|
|
||||||
|
@@ -38,8 +38,6 @@ class SelfAPIHandler(APIHandler):
|
|||||||
user = self.get_current_user_oauth_token()
|
user = self.get_current_user_oauth_token()
|
||||||
if user is None:
|
if user is None:
|
||||||
raise web.HTTPError(403)
|
raise web.HTTPError(403)
|
||||||
# Later: filter based on scopes.
|
|
||||||
# Perhaps user
|
|
||||||
self.write(json.dumps(self.user_model(user)))
|
self.write(json.dumps(self.user_model(user)))
|
||||||
|
|
||||||
|
|
||||||
@@ -53,7 +51,7 @@ class UserListAPIHandler(APIHandler):
|
|||||||
return any(spawner.ready for spawner in user.spawners.values())
|
return any(spawner.ready for spawner in user.spawners.values())
|
||||||
|
|
||||||
@needs_scope('read:users')
|
@needs_scope('read:users')
|
||||||
def get(self):
|
def get(self, scope_filter=None):
|
||||||
state_filter = self.get_argument("state", None)
|
state_filter = self.get_argument("state", None)
|
||||||
|
|
||||||
# post_filter
|
# post_filter
|
||||||
@@ -94,6 +92,8 @@ class UserListAPIHandler(APIHandler):
|
|||||||
else:
|
else:
|
||||||
# no filter, return all users
|
# no filter, return all users
|
||||||
query = self.db.query(orm.User)
|
query = self.db.query(orm.User)
|
||||||
|
if scope_filter is not None:
|
||||||
|
query.filter(orm.User.name.in_(scope_filter))
|
||||||
|
|
||||||
data = [
|
data = [
|
||||||
self.user_model(u, include_servers=True, include_state=True)
|
self.user_model(u, include_servers=True, include_state=True)
|
||||||
|
@@ -320,9 +320,7 @@ def get_user_scopes(name):
|
|||||||
'users:servers',
|
'users:servers',
|
||||||
'users:tokens',
|
'users:tokens',
|
||||||
]
|
]
|
||||||
scope_list.extend(
|
scope_list.extend(['read:' + scope for scope in scope_list])
|
||||||
['read:' + scope for scope in scope_list]
|
|
||||||
) # Todo: Put this in closure
|
|
||||||
return {"{}!user={}".format(scope, name) for scope in scope_list}
|
return {"{}!user={}".format(scope, name) for scope in scope_list}
|
||||||
|
|
||||||
|
|
||||||
@@ -348,6 +346,29 @@ def check_user_in_expanded_scope(handler, user_name, scope_group_names):
|
|||||||
return bool(set(scope_group_names) & group_names)
|
return bool(set(scope_group_names) & group_names)
|
||||||
|
|
||||||
|
|
||||||
|
def _flatten_groups(groups):
|
||||||
|
user_set = {}
|
||||||
|
for group in groups:
|
||||||
|
user_set |= group.users
|
||||||
|
return user_set
|
||||||
|
|
||||||
|
|
||||||
|
def _get_scope_filter(req_scope, sub_scope):
|
||||||
|
# Rough draft
|
||||||
|
scope_translator = {
|
||||||
|
'read:users': 'users',
|
||||||
|
'users': 'users',
|
||||||
|
'read:groups': 'groups',
|
||||||
|
}
|
||||||
|
if req_scope not in scope_translator:
|
||||||
|
raise AttributeError("Scope not found")
|
||||||
|
kind = scope_translator[req_scope]
|
||||||
|
scope_filter = None # todo: orm.Class(kind).find
|
||||||
|
if 'group' in sub_scope and kind == 'user':
|
||||||
|
scope_filter += _flatten_groups(sub_scope['group'])
|
||||||
|
return set(scope_filter)
|
||||||
|
|
||||||
|
|
||||||
def check_scope(api_handler, req_scope, scopes, **kwargs):
|
def check_scope(api_handler, req_scope, scopes, **kwargs):
|
||||||
# Parse user name and server name together
|
# Parse user name and server name together
|
||||||
if 'user' in kwargs and 'server' in kwargs:
|
if 'user' in kwargs and 'server' in kwargs:
|
||||||
@@ -358,17 +379,23 @@ def check_scope(api_handler, req_scope, scopes, **kwargs):
|
|||||||
return True
|
return True
|
||||||
# Apply filters
|
# Apply filters
|
||||||
sub_scope = scopes[req_scope]
|
sub_scope = scopes[req_scope]
|
||||||
for (
|
if 'scope_filter' in kwargs:
|
||||||
filter_,
|
scope_filter = _get_scope_filter(req_scope, sub_scope)
|
||||||
filter_value,
|
kwargs['scope_filter'] = scope_filter
|
||||||
) in kwargs.items(): # Interface change: Now can have multiple filters
|
return True
|
||||||
if filter_ in sub_scope and filter_value in sub_scope[filter_]:
|
else:
|
||||||
return True
|
# Interface change: Now can have multiple filters
|
||||||
if needs_scope_expansion(filter_, filter_value, sub_scope):
|
for (filter_, filter_value) in kwargs.items():
|
||||||
group_names = sub_scope['group']
|
if filter_ in sub_scope and filter_value in sub_scope[filter_]:
|
||||||
if check_user_in_expanded_scope(api_handler, filter_value, group_names):
|
|
||||||
return True
|
return True
|
||||||
return False
|
if needs_scope_expansion(filter_, filter_value, sub_scope):
|
||||||
|
group_names = sub_scope['group']
|
||||||
|
if check_user_in_expanded_scope(api_handler, filter_value, group_names):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
# Todo: make some methods private
|
||||||
|
|
||||||
|
|
||||||
def parse_scopes(scope_list):
|
def parse_scopes(scope_list):
|
||||||
|
Reference in New Issue
Block a user