I tried running the below script on pre-spawn-hook, its working for our usecase
import os
import django
import importlib
from django.apps import apps
import environ
import requests
def restricted_methods(method):
raise Exception("This method is restricted!!!")
def current_user_groups(hub_api_url, jupyterhub_api_token):
req = requests.get(
hub_api_url + '/hub/api/user',
headers={'Authorization': f'token {jupyterhub_api_token}'}
)
users = req.json()
return users
def is_import_restricted(item, restricted_imports):
return item in restricted_imports
def custom_importer(name, globals=None, locals=None, fromlist=(), level=0, users=None, users_group=None, jupyterhub_config=None):
if users.get('admin') or not fromlist:
return importlib.__import__(name, globals, locals, fromlist, level)
for group in users_group:
restricted_imports = jupyterhub_config['methods_imports_to_disable'].get(group, {}).get('imports', [])
if any(is_import_restricted(item, restricted_imports) for item in fromlist):
restricted_items = [item for item in fromlist if is_import_restricted(item, restricted_imports)]
raise ImportError(f"Imports {', '.join(restricted_items)} are restricted.")
return importlib.__import__(name, globals, locals, fromlist, level)
def run_production_code():
env = environ.Env()
environ.Env.read_env()
jupyterhub_config = env('JUPYTERHUB_CONFIG', default={
'hub_api_url': 'http://127.0.0.1:8888',
'methods_imports_to_disable': {
'DEVOPS-USERS': {
'imports': [],
'methods': []
},
'TECH_SUPPORT-USERS': {
'imports': ['models', 'Product', '*'],
'methods': ['save']
}
}
})
# Set up Django environment
os.chdir('/srv/www/project/')
os.environ.setdefault("DJANGO_ALLOW_ASYNC_UNSAFE", 'true')
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings")
django.setup()
# Fetch user groups from the Hub API
jupyterhub_api_token = os.environ.get("JUPYTERHUB_API_TOKEN")
users = current_user_groups(jupyterhub_config['hub_api_url'], jupyterhub_api_token)
users_group = users.get('groups', []) if len(users.get('groups', [])) > 0 else ['TECH_SUPPORT-USERS']
#built-in __import__ function with custom importer
__builtins__.__dict__['__import__'] = lambda name, globals=None, locals=None, fromlist=(), level=0: custom_importer(name, globals, locals, fromlist, level, users, users_group, jupyterhub_config)
# Disable specified methods based on user groups
for model in apps.get_models():
if users.get('admin'):
break
for group in users_group:
methods_to_disable = jupyterhub_config['methods_imports_to_disable'].get(group, {}).get('methods', [])
[setattr(model, method, restricted_methods) for method in methods_to_disable if hasattr(model, method)]
if __name__ == "__main__":
run_production_code()