From 4e6805c408b9bc842a50137caf431b15e3f075a2 Mon Sep 17 00:00:00 2001 From: Min RK Date: Tue, 24 Feb 2015 12:59:25 -0800 Subject: [PATCH 1/2] catch IOError in addition to OSError IOError is a subclass of OSError on py3, but not py2 --- IPython/html/services/contents/fileio.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IPython/html/services/contents/fileio.py b/IPython/html/services/contents/fileio.py index fcd78ad4d..77c39c2f5 100644 --- a/IPython/html/services/contents/fileio.py +++ b/IPython/html/services/contents/fileio.py @@ -61,7 +61,7 @@ class FileManagerMixin(object): """context manager for turning permission errors into 403.""" try: yield - except OSError as e: + except (OSError, IOError) as e: if e.errno in {errno.EPERM, errno.EACCES}: # make 403 error message without root prefix # this may not work perfectly on unicode paths on Python 2, From b83a9383a643b9537ef3d7c0f403e3ca14b86d78 Mon Sep 17 00:00:00 2001 From: Min RK Date: Tue, 24 Feb 2015 13:07:45 -0800 Subject: [PATCH 2/2] test that FileContentsManager.open turns permission error into 403 --- .../services/contents/tests/test_manager.py | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/IPython/html/services/contents/tests/test_manager.py b/IPython/html/services/contents/tests/test_manager.py index 06a664557..b13bc1ec7 100644 --- a/IPython/html/services/contents/tests/test_manager.py +++ b/IPython/html/services/contents/tests/test_manager.py @@ -5,6 +5,7 @@ from __future__ import print_function import os import time +from nose import SkipTest from tornado.web import HTTPError from unittest import TestCase from tempfile import NamedTemporaryFile @@ -128,6 +129,25 @@ class TestFileContentsManager(TestCase): sorted(dir_model['content'], key=lambda x: x['name']), [symlink_model, file_model], ) + + def test_403(self): + if hasattr(os, 'getuid'): + if os.getuid() == 0: + raise SkipTest("Can't test permissions as root") + + with TemporaryDirectory() as td: + cm = FileContentsManager(root_dir=td) + model = cm.new_untitled(type='file') + os_path = cm._get_os_path(model['path']) + + os.chmod(os_path, 0o400) + try: + with cm.open(os_path, 'w') as f: + f.write(u"don't care") + except HTTPError as e: + self.assertEqual(e.status_code, 403) + else: + self.fail("Should have raised HTTPError(403)") class TestContentsManager(TestCase):