From f8de7e75cc88264d3b1a8ee23cf3e49de0f5794d Mon Sep 17 00:00:00 2001 From: Ozzie Isaacs Date: Sun, 11 Jul 2021 09:19:46 +0200 Subject: [PATCH 01/24] Fix error unclosed IO on external binary version query --- cps/converter.py | 4 +--- cps/helper.py | 11 +++++------ cps/subproc_wrapper.py | 12 +++++++++--- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/cps/converter.py b/cps/converter.py index 2ff73666..f37168c7 100644 --- a/cps/converter.py +++ b/cps/converter.py @@ -39,9 +39,7 @@ def _get_command_version(path, pattern, argument=None): if argument: command.append(argument) try: - for line in process_wait(command): - if re.search(pattern, line): - return line + return process_wait(command, pattern=pattern).string except Exception as ex: log.warning("%s: %s", path, ex) return _EXECUTION_ERROR diff --git a/cps/helper.py b/cps/helper.py index d567e9b3..b6ea6760 100644 --- a/cps/helper.py +++ b/cps/helper.py @@ -711,12 +711,11 @@ def check_unrar(unrarLocation): if sys.version_info < (3, 0): unrarLocation = unrarLocation.encode(sys.getfilesystemencoding()) unrarLocation = [unrarLocation] - for lines in process_wait(unrarLocation): - value = re.search('UNRAR (.*) freeware', lines, re.IGNORECASE) - if value: - version = value.group(1) - log.debug("unrar version %s", version) - break + value = process_wait(unrarLocation, pattern='UNRAR (.*) freeware') + if value: + version = value.group(1) + log.debug("unrar version %s", version) + except (OSError, UnicodeDecodeError) as err: log.debug_or_exception(err) return _('Error excecuting UnRar') diff --git a/cps/subproc_wrapper.py b/cps/subproc_wrapper.py index c6c65851..27375686 100644 --- a/cps/subproc_wrapper.py +++ b/cps/subproc_wrapper.py @@ -20,7 +20,7 @@ from __future__ import division, print_function, unicode_literals import sys import os import subprocess - +import re def process_open(command, quotes=(), env=None, sout=subprocess.PIPE, serr=subprocess.PIPE, newlines=True): # Linux py2.7 encode as list without quotes no empty element for parameters @@ -44,12 +44,18 @@ def process_open(command, quotes=(), env=None, sout=subprocess.PIPE, serr=subpro return subprocess.Popen(exc_command, shell=False, stdout=sout, stderr=serr, universal_newlines=newlines, env=env) # nosec -def process_wait(command, serr=subprocess.PIPE): +def process_wait(command, serr=subprocess.PIPE, pattern=""): # Run command, wait for process to terminate, and return an iterator over lines of its output. newlines = os.name != 'nt' + ret_val = "" p = process_open(command, serr=serr, newlines=newlines) p.wait() for line in p.stdout.readlines(): if isinstance(line, bytes): line = line.decode('utf-8') - yield line + match = re.search(pattern, line, re.IGNORECASE) + if match and ret_val == "": + ret_val = match + p.stdout.close() + p.stderr.close() + return ret_val From 1bf065fd04fa809de35854d6d5aded200e56966d Mon Sep 17 00:00:00 2001 From: Ozzie Isaacs Date: Sun, 11 Jul 2021 07:38:15 +0200 Subject: [PATCH 02/24] Bugfix with encoding errors windows --- cps/subproc_wrapper.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cps/subproc_wrapper.py b/cps/subproc_wrapper.py index 27375686..3cc4a070 100644 --- a/cps/subproc_wrapper.py +++ b/cps/subproc_wrapper.py @@ -52,10 +52,11 @@ def process_wait(command, serr=subprocess.PIPE, pattern=""): p.wait() for line in p.stdout.readlines(): if isinstance(line, bytes): - line = line.decode('utf-8') + line = line.decode('utf-8', errors="ignore") match = re.search(pattern, line, re.IGNORECASE) if match and ret_val == "": ret_val = match + break p.stdout.close() p.stderr.close() return ret_val From aae81c3d24c03d761dca59d4469f9d8c2b0ff1df Mon Sep 17 00:00:00 2001 From: Ozzie Isaacs Date: Sun, 11 Jul 2021 12:52:35 +0200 Subject: [PATCH 03/24] Fix #2048 (Display book title in reader) --- cps/jinjia.py | 5 +---- cps/templates/detail.html | 2 +- cps/templates/read.html | 2 +- cps/templates/readcbr.html | 2 +- cps/templates/readdjvu.html | 2 +- cps/templates/readpdf.html | 2 +- cps/templates/readtxt.html | 2 +- cps/web.py | 17 +++++++++++------ 8 files changed, 18 insertions(+), 16 deletions(-) diff --git a/cps/jinjia.py b/cps/jinjia.py index de34cc86..23f727ab 100644 --- a/cps/jinjia.py +++ b/cps/jinjia.py @@ -113,10 +113,7 @@ def yesno(value, yes, no): @jinjia.app_template_filter('formatfloat') def formatfloat(value, decimals=1): - formatedstring = '%d' % value - if (value % 1) != 0: - formatedstring = ('%s.%d' % (formatedstring, (value % 1) * 10**decimals)).rstrip('0') - return formatedstring + return ('{0:.' + str(decimals) + 'g}').format(value) @jinjia.app_template_filter('formatseriesindex') diff --git a/cps/templates/detail.html b/cps/templates/detail.html index e5a67cde..ccad60c2 100644 --- a/cps/templates/detail.html +++ b/cps/templates/detail.html @@ -122,7 +122,7 @@ {% endif %} {% if entry.series|length > 0 %} -

