diff --git a/swh/web/ui/tests/test_upload.py b/swh/web/ui/tests/test_upload.py deleted file mode 100644 index 88668d6d0..000000000 --- a/swh/web/ui/tests/test_upload.py +++ /dev/null @@ -1,148 +0,0 @@ -# Copyright (C) 2015 The Software Heritage developers -# See the AUTHORS file at the top-level directory of this distribution -# License: GNU Affero General Public License version 3, or any later version -# See top-level LICENSE file for more information - -from nose.tools import istest -from unittest.mock import patch, MagicMock - -from swh.web.ui import upload -from swh.web.ui.tests import test_app - - -class UploadTestCase(test_app.SWHApiTestCase): - @istest - def allowed_file_ok(self): - # when - actual_perm = upload.allowed_file('README') - self.assertTrue(actual_perm) - - # when - actual_perm2 = upload.allowed_file('README', []) - self.assertTrue(actual_perm2) - - # when - actual_perm3 = upload.allowed_file('README', ['README', - 'LICENCE', - 'BUGS']) - self.assertTrue(actual_perm3) - - # when - actual_perm4 = upload.allowed_file('some-filename.txt', ['txt', - 'blah', - 'gz']) - self.assertTrue(actual_perm4) - - # when - actual_perm5 = upload.allowed_file('something.tar.gz', ['gz', - 'txt', - 'tar.gz']) - # then - self.assertTrue(actual_perm5) - - @istest - def allowed_file_denied(self): - # when - actual_perm = upload.allowed_file('some-filename', ['blah']) - self.assertFalse(actual_perm) - - # when - actual_perm = upload.allowed_file('something.tgz', ['gz', - 'txt', - 'tar.gz']) - # then - self.assertFalse(actual_perm) - - @patch('swh.web.ui.upload.os.path') - @patch('swh.web.ui.upload.shutil') - @istest - def cleanup_ok(self, mock_shutil, mock_os_path): - # given - mock_os_path.commonprefix.return_value = '/some/upload-dir' - mock_shutil.rmtree.return_value = True - - # when - upload.cleanup('/some/upload-dir/some-dummy-path') - - # then - mock_os_path.commonprefix.assert_called_with( - ['/some/upload-dir', '/some/upload-dir/some-dummy-path']) - mock_shutil.rmtree.assert_called_with( - '/some/upload-dir/some-dummy-path') - - @patch('swh.web.ui.upload.os.path') - @patch('swh.web.ui.upload.shutil') - @istest - def cleanup_should_fail(self, mock_shutil, mock_os_path): - # given - mock_os_path.commonprefix.return_value = '/somewhere/forbidden' - mock_shutil.rmtree.return_value = True - - # when - with self.assertRaises(AssertionError): - upload.cleanup('/some/upload-dir/some-dummy-path') - - # then - mock_os_path.commonprefix.assert_called_with( - ['/some/upload-dir', '/some/upload-dir/some-dummy-path']) - self.assertTrue(mock_shutil.rmtree.not_called) - - @istest - def save_in_upload_folder_no_file(self): - # when - act_tmpdir, act_name, act_path = upload.save_in_upload_folder(None) - - # then - self.assertIsNone(act_tmpdir) - self.assertIsNone(act_name) - self.assertIsNone(act_path) - - @istest - def save_in_upload_folder_file_not_allowed(self): - # given - file = MagicMock() - file.filename = 'some-non-file-allowed.ext' - - # when - with self.assertRaises(ValueError) as exc: - act_tmpdir, act_name, act_path = upload.save_in_upload_folder(file) - - # then - self.assertIn('Only', exc.exception.args[0]) - self.assertIn('extensions are valid for upload', exc.exception.args[0]) - - @patch('swh.web.ui.upload.werkzeug') - @patch('swh.web.ui.upload.tempfile') - @istest - def save_in_upload_folder_ok(self, mock_tempfile, mock_werkzeug): - # given - upload_folder = self.app_config['conf']['upload_folder'] - - # mock the dependencies - mock_werkzeug.secure_filename.return_value = 'some-allowed-file.txt' - tmpdir = upload_folder + '/foobar/' - mock_tempfile.mkdtemp.return_value = tmpdir - - # mock the input - file = MagicMock() - file.filename = 'some-allowed-file.txt' - - # when - act_tmpdir, act_name, act_path = upload.save_in_upload_folder(file) - - # then - expected_tmpdir = tmpdir - expected_filename = 'some-allowed-file.txt' - expected_filepath = tmpdir + 'some-allowed-file.txt' - - self.assertEqual(act_tmpdir, expected_tmpdir) - self.assertEqual(act_name, expected_filename) - self.assertEqual(act_path, expected_filepath) - - mock_werkzeug.secure_filename.assert_called_with(expected_filename) - file.save.assert_called_once_with(expected_filepath) - - mock_tempfile.mkdtemp.assert_called_with( - suffix='tmp', - prefix='swh.web.ui-', - dir=upload_folder) diff --git a/swh/web/ui/upload.py b/swh/web/ui/upload.py deleted file mode 100644 index a577b2daf..000000000 --- a/swh/web/ui/upload.py +++ /dev/null @@ -1,79 +0,0 @@ -# Copyright (C) 2015 The Software Heritage developers -# See the AUTHORS file at the top-level directory of this distribution -# License: GNU Affero General Public License version 3, or any later version -# See top-level LICENSE file for more information - -import os -import tempfile -import shutil -import werkzeug - -from swh.web.ui import main - - -def allowed_file(filename, allowed_extensions=[]): - """Filter on filename extension. - The filename to check for permission. - - Args: - filename. If no extension on the filename, the filename itself is - checked against allowed extensions (example of current extensionless - filenames: README, LICENCE, BUGS, etc...) - - Returns: - True if allowed, False otherwise. - - """ - if allowed_extensions == []: - return True - if '.' in filename: - return filename.rsplit('.', 1)[1] in allowed_extensions - return filename in allowed_extensions - - -def save_in_upload_folder(file): - """Persist uploaded file on server. - - Args: - File object (as per Flask's submission form) - - Returns: - a triplet: - - the temporary directory holding the persisted file - - the filename without any path from the file entry - - the complete path filepath - - """ - main_conf = main.app.config['conf'] - upload_folder = main_conf['upload_folder'] - allowed_extensions = main_conf['upload_allowed_extensions'] - - if not file: - return None, None, None - - filename = file.filename - if allowed_file(filename, allowed_extensions): - filename = werkzeug.secure_filename(filename) - - tmpdir = tempfile.mkdtemp(suffix='tmp', - prefix='swh.web.ui-', - dir=upload_folder) - - filepath = os.path.join(tmpdir, filename) - file.save(filepath) # persist on disk (not found how to avoid this) - - return tmpdir, filename, filepath - else: - raise ValueError( - 'Only %s extensions are valid for upload.' % allowed_extensions) - - -def cleanup(tmpdir): - """Clean up after oneself. - - Args: - The directory dir to destroy. - """ - upload_folder = main.app.config['conf']['upload_folder'] - assert (os.path.commonprefix([upload_folder, tmpdir]) == upload_folder) - shutil.rmtree(tmpdir)