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):
|
||||
@needs_scope('read:groups') # Todo: Apply filter on results
|
||||
def get(self):
|
||||
@needs_scope('read:groups')
|
||||
def get(self, scope_filter=None):
|
||||
"""List groups"""
|
||||
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]
|
||||
self.write(json.dumps(data))
|
||||
|
||||
|
@@ -31,8 +31,10 @@ def service_model(service):
|
||||
|
||||
class ServiceListAPIHandler(APIHandler):
|
||||
@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()}
|
||||
if scope_filter is not None:
|
||||
data = dict(filter(lambda tup: tup[0] in scope_filter))
|
||||
self.write(json.dumps(data))
|
||||
|
||||
|
||||
|
@@ -38,8 +38,6 @@ class SelfAPIHandler(APIHandler):
|
||||
user = self.get_current_user_oauth_token()
|
||||
if user is None:
|
||||
raise web.HTTPError(403)
|
||||
# Later: filter based on scopes.
|
||||
# Perhaps 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())
|
||||
|
||||
@needs_scope('read:users')
|
||||
def get(self):
|
||||
def get(self, scope_filter=None):
|
||||
state_filter = self.get_argument("state", None)
|
||||
|
||||
# post_filter
|
||||
@@ -94,6 +92,8 @@ class UserListAPIHandler(APIHandler):
|
||||
else:
|
||||
# no filter, return all users
|
||||
query = self.db.query(orm.User)
|
||||
if scope_filter is not None:
|
||||
query.filter(orm.User.name.in_(scope_filter))
|
||||
|
||||
data = [
|
||||
self.user_model(u, include_servers=True, include_state=True)
|
||||
|
@@ -320,9 +320,7 @@ def get_user_scopes(name):
|
||||
'users:servers',
|
||||
'users:tokens',
|
||||
]
|
||||
scope_list.extend(
|
||||
['read:' + scope for scope in scope_list]
|
||||
) # Todo: Put this in closure
|
||||
scope_list.extend(['read:' + scope 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)
|
||||
|
||||
|
||||
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):
|
||||
# Parse user name and server name together
|
||||
if 'user' in kwargs and 'server' in kwargs:
|
||||
@@ -358,10 +379,13 @@ def check_scope(api_handler, req_scope, scopes, **kwargs):
|
||||
return True
|
||||
# Apply filters
|
||||
sub_scope = scopes[req_scope]
|
||||
for (
|
||||
filter_,
|
||||
filter_value,
|
||||
) in kwargs.items(): # Interface change: Now can have multiple filters
|
||||
if 'scope_filter' in kwargs:
|
||||
scope_filter = _get_scope_filter(req_scope, sub_scope)
|
||||
kwargs['scope_filter'] = scope_filter
|
||||
return True
|
||||
else:
|
||||
# Interface change: Now can have multiple filters
|
||||
for (filter_, filter_value) in kwargs.items():
|
||||
if filter_ in sub_scope and filter_value in sub_scope[filter_]:
|
||||
return True
|
||||
if needs_scope_expansion(filter_, filter_value, sub_scope):
|
||||
@@ -371,6 +395,9 @@ def check_scope(api_handler, req_scope, scopes, **kwargs):
|
||||
return False
|
||||
|
||||
|
||||
# Todo: make some methods private
|
||||
|
||||
|
||||
def parse_scopes(scope_list):
|
||||
"""
|
||||
Parses scopes and filters in something akin to JSON style
|
||||
|
Reference in New Issue
Block a user