From 7eece7603bc7fa33913e55cfa2081f55132b5b96 Mon Sep 17 00:00:00 2001 From: yunimoo Date: Fri, 31 May 2024 17:43:49 -0400 Subject: [PATCH 1/9] Add mime_type checks on file uploads --- cps/editbooks.py | 5 +++++ cps/file_helper.py | 19 +++++++++++++++++++ cps/uploader.py | 5 +++-- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/cps/editbooks.py b/cps/editbooks.py index 43309a14..5ed95595 100644 --- a/cps/editbooks.py +++ b/cps/editbooks.py @@ -23,6 +23,7 @@ import os from datetime import datetime import json +import magic from shutil import copyfile from uuid import uuid4 from markupsafe import escape, Markup # dependency of flask @@ -757,6 +758,10 @@ def file_handling_on_upload(requested_file): flash(_("File %(filename)s could not saved to temp dir", filename=requested_file.filename), category="error") return None, Response(json.dumps({"location": url_for("web.index")}), mimetype='application/json') + except (Exception): + flash(_("File is not allowed to be uploaded to this server", + filename=requested_file.filename), category="error") + return None, Response(json.dumps({"location": url_for("web.index")}), mimetype='application/json') return meta, None diff --git a/cps/file_helper.py b/cps/file_helper.py index 7c3e5291..6160eb70 100644 --- a/cps/file_helper.py +++ b/cps/file_helper.py @@ -19,6 +19,9 @@ from tempfile import gettempdir import os import shutil +import magic +import zipfile +from . import constants def get_temp_dir(): tmp_dir = os.path.join(gettempdir(), 'calibre_web') @@ -30,3 +33,19 @@ def get_temp_dir(): def del_temp_dir(): tmp_dir = os.path.join(gettempdir(), 'calibre_web') shutil.rmtree(tmp_dir) + +def validate_mime_type(tmp_file_path): + mime = magic.Magic(mime=True) + tmp_mime_type = mime.from_file(tmp_file_path) + if any(mime_type in tmp_mime_type for mime_type in constants.EXTENSIONS_UPLOAD): + return True + # Some epubs show up as zip mimetypes + elif "zip" in tmp_mime_type: + try: + with zipfile.ZipFile(tmp_file_path, 'r') as epub: + if "mimetype" in epub.namelist(): + return True + except: + pass + + raise Exception("Forbidden MIME type to upload") diff --git a/cps/uploader.py b/cps/uploader.py index 8f20762f..c2ebd96b 100644 --- a/cps/uploader.py +++ b/cps/uploader.py @@ -23,7 +23,7 @@ from flask_babel import gettext as _ from . import logger, comic, isoLanguages from .constants import BookMeta from .helper import split_authors -from .file_helper import get_temp_dir +from .file_helper import get_temp_dir, validate_mime_type log = logger.create() @@ -91,7 +91,8 @@ def process(tmp_file_path, original_file_name, original_file_extension, rar_exec meta = meta._replace(title=original_file_name) if not meta.author.strip() or meta.author.lower() == 'unknown': meta = meta._replace(author=_('Unknown')) - return meta + if validate_mime_type(tmp_file_path): + return meta def default_meta(tmp_file_path, original_file_name, original_file_extension): From af52748acaa18a2b00585508222c7f884b1dc9f6 Mon Sep 17 00:00:00 2001 From: yunimoo Date: Fri, 31 May 2024 17:44:05 -0400 Subject: [PATCH 2/9] Update requirements to add python-magic --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index 7bb5ff3d..dd89dead 100644 --- a/requirements.txt +++ b/requirements.txt @@ -19,3 +19,4 @@ chardet>=3.0.0,<4.1.0 advocate>=1.0.0,<1.1.0 Flask-Limiter>=2.3.0,<3.6.0 regex>=2022.3.2,<2024.2.25 +python-magic>=0.4.27 From fef20c831aed53d7eab26de46229716ca9a8f7df Mon Sep 17 00:00:00 2001 From: Ozzie Isaacs Date: Sat, 22 Jun 2024 16:13:00 +0200 Subject: [PATCH 3/9] Changed limiter message --- cps/templates/config_edit.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cps/templates/config_edit.html b/cps/templates/config_edit.html index 0d0a695f..98fdcd9a 100755 --- a/cps/templates/config_edit.html +++ b/cps/templates/config_edit.html @@ -373,7 +373,7 @@
- +
From 6441f5f96b96ba5bc1bc3c7af23882c13ac77750 Mon Sep 17 00:00:00 2001 From: Ozzie Isaacs Date: Sun, 23 Jun 2024 13:07:28 +0200 Subject: [PATCH 4/9] Prevent non unique authors on upload --- cps/editbooks.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/cps/editbooks.py b/cps/editbooks.py index f1a95284..2065b70b 100644 --- a/cps/editbooks.py +++ b/cps/editbooks.py @@ -616,8 +616,9 @@ def prepare_authors(authr): input_authors = [_('Unknown')] # prevent empty Author renamed = list() - for in_aut in input_authors: - renamed_author = calibre_db.session.query(db.Authors).filter(db.Authors.name == in_aut).first() + for index,in_aut in enumerate(input_authors): + # renamed_author = calibre_db.session.query(db.Authors).filter(db.Authors.name == in_aut).first() + renamed_author = calibre_db.session.query(db.Authors).filter(func.lower(db.Authors.name).ilike(in_aut)).first() if renamed_author and in_aut != renamed_author.name: renamed.append(renamed_author.name) all_books = calibre_db.session.query(db.Books) \ @@ -626,6 +627,7 @@ def prepare_authors(authr): sorted_old_author = helper.get_sorted_author(in_aut) for one_book in all_books: one_book.author_sort = one_book.author_sort.replace(sorted_renamed_author, sorted_old_author) + input_authors[index] = renamed_author.name return input_authors, renamed @@ -642,7 +644,8 @@ def prepare_authors_on_upload(title, authr): sort_authors_list = list() db_author = None for inp in input_authors: - stored_author = calibre_db.session.query(db.Authors).filter(db.Authors.name == inp).first() + # stored_author = calibre_db.session.query(db.Authors).filter(db.Authors.name == inp).first() + stored_author = calibre_db.session.query(db.Authors).filter(func.lower(db.Authors.name).ilike(inp)).first() if not stored_author: if not db_author: db_author = db.Authors(inp, helper.get_sorted_author(inp), "") @@ -1389,8 +1392,8 @@ def add_objects(db_book_object, db_object, db_session, db_type, add_elements): if db_no_case: # check for new case of element db_element = create_objects_for_addition(db_element, add_element, db_type) - else: - db_element = create_objects_for_addition(db_element, add_element, db_type) + #else: + # db_element = create_objects_for_addition(db_element, add_element, db_type) # add element to book db_book_object.append(db_element) From 92ffce1dc83a0d1538b16be85e6cbe584e0a2d56 Mon Sep 17 00:00:00 2001 From: Ozzie Isaacs Date: Sun, 23 Jun 2024 13:47:54 +0200 Subject: [PATCH 5/9] Rename Archived in Book Detail page --- cps/templates/detail.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cps/templates/detail.html b/cps/templates/detail.html index 840d2f75..bca7b1c8 100644 --- a/cps/templates/detail.html +++ b/cps/templates/detail.html @@ -251,7 +251,7 @@ - {{ _('Read') }} + {{ _('Read') }}

