2020-03-27 10:59:16 -07:00
|
|
|
import base64
|
2018-12-16 20:36:02 +01:00
|
|
|
import unittest
|
2018-12-16 21:33:18 +01:00
|
|
|
import tempfile
|
|
|
|
import shutil
|
|
|
|
import io
|
2019-07-09 14:56:21 -07:00
|
|
|
import os
|
2018-12-16 20:36:02 +01:00
|
|
|
|
2020-03-27 10:59:16 -07:00
|
|
|
from unittest.mock import patch
|
2020-04-26 09:50:14 -07:00
|
|
|
from flask_testing import TestCase
|
2020-03-27 10:59:16 -07:00
|
|
|
|
2018-12-16 20:36:02 +01:00
|
|
|
import main
|
|
|
|
|
|
|
|
|
2020-04-26 09:50:14 -07:00
|
|
|
class Mat2WebTestCase(TestCase):
|
|
|
|
def create_app(self):
|
2019-07-09 14:56:21 -07:00
|
|
|
os.environ.setdefault('MAT2_ALLOW_ORIGIN_WHITELIST', 'origin1.gnu origin2.gnu')
|
|
|
|
self.upload_folder = tempfile.mkdtemp()
|
2020-04-23 10:39:35 -07:00
|
|
|
app = main.create_app(
|
|
|
|
test_config={
|
|
|
|
'TESTING': True,
|
|
|
|
'UPLOAD_FOLDER': self.upload_folder
|
|
|
|
}
|
2019-07-09 14:56:21 -07:00
|
|
|
)
|
2020-04-26 09:50:14 -07:00
|
|
|
return app
|
2018-12-16 20:36:02 +01:00
|
|
|
|
2018-12-16 21:33:18 +01:00
|
|
|
def tearDown(self):
|
2019-07-09 14:56:21 -07:00
|
|
|
shutil.rmtree(self.upload_folder)
|
2018-12-16 21:33:18 +01:00
|
|
|
|
2018-12-16 20:36:02 +01:00
|
|
|
def test_get_root(self):
|
2020-04-26 09:50:14 -07:00
|
|
|
rv = self.client.get('/')
|
2018-12-16 20:36:02 +01:00
|
|
|
self.assertIn(b'mat2-web', rv.data)
|
|
|
|
|
2018-12-16 21:47:25 +01:00
|
|
|
def test_check_mimetypes(self):
|
2020-04-26 09:50:14 -07:00
|
|
|
rv = self.client.get('/')
|
2019-03-06 21:20:39 +01:00
|
|
|
self.assertIn(b'.torrent', rv.data)
|
|
|
|
self.assertIn(b'.ods', rv.data)
|
2018-12-16 21:47:25 +01:00
|
|
|
|
2018-12-16 20:36:02 +01:00
|
|
|
def test_get_download_dangerous_file(self):
|
2020-04-26 09:50:14 -07:00
|
|
|
rv = self.client.get('/download/1337/aabb/\..\filename')
|
2018-12-16 20:36:02 +01:00
|
|
|
self.assertEqual(rv.status_code, 302)
|
|
|
|
|
2019-02-22 21:17:48 +01:00
|
|
|
def test_get_download_without_key_file(self):
|
2020-04-26 09:50:14 -07:00
|
|
|
rv = self.client.get('/download/non_existant')
|
2019-02-22 21:17:48 +01:00
|
|
|
self.assertEqual(rv.status_code, 404)
|
|
|
|
|
|
|
|
def test_get_download_nonexistant_file(self):
|
2020-04-26 09:50:14 -07:00
|
|
|
rv = self.client.get('/download/1337/aabb/non_existant')
|
2018-12-16 20:36:02 +01:00
|
|
|
self.assertEqual(rv.status_code, 302)
|
|
|
|
|
2018-12-16 21:33:18 +01:00
|
|
|
def test_get_upload_without_file(self):
|
2020-04-26 09:50:14 -07:00
|
|
|
rv = self.client.post('/')
|
2018-12-16 21:33:18 +01:00
|
|
|
self.assertEqual(rv.status_code, 302)
|
|
|
|
|
|
|
|
def test_get_upload_empty_file(self):
|
2020-04-26 09:50:14 -07:00
|
|
|
rv = self.client.post('/',
|
2018-12-16 21:33:18 +01:00
|
|
|
data=dict(
|
|
|
|
file=(io.BytesIO(b""), 'test.pdf'),
|
|
|
|
), follow_redirects=False)
|
|
|
|
self.assertEqual(rv.status_code, 302)
|
|
|
|
|
2022-01-24 19:43:12 +00:00
|
|
|
def test_get_upload_bad_file_type(self):
|
|
|
|
rv = self.client.post('/',
|
|
|
|
data=dict(
|
|
|
|
file=(io.BytesIO(b"1,2,3 \n 4,5,6"), 'test.csv'),
|
|
|
|
), follow_redirects=False)
|
|
|
|
self.assertEqual(rv.status_code, 200)
|
|
|
|
self.assertIn(b'The type text/csv could not be cleaned', rv.data)
|
|
|
|
|
2018-12-16 21:33:18 +01:00
|
|
|
def test_get_upload_empty_file_redir(self):
|
2020-04-26 09:50:14 -07:00
|
|
|
rv = self.client.post('/',
|
2018-12-16 21:33:18 +01:00
|
|
|
data=dict(
|
|
|
|
file=(io.BytesIO(b""), 'test.pdf'),
|
|
|
|
), follow_redirects=True)
|
2021-03-23 21:20:54 +01:00
|
|
|
self.assertIn(b'The filetype is not supported',
|
2018-12-16 21:33:18 +01:00
|
|
|
rv.data)
|
|
|
|
self.assertEqual(rv.status_code, 200)
|
|
|
|
|
2020-03-27 10:59:16 -07:00
|
|
|
def test_get_upload_no_selected_file(self):
|
2020-04-26 09:50:14 -07:00
|
|
|
rv = self.client.post('/',
|
2020-03-27 10:59:16 -07:00
|
|
|
data=dict(
|
|
|
|
file=(io.BytesIO(b""), ''),
|
|
|
|
), follow_redirects=True)
|
|
|
|
self.assertIn(b'No selected file',
|
|
|
|
rv.data)
|
|
|
|
self.assertEqual(rv.status_code, 200)
|
|
|
|
|
|
|
|
def test_failed_cleaning(self):
|
|
|
|
zip_file_bytes = base64.b64decode(
|
|
|
|
'UEsDBBQACAAIAPicPE8AAAAAAAAAAAAAAAAXACAAZmFpbGluZy5ub3Qtd29ya2luZy1le'
|
|
|
|
'HRVVA0AB+Saj13kmo9d5JqPXXV4CwABBOkDAAAE6QMAAAMAUEsHCAAAAAACAAAAAAAAAFBL'
|
|
|
|
'AwQUAAgACAD6nDxPAAAAAAAAAAAAAAAACQAgAHRlc3QuanNvblVUDQAH6JqPXeiaj13omo9d'
|
|
|
|
'dXgLAAEE6QMAAATpAwAAAwBQSwcIAAAAAAIAAAAAAAAAUEsBAhQDFAAIAAgA+Jw8TwAAAAACA'
|
|
|
|
'AAAAAAAABcAIAAAAAAAAAAAAKSBAAAAAGZhaWxpbmcubm90LXdvcmtpbmctZXh0VVQNAAfkmo9'
|
|
|
|
'd5JqPXeSaj111eAsAAQTpAwAABOkDAABQSwECFAMUAAgACAD6nDxPAAAAAAIAAAAAAAAACQAgA'
|
|
|
|
'AAAAAAAAAAApIFnAAAAdGVzdC5qc29uVVQNAAfomo9d6JqPXeiaj111eAsAAQTpAwAABOkDAAB'
|
|
|
|
'QSwUGAAAAAAIAAgC8AAAAwAAAAAAA'
|
|
|
|
)
|
2020-04-26 09:50:14 -07:00
|
|
|
rv = self.client.post('/',
|
2020-03-27 10:59:16 -07:00
|
|
|
data=dict(
|
|
|
|
file=(io.BytesIO(zip_file_bytes), 'test.zip'),
|
|
|
|
), follow_redirects=True)
|
2020-03-31 21:18:39 +02:00
|
|
|
self.assertIn(b'Unable to clean', rv.data)
|
2020-03-27 10:59:16 -07:00
|
|
|
self.assertEqual(rv.status_code, 200)
|
|
|
|
|
2018-12-16 21:41:23 +01:00
|
|
|
def test_get_upload_no_file_name(self):
|
2020-04-26 09:50:14 -07:00
|
|
|
rv = self.client.post('/',
|
2018-12-16 21:41:23 +01:00
|
|
|
data=dict(
|
2019-07-09 14:56:21 -07:00
|
|
|
file=(io.BytesIO(b"aaa")),
|
2018-12-16 21:41:23 +01:00
|
|
|
), follow_redirects=True)
|
|
|
|
self.assertIn(b'No file part', rv.data)
|
|
|
|
self.assertEqual(rv.status_code, 200)
|
|
|
|
|
2018-12-16 21:37:15 +01:00
|
|
|
def test_get_upload_harmless_file(self):
|
2020-04-26 09:50:14 -07:00
|
|
|
rv = self.client.post(
|
|
|
|
'/',
|
|
|
|
data=dict(
|
|
|
|
file=(io.BytesIO(b"Some text"), 'test.txt'),
|
|
|
|
),
|
|
|
|
follow_redirects=True
|
|
|
|
)
|
|
|
|
download_uri = self.get_context_variable('download_uri')
|
|
|
|
self.assertIn('/test.cleaned.txt', download_uri)
|
2018-12-16 21:37:15 +01:00
|
|
|
self.assertEqual(rv.status_code, 200)
|
2019-07-09 14:56:21 -07:00
|
|
|
self.assertNotIn('Access-Control-Allow-Origin', rv.headers)
|
2018-12-16 21:37:15 +01:00
|
|
|
|
2020-04-26 09:50:14 -07:00
|
|
|
rv = self.client.get(download_uri)
|
2018-12-16 21:37:15 +01:00
|
|
|
self.assertEqual(rv.status_code, 200)
|
|
|
|
|
2020-04-26 09:50:14 -07:00
|
|
|
rv = self.client.get(download_uri)
|
2018-12-16 21:37:15 +01:00
|
|
|
self.assertEqual(rv.status_code, 302)
|
|
|
|
|
2020-04-26 09:50:14 -07:00
|
|
|
def test_upload_wrong_hash_or_secret(self):
|
|
|
|
rv = self.client.post(
|
|
|
|
'/',
|
|
|
|
data=dict(
|
|
|
|
file=(io.BytesIO(b"Some text"), 'test.txt'),
|
|
|
|
),
|
|
|
|
follow_redirects=True
|
|
|
|
)
|
|
|
|
|
|
|
|
download_uri = self.get_context_variable('download_uri')
|
|
|
|
|
|
|
|
self.assertIn('/test.cleaned.txt', download_uri)
|
|
|
|
self.assertIn('/download', download_uri)
|
2019-07-09 14:56:21 -07:00
|
|
|
self.assertEqual(rv.status_code, 200)
|
|
|
|
|
2020-04-26 09:50:14 -07:00
|
|
|
uri_parts = download_uri.split("/")
|
|
|
|
self.assertEqual(len(uri_parts[2]), len(uri_parts[3]))
|
|
|
|
self.assertEqual(64, len(uri_parts[2]))
|
|
|
|
|
|
|
|
key_uri_parts = uri_parts
|
|
|
|
key_uri_parts[2] = '70623619c'
|
|
|
|
rv = self.client.get("/".join(key_uri_parts))
|
|
|
|
self.assertEqual(rv.status_code, 302)
|
|
|
|
|
|
|
|
key_uri_parts = uri_parts
|
|
|
|
key_uri_parts[3] = '70623619c'
|
|
|
|
rv = self.client.get("/".join(key_uri_parts))
|
2019-07-09 14:56:21 -07:00
|
|
|
self.assertEqual(rv.status_code, 302)
|
|
|
|
|
2020-04-23 10:39:35 -07:00
|
|
|
@patch('matweb.file_removal_scheduler.random.randint')
|
2020-03-27 10:59:16 -07:00
|
|
|
def test_upload_leftover(self, randint_mock):
|
|
|
|
randint_mock.return_value = 0
|
|
|
|
os.environ['MAT2_MAX_FILE_AGE_FOR_REMOVAL'] = '0'
|
|
|
|
app = main.create_app()
|
|
|
|
self.upload_folder = tempfile.mkdtemp()
|
|
|
|
app.config.update(
|
|
|
|
TESTING=True,
|
|
|
|
UPLOAD_FOLDER=self.upload_folder
|
|
|
|
)
|
|
|
|
app = app.test_client()
|
|
|
|
|
2020-04-26 09:50:14 -07:00
|
|
|
request = self.client.post('/',
|
2020-03-27 10:59:16 -07:00
|
|
|
data=dict(
|
|
|
|
file=(io.BytesIO(b"Some text"), 'test.txt'),
|
|
|
|
), follow_redirects=True)
|
|
|
|
self.assertEqual(request.status_code, 200)
|
2020-04-26 09:50:14 -07:00
|
|
|
|
|
|
|
request = app.get(self.get_context_variable('download_uri'))
|
2020-03-27 10:59:16 -07:00
|
|
|
self.assertEqual(302, request.status_code)
|
2020-05-15 14:38:13 +02:00
|
|
|
os.environ['MAT2_MAX_FILE_AGE_FOR_REMOVAL'] = str(15*60)
|
2020-03-27 10:59:16 -07:00
|
|
|
|
2020-04-13 23:02:55 +02:00
|
|
|
def test_info_page(self):
|
2020-04-26 09:50:14 -07:00
|
|
|
rv = self.client.get('/info')
|
2020-04-13 23:02:55 +02:00
|
|
|
self.assertIn(b'What are metadata?', rv.data)
|
2021-01-29 02:40:42 -08:00
|
|
|
self.assertIn(b'.jpg', rv.data)
|
2020-04-13 23:02:55 +02:00
|
|
|
self.assertIn(b'.mp2', rv.data)
|
|
|
|
self.assertEqual(rv.status_code, 200)
|
|
|
|
|
2025-01-12 12:11:06 +00:00
|
|
|
def test_get_upload_no_ascii_no_ext_input(self):
|
2020-05-08 09:10:18 -07:00
|
|
|
rv = self.client.post(
|
|
|
|
'/',
|
|
|
|
data=dict(
|
2025-01-12 12:11:06 +00:00
|
|
|
file=(io.BytesIO(b"a"), '﷽.txt'),
|
2020-05-08 09:10:18 -07:00
|
|
|
),
|
|
|
|
follow_redirects=True
|
|
|
|
)
|
|
|
|
self.assertEqual(rv.status_code, 200)
|
2025-01-12 12:11:06 +00:00
|
|
|
self.assertIn(b'.cleaned.txt', rv.data)
|
2020-05-08 09:10:18 -07:00
|
|
|
|
2025-01-12 12:11:06 +00:00
|
|
|
def test_get_upload_no_ascii_stem_input(self):
|
|
|
|
pdfBytes = b"%PDF-1.\n 1 0 obj<</Pages 2 0 R>>endobj\n2 0 obj<</Kids[3 0 R]/Count 1>>endobj\n3 0 obj<</Parent 2 0 R>>endobj\ntrailer <</Root 1 0 R>>"
|
|
|
|
rv = self.client.post(
|
|
|
|
'/',
|
|
|
|
data=dict(
|
|
|
|
file=(io.BytesIO(pdfBytes), '한국어.pdf'),
|
|
|
|
),
|
|
|
|
follow_redirects=True
|
|
|
|
)
|
|
|
|
self.assertEqual(rv.status_code, 200)
|
|
|
|
self.assertIn(b'.cleaned.pdf', rv.data)
|
2020-05-08 09:10:18 -07:00
|
|
|
|
2018-12-16 20:36:02 +01:00
|
|
|
if __name__ == '__main__':
|
|
|
|
unittest.main()
|
|
|
|
|