{{_('Book')}} {{entry.series_index}} {{_('of')}} {{entry.series[0].name}}

+

{{_('Book')}} {{entry.series_index|formatfloat(2)}} {{_('of')}} {{entry.series[0].name}}

{% endif %} {% if entry.languages.__len__() > 0 %} diff --git a/cps/templates/read.html b/cps/templates/read.html index b38f783c..3d2566e0 100644 --- a/cps/templates/read.html +++ b/cps/templates/read.html @@ -3,7 +3,7 @@ - ePub Reader + {{_('epub Reader')}} | {{title}} diff --git a/cps/templates/readcbr.html b/cps/templates/readcbr.html index bad5f1f6..411e3fdd 100644 --- a/cps/templates/readcbr.html +++ b/cps/templates/readcbr.html @@ -1,10 +1,10 @@ - Comic Reader + {{_('Comic Reader')}} | {{title}} diff --git a/cps/templates/readdjvu.html b/cps/templates/readdjvu.html index c192ffcb..9771b7c9 100644 --- a/cps/templates/readdjvu.html +++ b/cps/templates/readdjvu.html @@ -7,7 +7,7 @@ -Djvu HTML5 browser demo +{{_('DJVU Reader')}} | {{title}} diff --git a/cps/templates/readpdf.html b/cps/templates/readpdf.html index 7af417ea..586625cc 100644 --- a/cps/templates/readpdf.html +++ b/cps/templates/readpdf.html @@ -26,7 +26,7 @@ See https://github.com/adobe-type-tools/cmap-resources - {{_('PDF reader')}} + {{_('PDF Reader')}} | {{title}} diff --git a/cps/templates/readtxt.html b/cps/templates/readtxt.html index da862fb2..ea294948 100644 --- a/cps/templates/readtxt.html +++ b/cps/templates/readtxt.html @@ -3,7 +3,7 @@ - {{_('Basic txt Reader')}} + {{_('txt Reader')}} | {{title}} diff --git a/cps/web.py b/cps/web.py index ba3c5ae3..a14afb68 100644 --- a/cps/web.py +++ b/cps/web.py @@ -1680,28 +1680,33 @@ def read_book(book_id, book_format): ub.Bookmark.format == book_format.upper())).first() if book_format.lower() == "epub": log.debug(u"Start epub reader for %d", book_id) - return render_title_template('read.html', bookid=book_id, title=_(u"Read a Book"), bookmark=bookmark) + return render_title_template('read.html', bookid=book_id, title=book.title, bookmark=bookmark) elif book_format.lower() == "pdf": log.debug(u"Start pdf reader for %d", book_id) - return render_title_template('readpdf.html', pdffile=book_id, title=_(u"Read a Book")) + return render_title_template('readpdf.html', pdffile=book_id, title=book.title) elif book_format.lower() == "txt": log.debug(u"Start txt reader for %d", book_id) - return render_title_template('readtxt.html', txtfile=book_id, title=_(u"Read a Book")) + return render_title_template('readtxt.html', txtfile=book_id, title=book.title) elif book_format.lower() == "djvu": log.debug(u"Start djvu reader for %d", book_id) - return render_title_template('readdjvu.html', djvufile=book_id, title=_(u"Read a Book")) + return render_title_template('readdjvu.html', djvufile=book_id, title=book.title) else: for fileExt in constants.EXTENSIONS_AUDIO: if book_format.lower() == fileExt: entries = calibre_db.get_filtered_book(book_id) log.debug(u"Start mp3 listening for %d", book_id) return render_title_template('listenmp3.html', mp3file=book_id, audioformat=book_format.lower(), - title=_(u"Read a Book"), entry=entries, bookmark=bookmark) + entry=entries, bookmark=bookmark) for fileExt in ["cbr", "cbt", "cbz"]: if book_format.lower() == fileExt: all_name = str(book_id) + title = book.title + if len(book.series): + title = title + " - " + book.series[0].name + if book.series_index: + title = title + " #" + '{0:.2g}'.format(book.series_index) log.debug(u"Start comic reader for %d", book_id) - return render_title_template('readcbr.html', comicfile=all_name, title=_(u"Read a Book"), + return render_title_template('readcbr.html', comicfile=all_name, title=title, extension=fileExt) log.debug(u"Oops! Selected book title is unavailable. File does not exist or is not accessible") flash(_(u"Oops! Selected book title is unavailable. File does not exist or is not accessible"), category="error") From 15ec6bec95dec5c6098ee771dab255ff80aeb32b Mon Sep 17 00:00:00 2001 From: Ozzie Isaacs Date: Sun, 11 Jul 2021 13:15:13 +0200 Subject: [PATCH 04/24] fix #2014 (User menu dropdown in caliblur is tiny and presents scrollbars) Fix display of nonexistent series_index Fix caliblur add-to-shelf --- cps/jinjia.py | 1 + cps/static/css/caliBlur.css | 1 - cps/static/js/caliBlur.js | 6 +++++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/cps/jinjia.py b/cps/jinjia.py index 23f727ab..00778335 100644 --- a/cps/jinjia.py +++ b/cps/jinjia.py @@ -113,6 +113,7 @@ def yesno(value, yes, no): @jinjia.app_template_filter('formatfloat') def formatfloat(value, decimals=1): + value = 0 if not value else value return ('{0:.' + str(decimals) + 'g}').format(value) diff --git a/cps/static/css/caliBlur.css b/cps/static/css/caliBlur.css index f479f07f..3b226acb 100644 --- a/cps/static/css/caliBlur.css +++ b/cps/static/css/caliBlur.css @@ -3291,7 +3291,6 @@ div.btn-group[role=group][aria-label="Download, send to Kindle, reading"] .dropd transform-origin: center top; border: 0; left: 0 !important; - max-height: 80%; overflow-y: auto; } diff --git a/cps/static/js/caliBlur.js b/cps/static/js/caliBlur.js index 1a2814fc..ce230730 100644 --- a/cps/static/js/caliBlur.js +++ b/cps/static/js/caliBlur.js @@ -413,7 +413,11 @@ if($("body.advsearch").length > 0) { }); $('#add-to-shelf').height("40px"); function search_dropdownToggle() { - topPos = $("#add-to-shelf").offset().top-20; + if( $("#add-to-shelf").length) { + topPos = $("#add-to-shelf").offset().top - 20; + } else { + topPos = 0 + } if ($('div[aria-label="Add to shelves"]').length > 0) { position = $('div[aria-label="Add to shelves"]').offset().left From 280efad939d07a305d524fa0ab0db7681ad3ee16 Mon Sep 17 00:00:00 2001 From: Ozzie Isaacs Date: Mon, 12 Jul 2021 14:04:23 +0200 Subject: [PATCH 05/24] #2052 (wrong series index shown for series_index >=100) --- cps/jinjia.py | 2 +- cps/web.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cps/jinjia.py b/cps/jinjia.py index 00778335..70a6090e 100644 --- a/cps/jinjia.py +++ b/cps/jinjia.py @@ -114,7 +114,7 @@ def yesno(value, yes, no): @jinjia.app_template_filter('formatfloat') def formatfloat(value, decimals=1): value = 0 if not value else value - return ('{0:.' + str(decimals) + 'g}').format(value) + return ('{0:.' + str(decimals) + 'f}').format(value).rstrip('0').rstrip('.') @jinjia.app_template_filter('formatseriesindex') diff --git a/cps/web.py b/cps/web.py index a14afb68..9dab285a 100644 --- a/cps/web.py +++ b/cps/web.py @@ -1704,7 +1704,7 @@ def read_book(book_id, book_format): if len(book.series): title = title + " - " + book.series[0].name if book.series_index: - title = title + " #" + '{0:.2g}'.format(book.series_index) + title = title + " #" + '{0:.2f}'.format(book.series_index).rstrip('0').rstrip('.') log.debug(u"Start comic reader for %d", book_id) return render_title_template('readcbr.html', comicfile=all_name, title=title, extension=fileExt) From e69b1adccdaa05fcd27fa352f598176b0bbcbbbc Mon Sep 17 00:00:00 2001 From: Ozzie Isaacs Date: Mon, 12 Jul 2021 14:17:28 +0200 Subject: [PATCH 06/24] Fix #2053 (Add tooltip for complete title on hover over cover and title) --- cps/templates/author.html | 10 +++++----- cps/templates/book_edit.html | 2 +- cps/templates/detail.html | 2 +- cps/templates/discover.html | 4 ++-- cps/templates/grid.html | 4 ++-- cps/templates/index.html | 8 ++++---- cps/templates/search.html | 4 ++-- cps/templates/shelf.html | 4 ++-- cps/templates/shelf_order.html | 4 ++-- cps/templates/shelfdown.html | 2 +- 10 files changed, 22 insertions(+), 22 deletions(-) diff --git a/cps/templates/author.html b/cps/templates/author.html index 4e32db80..b011bae8 100644 --- a/cps/templates/author.html +++ b/cps/templates/author.html @@ -5,7 +5,7 @@ {% if author is not none %}
{%if author.image_url is not none %} - {{author.name|safe}} + {{author.name|safe}} {% endif %} {%if author.about is not none %} @@ -37,14 +37,14 @@
-