@@ -264,7 +264,7 @@ - {{ _('Archived') }} + {{ _('Archive') }}

From 1a1f1498a53d75dd427606becb079001bd26b285 Mon Sep 17 00:00:00 2001 From: Ozzie Isaacs Date: Mon, 24 Jun 2024 14:39:28 +0200 Subject: [PATCH 6/9] Bugfixes from Tests --- cps/__init__.py | 8 +- setup.cfg | 1 + test/Calibre-Web TestSummary_Linux.html | 2285 ++++++++++++++++------- 3 files changed, 1625 insertions(+), 669 deletions(-) diff --git a/cps/__init__.py b/cps/__init__.py index 6821d507..d68306de 100755 --- a/cps/__init__.py +++ b/cps/__init__.py @@ -62,10 +62,10 @@ mimetypes.add_type('application/x-mobipocket-ebook', '.mobi') mimetypes.add_type('application/x-mobipocket-ebook', '.prc') mimetypes.add_type('application/vnd.amazon.ebook', '.azw') mimetypes.add_type('application/x-mobi8-ebook', '.azw3') -mimetypes.add_type('application/x-cbr', '.cbr') -mimetypes.add_type('application/x-cbz', '.cbz') -mimetypes.add_type('application/x-cbt', '.cbt') -mimetypes.add_type('application/x-cb7', '.cb7') +mimetypes.add_type('application/x-rar', '.cbr') +mimetypes.add_type('application/zip', '.cbz') +mimetypes.add_type('application/x-tar', '.cbt') +mimetypes.add_type('application/x-7z-compressed', '.cb7') mimetypes.add_type('image/vnd.djv', '.djv') mimetypes.add_type('image/vnd.djv', '.djvu') mimetypes.add_type('application/mpeg', '.mpeg') diff --git a/setup.cfg b/setup.cfg index ac832da9..570c66d1 100644 --- a/setup.cfg +++ b/setup.cfg @@ -59,6 +59,7 @@ install_requires = advocate>=1.0.0,<1.1.0 Flask-Limiter>=2.3.0,<3.6.0 regex>=2022.3.2,<2024.2.25 + python-magic>=0.4.27,<0.5.0 [options.packages.find] diff --git a/test/Calibre-Web TestSummary_Linux.html b/test/Calibre-Web TestSummary_Linux.html index 1fc3469c..34d29396 100644 --- a/test/Calibre-Web TestSummary_Linux.html +++ b/test/Calibre-Web TestSummary_Linux.html @@ -37,20 +37,20 @@
-

