mirror of
https://github.com/jupyter/notebook.git
synced 2024-12-27 04:20:22 +08:00
Added a flag to allow access of hidden files (#2819)
* Added a flag to allow access of hidden files The flag '--allow-hidden' will allow Tornado to access hidden files such as '.images/my_img.jpg' * Fixed jupyterlab not following allow-hidden Jupyterlab stores its options in a different location than the standard notebook. Added the ability to check there as well. * Updated implementation for any app Previously I was accessing the settings dict based on the name of the app that was being used. ex 'NotebookApp', or 'LabApp'. Now the setting is passed directly into the Tornado settings, and can be accessed via a more general method. * Added/fixed unit tests for test_hidden_files Fixed broken unit tests by setting the default to allow_hidden=False then added unit test in FilesTest:test_hidden_files that checks for the accessibility of files with allow_hidden=True * allow-hidden now works everywhere Previously allow-hidden flag only allowed hidden files to be accessed via tornado. Now you can use the allow-hidden flag to access hidden directories and files via the filebrowser. * Remove --allow-hidden alias * Move allow_hidden option onto ContentsManager * Use try/finally to ensure allow_hidden option is set back to False after test * Allow access to hidden files, but don't list them for now * Simplify hidden check for listing again * Fix indentation
This commit is contained in:
parent
e4529a46c4
commit
605eaa72be
@ -612,8 +612,8 @@ class AuthenticatedFileHandler(IPythonHandler, web.StaticFileHandler):
|
||||
"""
|
||||
abs_path = super(AuthenticatedFileHandler, self).validate_absolute_path(root, absolute_path)
|
||||
abs_root = os.path.abspath(root)
|
||||
if is_hidden(abs_path, abs_root):
|
||||
self.log.info("Refusing to serve hidden file, via 404 Error")
|
||||
if is_hidden(abs_path, abs_root) and not self.contents_manager.allow_hidden:
|
||||
self.log.info("Refusing to serve hidden file, via 404 Error, use flag 'ContentsManager.allow_hidden' to enable")
|
||||
raise web.HTTPError(404)
|
||||
return abs_path
|
||||
|
||||
|
@ -34,7 +34,7 @@ class FilesHandler(IPythonHandler):
|
||||
def get(self, path, include_body=True):
|
||||
cm = self.contents_manager
|
||||
|
||||
if cm.is_hidden(path):
|
||||
if cm.is_hidden(path) and not cm.allow_hidden:
|
||||
self.log.info("Refusing to serve hidden file, via 404 Error")
|
||||
raise web.HTTPError(404)
|
||||
|
||||
|
@ -78,7 +78,6 @@ class FileContentsManager(FileManagerMixin, ContentsManager):
|
||||
return getcwd()
|
||||
|
||||
save_script = Bool(False, config=True, help='DEPRECATED, use post_save_hook. Will be removed in Notebook 5.0')
|
||||
|
||||
@observe('save_script')
|
||||
def _update_save_script(self, change):
|
||||
if not change['new']:
|
||||
@ -288,7 +287,7 @@ class FileContentsManager(FileManagerMixin, ContentsManager):
|
||||
|
||||
if not os.path.isdir(os_path):
|
||||
raise web.HTTPError(404, four_o_four)
|
||||
elif is_hidden(os_path, self.root_dir):
|
||||
elif is_hidden(os_path, self.root_dir) and not self.allow_hidden:
|
||||
self.log.info("Refusing to serve hidden directory %r, via 404 Error",
|
||||
os_path
|
||||
)
|
||||
@ -426,7 +425,7 @@ class FileContentsManager(FileManagerMixin, ContentsManager):
|
||||
|
||||
def _save_directory(self, os_path, model, path=''):
|
||||
"""create a directory"""
|
||||
if is_hidden(os_path, self.root_dir):
|
||||
if is_hidden(os_path, self.root_dir) and not self.allow_hidden:
|
||||
raise web.HTTPError(400, u'Cannot create hidden directory %r' % os_path)
|
||||
if not os.path.exists(os_path):
|
||||
with self.perm_to_403():
|
||||
|
@ -19,6 +19,7 @@ from nbformat.v4 import new_notebook
|
||||
from ipython_genutils.importstring import import_item
|
||||
from traitlets import (
|
||||
Any,
|
||||
Bool,
|
||||
Dict,
|
||||
Instance,
|
||||
List,
|
||||
@ -56,6 +57,8 @@ class ContentsManager(LoggingConfigurable):
|
||||
|
||||
root_dir = Unicode('/', config=True)
|
||||
|
||||
allow_hidden = Bool(False, config=True, help="Allow access to hidden files")
|
||||
|
||||
notary = Instance(sign.NotebookNotary)
|
||||
def _notary_default(self):
|
||||
return sign.NotebookNotary(parent=self)
|
||||
|
@ -56,6 +56,26 @@ class FilesTest(NotebookTestBase):
|
||||
r = self.request('GET', url_path_join('files', d, foo))
|
||||
self.assertEqual(r.status_code, 404)
|
||||
|
||||
self.notebook.contents_manager.allow_hidden = True
|
||||
try:
|
||||
for d in not_hidden:
|
||||
path = pjoin(nbdir, d.replace('/', os.sep))
|
||||
r = self.request('GET', url_path_join('files', d, 'foo'))
|
||||
r.raise_for_status()
|
||||
self.assertEqual(r.text, 'foo')
|
||||
r = self.request('GET', url_path_join('files', d, '.foo'))
|
||||
r.raise_for_status()
|
||||
self.assertEqual(r.text, '.foo')
|
||||
|
||||
for d in hidden:
|
||||
path = pjoin(nbdir, d.replace('/', os.sep))
|
||||
for foo in ('foo', '.foo'):
|
||||
r = self.request('GET', url_path_join('files', d, foo))
|
||||
r.raise_for_status()
|
||||
self.assertEqual(r.text, foo)
|
||||
finally:
|
||||
self.notebook.contents_manager.allow_hidden = False
|
||||
|
||||
def test_contents_manager(self):
|
||||
"make sure ContentsManager returns right files (ipynb, bin, txt)."
|
||||
|
||||
|
@ -40,7 +40,7 @@ class TreeHandler(IPythonHandler):
|
||||
cm = self.contents_manager
|
||||
|
||||
if cm.dir_exists(path=path):
|
||||
if cm.is_hidden(path):
|
||||
if cm.is_hidden(path) and not cm.allow_hidden:
|
||||
self.log.info("Refusing to serve hidden directory, via 404 Error")
|
||||
raise web.HTTPError(404)
|
||||
breadcrumbs = self.generate_breadcrumbs(path)
|
||||
|
Loading…
Reference in New Issue
Block a user