{{entry.title|shortentitle}}

+

{{entry.title|shortentitle}}

{% for author in entry.authors %} @@ -104,11 +104,11 @@

-

{{entry.title|shortentitle}}

+

{{entry.title|shortentitle}}

{% for author in entry.authors %} {% if loop.index > g.config_authors_max and g.config_authors_max != 0 %} diff --git a/cps/templates/book_edit.html b/cps/templates/book_edit.html index b932f56d..f79ec559 100644 --- a/cps/templates/book_edit.html +++ b/cps/templates/book_edit.html @@ -3,7 +3,7 @@ {% if book %}

- {{ book.title }} + {{ book.title }}
{% if g.user.role_delete_books() %}
diff --git a/cps/templates/detail.html b/cps/templates/detail.html index ccad60c2..76a5a87d 100644 --- a/cps/templates/detail.html +++ b/cps/templates/detail.html @@ -4,7 +4,7 @@
- {{ entry.title }} + {{ entry.title }}
diff --git a/cps/templates/discover.html b/cps/templates/discover.html index d57994b4..f6d8207d 100644 --- a/cps/templates/discover.html +++ b/cps/templates/discover.html @@ -9,7 +9,7 @@ {% if entry.has_cover is defined %} - {{ entry.title }} + {{ entry.title }} {% if entry.id in read_book_ids %}{% endif %} @@ -17,7 +17,7 @@
-