Start Time: 2024-05-11 18:39:24

+

Start Time: 2024-06-23 19:26:37

-

Stop Time: 2024-05-12 01:48:22

+

Stop Time: 2024-06-24 02:18:31

-

Duration: 5h 59 min

+

Duration: 5h 39 min

@@ -234,11 +234,11 @@ - + TestBackupMetadata 21 - 21 - 0 + 20 + 1 0 0 @@ -410,11 +410,31 @@ - +
TestBackupMetadata - test_backup_change_custom_rating
- PASS + +
+ FAIL +
+ + + + @@ -1005,12 +1025,12 @@ - + TestEditAdditionalBooks 20 - 17 - 1 - 0 + 7 + 3 + 8 2 Detail @@ -1019,38 +1039,120 @@ - +
TestEditAdditionalBooks - test_cbz_comicinfo
- PASS + +
+ ERROR +
+ + + + - +
TestEditAdditionalBooks - test_change_upload_formats
- PASS + +
+ FAIL +
+ + + + - +
TestEditAdditionalBooks - test_delete_book
- PASS + +
+ ERROR +
+ + + + - +
TestEditAdditionalBooks - test_delete_role
- PASS + +
+ FAIL +
+ + + + @@ -1100,55 +1202,26 @@ - +
TestEditAdditionalBooks - test_title_sort
- PASS - - - - - - -
TestEditAdditionalBooks - test_upload_cbz_coverformats
- - PASS - - - - - - -
TestEditAdditionalBooks - test_upload_edit_role
- - PASS - - - - - - -
TestEditAdditionalBooks - test_upload_metadata_cb7
-
- FAIL + FAIL
-