Read hidden files from extension

Hi!

I made a JupyterLab 4 extension to allow iframe tags inside Markdown cells depending on the source (i.e., the “src” attribute). Allowed sources are stored inside a whitelist file.

If that’s the way to store an extension’s configuration, I need the whitelist file to be hidden so that users cannot see it from the JupyterLab’s file explorer.

For the moment, the extension reads the whitelist file in the following function. However, the contents manager cannot access the whitelist file if it is hidden.

/**
 * Loads the list of whitelisted domains.
 */
async function loadWhitelistedDomains(): Promise<Set<string>> {
  const filePath = PathExt.joinWithLeadingSlash('resources', 'iframe_whitelist', 'iframe_whitelist.txt');
  const contentsManager = new ContentsManager();

  try {
    const model = await contentsManager.get(filePath);
    const domains = new Set<string>(model.content.split('\n').map((line: string) => line.trim()).filter((line: string) => line !== ''));
    return domains;
  } catch (reason) {
    console.error(`Error reading ${filePath}: ${reason}`);
    return new Set<string>();
  };
}

This looks like a security restriction from jupyter-server, it requires to set ContentsManager.allow_hidden = True to allow acess to hidden files (Configuring a Jupyter Server — Jupyter Server documentation). Did you try that already?

2 Likes

Hi! Thank you for your fast reply.

I have tried multiple times (now, again) to use this configuration. It is, however, not working.

My guess is that the configuration is not working because I am using TLJH (w/ repo2docker).

TLJH’s configuration file is in /opt/tljh/config/jupyterhub_config.d/jupyter_config.py and all other configurations stored in it work.

# Allow access to hidden files
c.ContentsManager.allow_hidden = True

Hi, again!

I was thinking that, maybe, loading strings from a hidden file isn’t the best way to configure the extension.

In an ideal scenario, I would like the whitelist of my extension to be loaded during the build of the container and unchangeable once the user is using JupyterLab. However, I do not mind if the whitelist can be modified by the user inside JupyterLab. But I need the whitelist to be invisible to the user.

What is the commonly used method to configure a JupyterLab extension in this way? In other words, what would be the best way to configure my JupyterLab extension with a whitelist of domains?

After a lot of searching, I now understand that the configuration file in which c.ContentsManager.allow_hidden needs to be set to true is jupyter_notebook_config.py. The suggested jupyter_server_config.py configuration file did not work.

This file, with this exact name, needs to be located under one of the paths presented with the command jupyter --paths. However, this file can also be created at the correct location with the command jupyter notebook --generate-config.

In my case, as I am building environments inside Docker containers using repo2docker, the correct location for configuration files such as jupyter_notebook_config.py is the ~/.jupyter/ folder located at the root directory of the Jupyter project inside each environment.

I initially thought that these configuration files were a single file and that their lines could be entered inside the JupyterHub configuration file located on the host of the Docker containers with the path /opt/tljh/config/jupyterhub_config.d/jupyter_config.py.

Although the issue is now resolved, I do have questions over the difference between the following configurations, because the documentation doesn’t say much:

  • c.ContentsManager.allow_hidden (inside jupyter_notebook_config.py)
  • c.FileContentsManager.allow_hidden (inside jupyter_notebook_config.py)
  • c.ContentsManager.allow_hidden (inside jupyter_server_config.py)
  • c.FileContentsManager.allow_hidden (inside jupyter_server_config.py)

See What is the difference between `jupyter notebook` and `jupyter server`? - Stack Overflow. It seems you are running with the old notebook server - I would not recommend this any longer as that is de facto not maintained anymore (it may recieve security updates but bug fixes are highly unlikely).

Thank you for you fast reply! I will check on that.

However, what is the difference between c.ContentsManager.allow_hidden and c.FileContentsManager.allow_hidden?

Good question. More generally one should ask what is the difference between ContentsManager and FileContentsManager. The ContentsManager is an abstract class, and FileContentsManager is a concrete implementation of ContentsManager. This should not usually matter, but if you are swapping to a different subclass of ContentsManager, then you may want to set it on that sublass (or on ContentsManager) rather than on FileContentsManager.

1 Like