{{entry.title|shortentitle}}

+

{{entry.title|shortentitle}}

{% for author in entry.authors %} diff --git a/cps/templates/grid.html b/cps/templates/grid.html index 1e79c43d..f8beffc5 100644 --- a/cps/templates/grid.html +++ b/cps/templates/grid.html @@ -29,14 +29,14 @@

diff --git a/cps/templates/index.html b/cps/templates/index.html index d300fc65..b11500e4 100644 --- a/cps/templates/index.html +++ b/cps/templates/index.html @@ -9,14 +9,14 @@
-

{{entry.title|shortentitle}}

+

{{entry.title|shortentitle}}

{% for author in entry.authors %} @@ -86,14 +86,14 @@

-

{{entry.title|shortentitle}}

+

{{entry.title|shortentitle}}

{% for author in entry.authors %} diff --git a/cps/templates/search.html b/cps/templates/search.html index 81ab2d99..b63819be 100644 --- a/cps/templates/search.html +++ b/cps/templates/search.html @@ -44,7 +44,7 @@ {% if entry.has_cover is defined %} - {{ entry.title }} + {{ entry.title }} {% if entry.id in read_book_ids %}{% endif %} @@ -52,7 +52,7 @@

-

{{entry.title|shortentitle}}

+

{{entry.title|shortentitle}}

{% for author in entry.authors %} diff --git a/cps/templates/shelf.html b/cps/templates/shelf.html index 1ad79dbd..7ee96f7d 100644 --- a/cps/templates/shelf.html +++ b/cps/templates/shelf.html @@ -31,14 +31,14 @@

-

{{entry.title|shortentitle}}

+

{{entry.title|shortentitle}}

{% for author in entry.authors %} diff --git a/cps/templates/shelf_order.html b/cps/templates/shelf_order.html index 1e49f29a..fc53a69a 100644 --- a/cps/templates/shelf_order.html +++ b/cps/templates/shelf_order.html @@ -9,9 +9,9 @@

diff --git a/cps/templates/shelfdown.html b/cps/templates/shelfdown.html index 77251e02..1d781310 100644 --- a/cps/templates/shelfdown.html +++ b/cps/templates/shelfdown.html @@ -35,7 +35,7 @@
-

{{entry.title|shortentitle}}

+

{{entry.title|shortentitle}}

