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 2ff736662..f37168c74 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 d567e9b3e..b6ea6760b 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 c6c65851e..273756868 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 273756868..3cc4a0709 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 de34cc86e..23f727ab4 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 e5a67cde4..ccad60c22 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 b38f783cf..3d2566e0d 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 bad5f1f6c..411e3fdd4 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 c192ffcb2..9771b7c93 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 7af417ea2..586625cc9 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 da862fb22..ea2949481 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 ba3c5ae3e..a14afb68b 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 23f727ab4..007783355 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 f479f07f1..3b226acbe 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 1a2814fc1..ce2307309 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 007783355..70a6090ee 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 a14afb68b..9dab285ad 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 4e32db80a..b011bae8e 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 b932f56d3..f79ec5596 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 ccad60c22..76a5a87d4 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 d57994b4f..f6d8207d2 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 1e79c43d3..f8beffc53 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 d300fc65a..b11500e40 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 81ab2d998..b63819be1 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 1ad79dbd7..7ee96f7d9 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 1e49f29ac..fc53a69a1 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 77251e022..1d7813101 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 a6c4236f9..113811707 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 b54d8d953..cc67542c3 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 f79ec5596..2da7b09bc 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 cfa549f9e..dd5e858ed 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 431eeff8c..9556ba666 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 9556ba666..229eaade1 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 229eaade1..8ec4da455 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 cc83a1b53..6fb30fc37 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 000000000..2f36fac8e --- /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 ce2bd7803..c6006ad12 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 3266a4e95..9b004640c 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 f37168c74..6b0f22e49 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 0d1d1bce2..e0e1bfd10 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 db27bdf41..6c26a5b6a 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 d9f634a49..871a3de32 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 b4ef6efa2..f9a9218aa 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
-