jupyterhub-singleuser as a Jupyter Server 2.0 extension

mostly a copy (fork) of singleuser app
using public APIs instead of lots of patching.

opt-in via `JUPYTERHUB_SINGLEUSER_EXTENSION=1`

related changes:

- stop running a test single-user server in a thread. It's complicated and fragile.
  Instead, run it normally, and get the info we need from a custom handler registered via an extension
  via the `full_spawn` fixture
This commit is contained in:
Min RK
2022-12-21 12:28:37 +01:00
parent 63f164ca53
commit 58dccdb59b
17 changed files with 1068 additions and 141 deletions

View File

@@ -0,0 +1,36 @@
import os
from jupyterhub.singleuser.extension import JupyterHubAuthorizer
class GranularJupyterHubAuthorizer(JupyterHubAuthorizer):
"""Authorizer that looks for permissions in JupyterHub scopes"""
def is_authorized(self, handler, user, action, resource):
# authorize if any of these permissions are present
# filters check for access to this specific user or server
# group filters aren't available!
filters = [
f"!user={os.environ['JUPYTERHUB_USER']}",
f"!server={os.environ['JUPYTERHUB_USER']}/{os.environ['JUPYTERHUB_SERVER_NAME']}",
]
required_scopes = set()
for f in filters:
required_scopes.update(
{
f"custom:jupyter_server:{action}:{resource}{f}",
f"custom:jupyter_server:{action}:*{f}",
}
)
have_scopes = self.hub_auth.check_scopes(required_scopes, user.hub_user)
self.log.debug(
f"{user.username} has permissions {have_scopes} required to {action} on {resource}"
)
return bool(have_scopes)
c = get_config() # noqa
c.ServerApp.authorizer_class = GranularJupyterHubAuthorizer