{% for author in entry.authors %} {{author.name.replace('|',',')}} From 616cc2018ab797548539d4833e4d441b1fb8fd3b Mon Sep 17 00:00:00 2001 From: Ozzie Isaacs Date: Mon, 12 Jul 2021 14:58:03 +0200 Subject: [PATCH 07/24] Fix show cover Update more debug output for kobo sync --- cps/kobo.py | 2 ++ cps/services/SyncToken.py | 9 +++++++++ cps/templates/book_edit.html | 2 +- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/cps/kobo.py b/cps/kobo.py index a6c4236f..11381170 100644 --- a/cps/kobo.py +++ b/cps/kobo.py @@ -139,6 +139,7 @@ def convert_to_kobo_timestamp_string(timestamp): def HandleSyncRequest(): sync_token = SyncToken.SyncToken.from_headers(request.headers) log.info("Kobo library sync request received.") + log.debug("SyncToken: {}".format(sync_token)) if not current_app.wsgi_app.is_proxied: log.debug('Kobo: Received unproxied request, changed request port to external server port') @@ -330,6 +331,7 @@ def generate_sync_response(sync_token, sync_results, set_cont=False): extra_headers["x-kobo-sync"] = "continue" sync_token.to_headers(extra_headers) + log.debug("Kobo Sync Content: {}".format(sync_results)) response = make_response(jsonify(sync_results), extra_headers) return response diff --git a/cps/services/SyncToken.py b/cps/services/SyncToken.py index b54d8d95..cc67542c 100644 --- a/cps/services/SyncToken.py +++ b/cps/services/SyncToken.py @@ -183,3 +183,12 @@ class SyncToken: }, } return b64encode_json(token) + + def __str__(self): + return "{},{},{},{},{},{},{}".format(self.raw_kobo_store_token, + self.books_last_created, + self.books_last_modified, + self.archive_last_modified, + self.reading_state_last_modified, + self.tags_last_modified, + self.books_last_id) diff --git a/cps/templates/book_edit.html b/cps/templates/book_edit.html index f79ec559..2da7b09b 100644 --- a/cps/templates/book_edit.html +++ b/cps/templates/book_edit.html @@ -3,7 +3,7 @@ {% if book %}

