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:
Daniel Farrell 2018-01-07 15:26:10 -08:00 committed by Grant Nestor
parent e4529a46c4
commit 605eaa72be
6 changed files with 32 additions and 10 deletions

View File

@ -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

View File

@ -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)

View File

@ -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():

View File

@ -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)

View File

@ -41,7 +41,7 @@ class FilesTest(NotebookTestBase):
f.write('foo')
with open(pjoin(path, '.foo'), 'w') as f:
f.write('.foo')
for d in not_hidden:
path = pjoin(nbdir, d.replace('/', os.sep))
r = self.request('GET', url_path_join('files', d, 'foo'))
@ -49,13 +49,33 @@ class FilesTest(NotebookTestBase):
self.assertEqual(r.text, 'foo')
r = self.request('GET', url_path_join('files', d, '.foo'))
self.assertEqual(r.status_code, 404)
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))
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)."

View File

@ -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)