Implemented mock scopes

This commit is contained in:
0mar
2020-10-28 16:23:21 +01:00
parent dece64d248
commit 21ea4ad2b6
4 changed files with 33 additions and 4 deletions

View File

@@ -83,6 +83,7 @@ class BaseHandler(RequestHandler):
except Exception:
self.log.exception("Failed to get current user")
self._jupyterhub_user = None
self.scopes = []
return await maybe_future(super().prepare())
@@ -426,6 +427,10 @@ class BaseHandler(RequestHandler):
# don't let errors here raise more than once
self._jupyterhub_user = None
self.log.exception("Error getting current user")
if self._jupyterhub_user is not None:
self.scopes = self.settings.get("mock_scopes", [])
else:
self.scopes = []
return self._jupyterhub_user
@property

View File

@@ -53,6 +53,7 @@ from ..spawner import SimpleLocalProcessSpawner
from ..utils import random_port
from ..utils import url_path_join
from .utils import async_requests
from .utils import get_all_scopes
from .utils import public_host
from .utils import public_url
from .utils import ssl_setup
@@ -299,6 +300,7 @@ class MockHub(JupyterHub):
super().init_tornado_application()
# reconnect tornado_settings so that mocks can update the real thing
self.tornado_settings = self.users.settings = self.tornado_application.settings
self.tornado_settings['mock_scopes'] = get_all_scopes()
def init_services(self):
# explicitly expire services before reinitializing

View File

@@ -194,3 +194,25 @@ def public_url(app, user_or_service=None, path=''):
return host + ujoin(prefix, path)
else:
return host + prefix
def get_all_scopes():
scopes = [
'all',
'all',
'users',
'users:name',
'users:groups',
'users:activity',
'users:servers',
'users:tokens',
'admin:users',
'admin:users:servers',
'groups',
'admin:groups',
'read:services',
'proxy',
'shutdown',
]
read_only = ["read:%s" % el for el in scopes]
return scopes + read_only

View File

@@ -305,12 +305,12 @@ def needs_scope(scope):
def scope_decorator(func):
@functools.wraps(func)
def _auth_func(self, *args, **kwargs):
if scope not in self.current_scopes:
self.log.warning("Scope needed: " + scope)
self.log.warning("Scope possessed: %s" % ", ".join(self.scopes))
if scope not in self.scopes:
# Check if access is not restricted to user/server/group
match_string = re.compile("^" + re.escape(scope) + r"!.+=.+$")
subscopes = filter(
lambda s: re.search(match_string, s), self.current_scopes
)
subscopes = filter(lambda s: re.search(match_string, s), self.scopes)
subset = [subscope.split('=')[1] for subscope in subscopes]
if not subset:
raise web.HTTPError(