|
"""A module with various utility methods for authorization in Jupyter Server.""" |
|
|
|
|
|
|
|
import importlib |
|
import random |
|
import re |
|
import warnings |
|
|
|
|
|
def warn_disabled_authorization(): |
|
"""DEPRECATED, does nothing""" |
|
warnings.warn( |
|
"jupyter_server.auth.utils.warn_disabled_authorization is deprecated", |
|
DeprecationWarning, |
|
stacklevel=2, |
|
) |
|
|
|
|
|
HTTP_METHOD_TO_AUTH_ACTION = { |
|
"GET": "read", |
|
"HEAD": "read", |
|
"OPTIONS": "read", |
|
"POST": "write", |
|
"PUT": "write", |
|
"PATCH": "write", |
|
"DELETE": "write", |
|
"WEBSOCKET": "execute", |
|
} |
|
|
|
|
|
def get_regex_to_resource_map(): |
|
"""Returns a dictionary with all of Jupyter Server's |
|
request handler URL regex patterns mapped to |
|
their resource name. |
|
|
|
e.g. |
|
{ "/api/contents/<regex_pattern>": "contents", ...} |
|
""" |
|
from jupyter_server.serverapp import JUPYTER_SERVICE_HANDLERS |
|
|
|
modules = [] |
|
for mod_name in JUPYTER_SERVICE_HANDLERS.values(): |
|
if mod_name: |
|
modules.extend(mod_name) |
|
resource_map = {} |
|
for handler_module in modules: |
|
mod = importlib.import_module(handler_module) |
|
name = mod.AUTH_RESOURCE |
|
for handler in mod.default_handlers: |
|
url_regex = handler[0] |
|
resource_map[url_regex] = name |
|
|
|
|
|
for url_regex in [ |
|
r"/terminals/websocket/(\w+)", |
|
"/api/terminals", |
|
r"/api/terminals/(\w+)", |
|
]: |
|
resource_map[url_regex] = "terminals" |
|
return resource_map |
|
|
|
|
|
def match_url_to_resource(url, regex_mapping=None): |
|
"""Finds the JupyterHandler regex pattern that would |
|
match the given URL and returns the resource name (str) |
|
of that handler. |
|
|
|
e.g. |
|
/api/contents/... returns "contents" |
|
""" |
|
if not regex_mapping: |
|
regex_mapping = get_regex_to_resource_map() |
|
for regex, auth_resource in regex_mapping.items(): |
|
pattern = re.compile(regex) |
|
if pattern.fullmatch(url): |
|
return auth_resource |
|
|
|
|
|
|
|
moons_of_jupyter = [ |
|
"Metis", |
|
"Adrastea", |
|
"Amalthea", |
|
"Thebe", |
|
"Io", |
|
"Europa", |
|
"Ganymede", |
|
"Callisto", |
|
"Themisto", |
|
"Leda", |
|
"Ersa", |
|
"Pandia", |
|
"Himalia", |
|
"Lysithea", |
|
"Elara", |
|
"Dia", |
|
"Carpo", |
|
"Valetudo", |
|
"Euporie", |
|
"Eupheme", |
|
|
|
|
|
"Helike", |
|
|
|
|
|
"Euanthe", |
|
|
|
"Hermippe", |
|
"Praxidike", |
|
"Thyone", |
|
"Thelxinoe", |
|
|
|
"Ananke", |
|
"Mneme", |
|
|
|
"Orthosie", |
|
"Harpalyke", |
|
"Iocaste", |
|
|
|
|
|
|
|
"Erinome", |
|
"Aitne", |
|
"Herse", |
|
"Taygete", |
|
|
|
|
|
"Eukelade", |
|
"Carme", |
|
|
|
"Isonoe", |
|
|
|
"Autonoe", |
|
"Philophrosyne", |
|
"Cyllene", |
|
"Pasithee", |
|
|
|
"Pasiphae", |
|
"Sponde", |
|
|
|
"Eurydome", |
|
|
|
"Kalyke", |
|
"Hegemone", |
|
"Kale", |
|
"Kallichore", |
|
|
|
|
|
"Chaldene", |
|
"Arche", |
|
"Eirene", |
|
"Kore", |
|
|
|
|
|
"Megaclite", |
|
"Aoede", |
|
|
|
"Callirrhoe", |
|
"Sinope", |
|
] |
|
|
|
|
|
def get_anonymous_username() -> str: |
|
""" |
|
Get a random user-name based on the moons of Jupyter. |
|
This function returns names like "Anonymous Io" or "Anonymous Metis". |
|
""" |
|
return moons_of_jupyter[random.randint(0, len(moons_of_jupyter) - 1)] |
|
|