- {{ book.title }} + {{ book.title }}
{% if g.user.role_delete_books() %}
From 20fa9f55234dc1c9b526c933aef03e47351d817f Mon Sep 17 00:00:00 2001 From: Ozzie Isaacs Date: Mon, 12 Jul 2021 17:33:35 +0200 Subject: [PATCH 08/24] Fix encoding errors on windows while downloading logbooks --- cps/debug_info.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/cps/debug_info.py b/cps/debug_info.py index cfa549f9..dd5e858e 100644 --- a/cps/debug_info.py +++ b/cps/debug_info.py @@ -22,10 +22,6 @@ import glob import zipfile import json from io import BytesIO -try: - from StringIO import StringIO -except ImportError: - from io import StringIO import os @@ -38,9 +34,9 @@ log = logger.create() def assemble_logfiles(file_name): log_list = sorted(glob.glob(file_name + '*'), reverse=True) - wfd = StringIO() + wfd = BytesIO() for f in log_list: - with open(f, 'r') as fd: + with open(f, 'rb') as fd: shutil.copyfileobj(fd, wfd) wfd.seek(0) if int(__version__.split('.')[0]) < 2: From d5d0ad50fa33eb9e0fff32c24a0ce65f03bbc352 Mon Sep 17 00:00:00 2001 From: Ileana Maricel Barrionuevo Date: Wed, 21 Jul 2021 22:08:41 -0300 Subject: [PATCH 09/24] Fixed security issue: a user could edit others' shelves. --- cps/shelf.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cps/shelf.py b/cps/shelf.py index 431eeff8..9556ba66 100644 --- a/cps/shelf.py +++ b/cps/shelf.py @@ -235,6 +235,8 @@ def create_shelf(): @login_required def edit_shelf(shelf_id): shelf = ub.session.query(ub.Shelf).filter(ub.Shelf.id == shelf_id).first() + if not shelf.user_id == int(current_user.id): + return "Sorry you are not allowed to edit this shelf", 403 return create_edit_shelf(shelf, title=_(u"Edit a shelf"), page="shelfedit", shelf_id=shelf_id) From c8ebaee0f76d5b404cd2d5fd17df9f27795abc49 Mon Sep 17 00:00:00 2001 From: Ileana Maricel Barrionuevo Date: Thu, 22 Jul 2021 00:41:07 -0300 Subject: [PATCH 10/24] Security fix improved: user should not edit other shelve's titles --- cps/shelf.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cps/shelf.py b/cps/shelf.py index 9556ba66..229eaade 100644 --- a/cps/shelf.py +++ b/cps/shelf.py @@ -235,8 +235,9 @@ def create_shelf(): @login_required def edit_shelf(shelf_id): shelf = ub.session.query(ub.Shelf).filter(ub.Shelf.id == shelf_id).first() - if not shelf.user_id == int(current_user.id): - return "Sorry you are not allowed to edit this shelf", 403 + if not check_shelf_edit_permissions(shelf): + flash(_(u"Sorry you are not allowed to edit this shelf: "),category="error") + return redirect(url_for('web.index')) return create_edit_shelf(shelf, title=_(u"Edit a shelf"), page="shelfedit", shelf_id=shelf_id) From 59881367fe199f8a1b661dc78c312fccf9e1eadf Mon Sep 17 00:00:00 2001 From: Ileana Maricel Barrionuevo Date: Thu, 22 Jul 2021 01:05:11 -0300 Subject: [PATCH 11/24] Security fixes: Report 85176e1f-7920-4824-87ea-8eb5b5e505e0: Exposure of Private Personal Information to an Unauthorized Actor in janeczku/calibre-web --- cps/shelf.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/cps/shelf.py b/cps/shelf.py index 229eaade..8ec4da45 100644 --- a/cps/shelf.py +++ b/cps/shelf.py @@ -72,10 +72,9 @@ def add_to_shelf(shelf_id, book_id): if not check_shelf_edit_permissions(shelf): if not xhr: - flash(_(u"Sorry you are not allowed to add a book to the the shelf: %(shelfname)s", shelfname=shelf.name), - category="error") + flash(_(u"Sorry you are not allowed to add a book to the the shelf"), category="error") return redirect(url_for('web.index')) - return "Sorry you are not allowed to add a book to the the shelf: %s" % shelf.name, 403 + return "Sorry you are not allowed to add a book to the that shelf", 403 book_in_shelf = ub.session.query(ub.BookShelf).filter(ub.BookShelf.shelf == shelf_id, ub.BookShelf.book_id == book_id).first() @@ -236,7 +235,7 @@ def create_shelf(): def edit_shelf(shelf_id): shelf = ub.session.query(ub.Shelf).filter(ub.Shelf.id == shelf_id).first() if not check_shelf_edit_permissions(shelf): - flash(_(u"Sorry you are not allowed to edit this shelf: "),category="error") + flash(_(u"Sorry you are not allowed to edit this shelf"), category="error") return redirect(url_for('web.index')) return create_edit_shelf(shelf, title=_(u"Edit a shelf"), page="shelfedit", shelf_id=shelf_id) From 3c8bfc31e4ac53c64281e4b62ba66f96620ccdc1 Mon Sep 17 00:00:00 2001 From: Ozzie Isaacs Date: Fri, 23 Jul 2021 19:34:46 +0200 Subject: [PATCH 12/24] fix change name allowd as non admin --- cps/templates/user_edit.html | 58 ++++++++++++++++++------------------ cps/web.py | 15 +++++----- 2 files changed, 37 insertions(+), 36 deletions(-) diff --git a/cps/templates/user_edit.html b/cps/templates/user_edit.html index cc83a1b5..6fb30fc3 100644 --- a/cps/templates/user_edit.html +++ b/cps/templates/user_edit.html @@ -67,15 +67,14 @@
{% endif %}
- {% for element in sidebar %} - {% if element['config_show'] %} -
- - -
- {% endif %} - {% endfor %} - + {% for element in sidebar %} + {% if element['config_show'] %} +
+ + +
+ {% endif %} + {% endfor %}
@@ -84,6 +83,7 @@ {{_('Add Allowed/Denied Tags')}} {{_('Add allowed/Denied Custom Column Values')}} {% endif %} +
{% if g.user and g.user.role_admin() and not profile %} @@ -131,32 +131,32 @@
{% endif %}
-
-
{{_('Save')}}
- {% if not profile %} -
{{_('Cancel')}}
- {% endif %} - {% if g.user and g.user.role_admin() and not profile and not new_user and not content.role_anonymous() %} -
{{_('Delete User')}}
- {% endif %} +
+
{{_('Save')}}
+ {% if not profile %} +
{{_('Cancel')}}
+ {% endif %} + {% if g.user and g.user.role_admin() and not profile and not new_user and not content.role_anonymous() %} +
{{_('Delete User')}}
+ {% endif %}
-
{% if g.user and g.user.role_admin() and not profile %} @@ -140,6 +139,7 @@
{{_('Delete User')}}
{% endif %}
+
From e4b0434733d4c6002334dc6178e06c365e3668db Mon Sep 17 00:00:00 2001 From: Ziding Zhang Date: Mon, 26 Jul 2021 15:01:06 +0100 Subject: [PATCH 21/24] Create SECURITY.md A simple instruction for security researchers in future. --- SECURITY.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 SECURITY.md diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 00000000..2f36fac8 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,5 @@ +# Security Policy + +## Reporting a Vulnerability + +Please report security issues to ozzie.fernandez.isaacs@googlemail.com From 0ec2bcd8979bbf190cb1204aa4ecf19f6a8ebada Mon Sep 17 00:00:00 2001 From: Ozzie Isaacs Date: Fri, 30 Jul 2021 09:25:08 +0200 Subject: [PATCH 22/24] Fixes from testrun --- CONTRIBUTING.md | 4 +- cps/__init__.py | 5 +- cps/converter.py | 4 +- cps/templates/config_db.html | 2 +- cps/templates/logviewer.html | 4 +- cps/web.py | 4 + test/Calibre-Web TestSummary_Linux.html | 2827 ++++++++++++++++++----- 7 files changed, 2321 insertions(+), 529 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ce2bd780..c6006ad1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -41,6 +41,6 @@ Open a new GitHub pull request with the patch. Ensure the PR description clearly In case your code enhances features of Calibre-Web: Create your pull request for the development branch if your enhancement consists of more than some lines of code in a local section of Calibre-Webs code. This makes it easier to test it and check all implication before it's made public. -Please check if your code runs on Python 2.7 (still necessary in 2020) and mainly on python 3. If possible and the feature is related to operating system functions, try to check it on Windows and Linux. -Calibre-Web is automatically tested on Linux in combination with python 3.7. The code for testing is in a [separate repo](https://github.com/OzzieIsaacs/calibre-web-test) on Github. It uses unit tests and performs real system tests with selenium; it would be great if you could consider also writing some tests. +Please check if your code runs with python 3, python 2 is no longer supported. If possible and the feature is related to operating system functions, try to check it on Windows and Linux. +Calibre-Web is automatically tested on Linux in combination with python 3.8. The code for testing is in a [separate repo](https://github.com/OzzieIsaacs/calibre-web-test) on Github. It uses unit tests and performs real system tests with selenium; it would be great if you could consider also writing some tests. A static code analysis is done by Codacy, but it's partly broken and doesn't run automatically. You could check your code with ESLint before contributing, a configuration file can be found in the projects root folder. diff --git a/cps/__init__.py b/cps/__init__.py index 3266a4e9..9b004640 100644 --- a/cps/__init__.py +++ b/cps/__init__.py @@ -102,8 +102,9 @@ def create_app(): log.info('Starting Calibre Web...') if sys.version_info < (3, 0): - log.info('Python2 is EOL since end of 2019, this version of Calibre-Web is no longer supporting Python2 please consider upgrading to Python3') - print('Python2 is EOL since end of 2019, this version of Calibre-Web is no longer supporting Python2 please consider upgrading to Python3') + log.info('*** Python2 is EOL since end of 2019, this version of Calibre-Web is no longer supporting Python2, please update your installation to Python3 ***') + print('*** Python2 is EOL since end of 2019, this version of Calibre-Web is no longer supporting Python2, please update your installation to Python3 ***') + sys.exit(5) Principal(app) lm.init_app(app) app.secret_key = os.getenv('SECRET_KEY', config_sql.get_flask_session_key(ub.session)) diff --git a/cps/converter.py b/cps/converter.py index f37168c7..6b0f22e4 100644 --- a/cps/converter.py +++ b/cps/converter.py @@ -39,7 +39,9 @@ def _get_command_version(path, pattern, argument=None): if argument: command.append(argument) try: - return process_wait(command, pattern=pattern).string + match = process_wait(command, pattern=pattern) + if isinstance(match, re.Match): + return match.string except Exception as ex: log.warning("%s: %s", path, ex) return _EXECUTION_ERROR diff --git a/cps/templates/config_db.html b/cps/templates/config_db.html index 0d1d1bce..e0e1bfd1 100644 --- a/cps/templates/config_db.html +++ b/cps/templates/config_db.html @@ -20,7 +20,7 @@
- {% if not gdriveError %} + {% if not gdriveError and config.config_use_google_drive %} {% if show_authenticate_google_drive and config.config_use_google_drive %}
{{_('Authenticate Google Drive')}} diff --git a/cps/templates/logviewer.html b/cps/templates/logviewer.html index db27bdf4..6c26a5b6 100644 --- a/cps/templates/logviewer.html +++ b/cps/templates/logviewer.html @@ -15,10 +15,10 @@
{% if log_enable %} - {{_('Download Calibre-Web Log')}} + {{_('Download Calibre-Web Log')}} {% endif %} {% if accesslog_enable %} - {{_('Download Access Log')}} + {{_('Download Access Log')}} {% endif %}
diff --git a/cps/web.py b/cps/web.py index d9f634a4..871a3de3 100644 --- a/cps/web.py +++ b/cps/web.py @@ -1523,6 +1523,7 @@ def login(): login_result, error = services.ldap.bind_user(form['username'], form['password']) if login_result: login_user(user, remember=bool(form.get('remember_me'))) + ub.store_user_session() log.debug(u"You are now logged in as: '%s'", user.name) flash(_(u"you are now logged in as: '%(nickname)s'", nickname=user.name), category="success") @@ -1530,6 +1531,7 @@ def login(): elif login_result is None and user and check_password_hash(str(user.password), form['password']) \ and user.name != "Guest": login_user(user, remember=bool(form.get('remember_me'))) + ub.store_user_session() log.info("Local Fallback Login as: '%s'", user.name) flash(_(u"Fallback Login as: '%(nickname)s', LDAP Server not reachable, or user not known", nickname=user.name), @@ -1559,6 +1561,7 @@ def login(): else: if user and check_password_hash(str(user.password), form['password']) and user.name != "Guest": login_user(user, remember=bool(form.get('remember_me'))) + ub.store_user_session() log.debug(u"You are now logged in as: '%s'", user.name) flash(_(u"You are now logged in as: '%(nickname)s'", nickname=user.name), category="success") config.config_is_initial = False @@ -1582,6 +1585,7 @@ def login(): @login_required def logout(): if current_user is not None and current_user.is_authenticated: + ub.delete_user_session(current_user.id, flask_session.get('_id',"")) logout_user() if feature_support['oauth'] and (config.config_login_type == 2 or config.config_login_type == 3): logout_oauth_user() diff --git a/test/Calibre-Web TestSummary_Linux.html b/test/Calibre-Web TestSummary_Linux.html index b4ef6efa..f9a9218a 100644 --- a/test/Calibre-Web TestSummary_Linux.html +++ b/test/Calibre-Web TestSummary_Linux.html @@ -37,20 +37,20 @@
-

Start Time: 2021-05-27 20:44:36

+

Start Time: 2021-07-29 20:37:20

-

Stop Time: 2021-05-28 00:00:32

+

Stop Time: 2021-07-30 00:10:27

-

Duration: 2h 37 min

+

Duration: 2h 47 min

@@ -234,12 +234,12 @@ - + TestCli 8 - 8 - 0 - 0 + 4 + 3 + 1 0 Detail @@ -266,20 +266,68 @@ - +
TestCli - test_change_password
- PASS + +
+ FAIL +
+ + + + - +
TestCli - test_cli_SSL_files
- PASS + +
+ FAIL +
+ + + + @@ -293,11 +341,41 @@ - +
TestCli - test_cli_different_settings_database
- PASS + +
+ ERROR +
+ + + + @@ -311,22 +389,50 @@ - +
TestCli - test_settingsdb_not_writeable
- PASS + +
+ FAIL +
+ + + + - + TestCliGdrivedb 2 - 2 - 0 0 + 1 + 1 0 Detail @@ -335,20 +441,72 @@ - +
TestCliGdrivedb - test_cli_gdrive_location
- PASS + +
+ FAIL +
+ + + + - +
TestCliGdrivedb - test_gdrive_db_nonwrite
- PASS + +
+ ERROR +
+ + + + @@ -402,11 +560,11 @@ - + TestEbookConvertCalibre 11 - 11 - 0 + 9 + 2 0 0 @@ -461,11 +619,33 @@ - +
TestEbookConvertCalibre - test_convert_wrong_excecutable
- PASS + +
+ FAIL +
+ + + + @@ -479,11 +659,33 @@ - +
TestEbookConvertCalibre - test_email_only
- PASS + +
+ FAIL +
+ + + + @@ -669,12 +871,12 @@ - + TestEditAdditionalBooks 13 - 12 - 0 + 8 0 + 4 1 Detail @@ -755,29 +957,159 @@ - +
TestEditAdditionalBooks - test_upload_edit_role
- PASS + +
+ ERROR +
+ + + + - +
TestEditAdditionalBooks - test_upload_metadata_cbr
- PASS + +
+ ERROR +
+ + + + - +
TestEditAdditionalBooks - test_upload_metadata_cbt
- PASS + +
+ ERROR +
+ + + + @@ -808,31 +1140,111 @@ - +
TestEditAdditionalBooks - test_writeonly_path
- PASS + +
+ ERROR +
+ + + + - - TestEditBooks - 35 - 34 + + _ErrorHolder + 1 0 0 1 + 0 - Detail + Detail - + + +
tearDownClass (test_edit_additional_books)
+ + +
+ ERROR +
+ + + + + + + + + + + TestEditBooks + 35 + 25 + 0 + 9 + 1 + + Detail + + + + + +
TestEditBooks - test_download_book
@@ -841,7 +1253,7 @@ - +
TestEditBooks - test_edit_author
@@ -850,7 +1262,7 @@ - +
TestEditBooks - test_edit_category
@@ -859,7 +1271,7 @@ - +
TestEditBooks - test_edit_comments
@@ -868,7 +1280,7 @@ - +
TestEditBooks - test_edit_custom_bool
@@ -877,7 +1289,7 @@ - +
TestEditBooks - test_edit_custom_categories
@@ -886,7 +1298,7 @@ - +
TestEditBooks - test_edit_custom_comment
@@ -895,7 +1307,7 @@ - +
TestEditBooks - test_edit_custom_date
@@ -904,7 +1316,7 @@ - +
TestEditBooks - test_edit_custom_float
@@ -913,7 +1325,7 @@ - +
TestEditBooks - test_edit_custom_int
@@ -922,7 +1334,7 @@ - +
TestEditBooks - test_edit_custom_rating
@@ -931,7 +1343,7 @@ - +
TestEditBooks - test_edit_custom_single_select
@@ -940,7 +1352,7 @@ - +
TestEditBooks - test_edit_custom_text
@@ -949,7 +1361,7 @@ - +
TestEditBooks - test_edit_language
@@ -958,7 +1370,7 @@ - +
TestEditBooks - test_edit_publisher
@@ -967,7 +1379,7 @@ - +
TestEditBooks - test_edit_publishing_date
@@ -976,7 +1388,7 @@ - +
TestEditBooks - test_edit_rating
@@ -985,7 +1397,7 @@ - +
TestEditBooks - test_edit_series
@@ -994,7 +1406,7 @@ - +
TestEditBooks - test_edit_title
@@ -1003,19 +1415,19 @@ - +
TestEditBooks - test_rename_uppercase_lowercase
- SKIP + SKIP
-