diff options
Diffstat (limited to 'matweb/utils.py')
| -rw-r--r-- | matweb/utils.py | 35 |
1 files changed, 25 insertions, 10 deletions
diff --git a/matweb/utils.py b/matweb/utils.py index 8dfff45..ec9b99c 100644 --- a/matweb/utils.py +++ b/matweb/utils.py | |||
| @@ -12,15 +12,21 @@ def get_allow_origin_header_value(): | |||
| 12 | return os.environ.get('MAT2_ALLOW_ORIGIN_WHITELIST', '*').split(" ") | 12 | return os.environ.get('MAT2_ALLOW_ORIGIN_WHITELIST', '*').split(" ") |
| 13 | 13 | ||
| 14 | 14 | ||
| 15 | def hash_file(filepath: str) -> str: | 15 | def hash_file(filepath: str, secret: str) -> str: |
| 16 | sha256 = hashlib.sha256() | 16 | """ |
| 17 | The goal of the hmac is to ONLY make the hashes unpredictable | ||
| 18 | :param filepath: Path of the file | ||
| 19 | :param secret: a server side generated secret | ||
| 20 | :return: digest, secret | ||
| 21 | """ | ||
| 22 | mac = hmac.new(secret.encode(), None, hashlib.sha256) | ||
| 17 | with open(filepath, 'rb') as f: | 23 | with open(filepath, 'rb') as f: |
| 18 | while True: | 24 | while True: |
| 19 | data = f.read(65536) # read the file by chunk of 64k | 25 | data = f.read(65536) # read the file by chunk of 64k |
| 20 | if not data: | 26 | if not data: |
| 21 | break | 27 | break |
| 22 | sha256.update(data) | 28 | mac.update(data) |
| 23 | return sha256.hexdigest() | 29 | return mac.hexdigest() |
| 24 | 30 | ||
| 25 | 31 | ||
| 26 | def check_upload_folder(upload_folder): | 32 | def check_upload_folder(upload_folder): |
| @@ -28,11 +34,20 @@ def check_upload_folder(upload_folder): | |||
| 28 | os.mkdir(upload_folder) | 34 | os.mkdir(upload_folder) |
| 29 | 35 | ||
| 30 | 36 | ||
| 31 | def return_file_created_response(output_filename, mime, key, meta, meta_after, download_link): | 37 | def return_file_created_response( |
| 38 | output_filename: str, | ||
| 39 | mime: str, | ||
| 40 | key: str, | ||
| 41 | secret: str, | ||
| 42 | meta: list, | ||
| 43 | meta_after: list, | ||
| 44 | download_link: str | ||
| 45 | ) -> dict: | ||
| 32 | return { | 46 | return { |
| 33 | 'output_filename': output_filename, | 47 | 'output_filename': output_filename, |
| 34 | 'mime': mime, | 48 | 'mime': mime, |
| 35 | 'key': key, | 49 | 'key': key, |
| 50 | 'secret': secret, | ||
| 36 | 'meta': meta, | 51 | 'meta': meta, |
| 37 | 'meta_after': meta_after, | 52 | 'meta_after': meta_after, |
| 38 | 'download_link': download_link | 53 | 'download_link': download_link |
| @@ -65,9 +80,9 @@ def cleanup(parser, filepath, upload_folder): | |||
| 65 | parser, _ = parser_factory.get_parser(parser.output_filename) | 80 | parser, _ = parser_factory.get_parser(parser.output_filename) |
| 66 | meta_after = parser.get_meta() | 81 | meta_after = parser.get_meta() |
| 67 | os.remove(filepath) | 82 | os.remove(filepath) |
| 68 | 83 | secret = os.urandom(32).hex() | |
| 69 | key = hash_file(os.path.join(upload_folder, output_filename)) | 84 | key = hash_file(os.path.join(upload_folder, output_filename), secret) |
| 70 | return key, meta_after, output_filename | 85 | return key, secret, meta_after, output_filename |
| 71 | 86 | ||
| 72 | 87 | ||
| 73 | def get_file_paths(filename, upload_folder): | 88 | def get_file_paths(filename, upload_folder): |
| @@ -77,7 +92,7 @@ def get_file_paths(filename, upload_folder): | |||
| 77 | return complete_path, filepath | 92 | return complete_path, filepath |
| 78 | 93 | ||
| 79 | 94 | ||
| 80 | def is_valid_api_download_file(filename, key, upload_folder): | 95 | def is_valid_api_download_file(filename: str, key: str, secret: str, upload_folder: str) -> [str, str]: |
| 81 | if filename != secure_filename(filename): | 96 | if filename != secure_filename(filename): |
| 82 | abort(400, message='Insecure filename') | 97 | abort(400, message='Insecure filename') |
| 83 | 98 | ||
| @@ -86,6 +101,6 @@ def is_valid_api_download_file(filename, key, upload_folder): | |||
| 86 | if not os.path.exists(complete_path): | 101 | if not os.path.exists(complete_path): |
| 87 | abort(404, message='File not found') | 102 | abort(404, message='File not found') |
| 88 | 103 | ||
| 89 | if hmac.compare_digest(hash_file(complete_path), key) is False: | 104 | if hmac.compare_digest(hash_file(complete_path, secret), key) is False: |
| 90 | abort(400, message='The file hash does not match') | 105 | abort(400, message='The file hash does not match') |
| 91 | return complete_path, filepath | 106 | return complete_path, filepath |
