Skip to content

Commit

Permalink
Merge branch 'janeczku:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
holta authored Jun 20, 2024
2 parents ad9c02a + 64e4a11 commit 07e2a05
Show file tree
Hide file tree
Showing 47 changed files with 322 additions and 228 deletions.
3 changes: 2 additions & 1 deletion cps/MyLoginManager.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,13 @@
from flask_login.utils import decode_cookie
from flask_login.signals import user_loaded_from_cookie


class MyLoginManager(LoginManager):
def _session_protection_failed(self):
sess = session._get_current_object()
ident = self._session_identifier_generator()
if(sess and not (len(sess) == 1
and sess.get('csrf_token', None))) and ident != sess.get('_id', None):
and sess.get('csrf_token', None))) and ident != sess.get('_id', None):
return super(). _session_protection_failed()
return False

Expand Down
1 change: 1 addition & 0 deletions cps/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
else:
limiter = None


def create_app():
if csrf:
csrf.init_app(app)
Expand Down
25 changes: 11 additions & 14 deletions cps/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,7 @@ def edit_list_user(param):
elif param.endswith('role'):
value = int(vals['field_index'])
if user.name == "Guest" and value in \
[constants.ROLE_ADMIN, constants.ROLE_PASSWD, constants.ROLE_EDIT_SHELFS]:
[constants.ROLE_ADMIN, constants.ROLE_PASSWD, constants.ROLE_EDIT_SHELFS]:
raise Exception(_("Guest can't have this role"))
# check for valid value, last on checks for power of 2 value
if value > 0 and value <= constants.ROLE_VIEWER and (value & value - 1 == 0 or value == 1):
Expand Down Expand Up @@ -945,15 +945,15 @@ def do_full_kobo_sync(userid):
def check_valid_read_column(column):
if column != "0":
if not calibre_db.session.query(db.CustomColumns).filter(db.CustomColumns.id == column) \
.filter(and_(db.CustomColumns.datatype == 'bool', db.CustomColumns.mark_for_delete == 0)).all():
.filter(and_(db.CustomColumns.datatype == 'bool', db.CustomColumns.mark_for_delete == 0)).all():
return False
return True


def check_valid_restricted_column(column):
if column != "0":
if not calibre_db.session.query(db.CustomColumns).filter(db.CustomColumns.id == column) \
.filter(and_(db.CustomColumns.datatype == 'text', db.CustomColumns.mark_for_delete == 0)).all():
.filter(and_(db.CustomColumns.datatype == 'text', db.CustomColumns.mark_for_delete == 0)).all():
return False
return True

Expand Down Expand Up @@ -999,10 +999,7 @@ def get_drives(current):
for d in string.ascii_uppercase:
if os.path.exists('{}:'.format(d)) and current[0].lower() != d.lower():
drive = "{}:\\".format(d)
data = {"name": drive, "fullpath": drive}
data["sort"] = "_" + data["fullpath"].lower()
data["type"] = "dir"
data["size"] = ""
data = {"name": drive, "fullpath": drive, "type": "dir", "size": "", "sort": "_" + drive.lower()}
drive_letters.append(data)
return drive_letters

Expand Down Expand Up @@ -1142,12 +1139,12 @@ def _configuration_oauth_helper(to_save):
reboot_required = False
for element in oauthblueprints:
if to_save["config_" + str(element['id']) + "_oauth_client_id"] != element['oauth_client_id'] \
or to_save["config_" + str(element['id']) + "_oauth_client_secret"] != element['oauth_client_secret']:
or to_save["config_" + str(element['id']) + "_oauth_client_secret"] != element['oauth_client_secret']:
reboot_required = True
element['oauth_client_id'] = to_save["config_" + str(element['id']) + "_oauth_client_id"]
element['oauth_client_secret'] = to_save["config_" + str(element['id']) + "_oauth_client_secret"]
if to_save["config_" + str(element['id']) + "_oauth_client_id"] \
and to_save["config_" + str(element['id']) + "_oauth_client_secret"]:
and to_save["config_" + str(element['id']) + "_oauth_client_secret"]:
active_oauths += 1
element["active"] = 1
else:
Expand Down Expand Up @@ -1202,9 +1199,9 @@ def _configuration_ldap_helper(to_save):
config.save()

if not config.config_ldap_provider_url \
or not config.config_ldap_port \
or not config.config_ldap_dn \
or not config.config_ldap_user_object:
or not config.config_ldap_port \
or not config.config_ldap_dn \
or not config.config_ldap_user_object:
return reboot_required, _configuration_result(_('Please Enter a LDAP Provider, '
'Port, DN and User Object Identifier'))

Expand Down Expand Up @@ -1372,7 +1369,7 @@ def update_scheduledtasks():
error = False
to_save = request.form.to_dict()
if 0 <= int(to_save.get("schedule_start_time")) <= 23:
_config_int( to_save, "schedule_start_time")
_config_int(to_save, "schedule_start_time")
else:
flash(_("Invalid start time for task specified"), category="error")
error = True
Expand Down Expand Up @@ -1720,7 +1717,7 @@ def _db_configuration_update_helper():
return _db_configuration_result('{}'.format(ex), gdrive_error)

if db_change or not db_valid or not config.db_configured \
or config.config_calibre_dir != to_save["config_calibre_dir"]:
or config.config_calibre_dir != to_save["config_calibre_dir"]:
if not os.path.exists(metadata_db) or not to_save['config_calibre_dir']:
return _db_configuration_result(_('DB Location is not Valid, Please Enter Correct Path'), gdrive_error)
else:
Expand Down
1 change: 1 addition & 0 deletions cps/babel.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

babel = Babel()


def get_locale():
# if a user is logged in, use the locale from the user settings
if current_user is not None and hasattr(current_user, "locale"):
Expand Down
10 changes: 9 additions & 1 deletion cps/clean_html.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,21 @@
try:
# at least bleach 6.0 is needed -> incomplatible change from list arguments to set arguments
from bleach import clean as clean_html
from bleach.sanitizer import ALLOWED_TAGS
bleach = True
except ImportError:
from nh3 import clean as clean_html
bleach = False


def clean_string(unsafe_text, book_id=0):
try:
safe_text = clean_html(unsafe_text)
if bleach:
allowed_tags = list(ALLOWED_TAGS)
allowed_tags.extend(['p', 'span', 'div', 'pre'])
safe_text = clean_html(unsafe_text, tags=set(allowed_tags))
else:
safe_text = clean_html(unsafe_text)
except ParserError as e:
log.error("Comments of book {} are corrupted: {}".format(book_id, e))
safe_text = ""
Expand Down
35 changes: 24 additions & 11 deletions cps/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,19 @@ def version_info():

class CliParameter(object):

def __init__(self):
self.user_credentials = None
self.ip_address = None
self.allow_localhost = None
self.reconnect_enable = None
self.memory_backend = None
self.dry_run = None
self.certfilepath = None
self.keyfilepath = None
self.gd_path = None
self.settings_path = None
self.logpath = None

def init(self):
self.arg_parser()

Expand All @@ -44,22 +57,25 @@ def arg_parser(self):
prog='cps.py')
parser.add_argument('-p', metavar='path', help='path and name to settings db, e.g. /opt/cw.db')
parser.add_argument('-g', metavar='path', help='path and name to gdrive db, e.g. /opt/gd.db')
parser.add_argument('-c', metavar='path', help='path and name to SSL certfile, e.g. /opt/test.cert, '
'works only in combination with keyfile')
parser.add_argument('-c', metavar='path', help='path and name to SSL certfile, '
'e.g. /opt/test.cert, works only in combination with keyfile')
parser.add_argument('-k', metavar='path', help='path and name to SSL keyfile, e.g. /opt/test.key, '
'works only in combination with certfile')
parser.add_argument('-o', metavar='path', help='path and name Calibre-Web logfile')
parser.add_argument('-v', '--version', action='version', help='Shows version number and exits Calibre-Web',
parser.add_argument('-v', '--version', action='version', help='Shows version number '
'and exits Calibre-Web',
version=version_info())
parser.add_argument('-i', metavar='ip-address', help='Server IP-Address to listen')
parser.add_argument('-m', action='store_true', help='Use Memory-backend as limiter backend, use this parameter in case of miss configured backend')
parser.add_argument('-m', action='store_true',
help='Use Memory-backend as limiter backend, use this parameter '
'in case of miss configured backend')
parser.add_argument('-s', metavar='user:pass',
help='Sets specific username to new password and exits Calibre-Web')
parser.add_argument('-f', action='store_true', help='Flag is depreciated and will be removed in next version')
parser.add_argument('-l', action='store_true', help='Allow loading covers from localhost')
parser.add_argument('-d', action='store_true', help='Dry run of updater to check file permissions in advance '
'and exits Calibre-Web')
parser.add_argument('-r', action='store_true', help='Enable public database reconnect route under /reconnect')
parser.add_argument('-d', action='store_true', help='Dry run of updater to check file permissions '
'in advance and exits Calibre-Web')
parser.add_argument('-r', action='store_true', help='Enable public database reconnect '
'route under /reconnect')
args = parser.parse_args()

self.logpath = args.o or ""
Expand Down Expand Up @@ -130,6 +146,3 @@ def arg_parser(self):
if self.user_credentials and ":" not in self.user_credentials:
print("No valid 'username:password' format")
sys.exit(3)

if args.f:
print("Warning: -f flag is depreciated and will be removed in next version")
37 changes: 30 additions & 7 deletions cps/config_sql.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class _Flask_Settings(_Base):
flask_session_key = Column(BLOB, default=b"")

def __init__(self, key):
super().__init__()
self.flask_session_key = key


Expand Down Expand Up @@ -82,7 +83,9 @@ class _Settings(_Base):
config_random_books = Column(Integer, default=4)
config_authors_max = Column(Integer, default=0)
config_read_column = Column(Integer, default=0)
config_title_regex = Column(String, default=r'^(A|The|An|Der|Die|Das|Den|Ein|Eine|Einen|Dem|Des|Einem|Eines|Le|La|Les|L\'|Un|Une)\s+')
config_title_regex = Column(String,
default=r'^(A|The|An|Der|Die|Das|Den|Ein|Eine'
r'|Einen|Dem|Des|Einem|Eines|Le|La|Les|L\'|Un|Une)\s+')
config_theme = Column(Integer, default=0)

config_log_level = Column(SmallInteger, default=logger.DEFAULT_LOG_LEVEL)
Expand Down Expand Up @@ -178,6 +181,26 @@ def __repr__(self):
class ConfigSQL(object):
# pylint: disable=no-member
def __init__(self):
'''self.config_calibre_uuid = None
self.config_calibre_split_dir = None
self.dirty = None
self.config_logfile = None
self.config_upload_formats = None
self.mail_gmail_token = None
self.mail_server_type = None
self.mail_server = None
self.config_log_level = None
self.config_allowed_column_value = None
self.config_denied_column_value = None
self.config_allowed_tags = None
self.config_denied_tags = None
self.config_default_show = None
self.config_default_role = None
self.config_keyfile = None
self.config_certfile = None
self.config_rarfile_location = None
self.config_kepubifypath = None
self.config_binariesdir = None'''
self.__dict__["dirty"] = list()

def init_config(self, session, secret_key, cli):
Expand All @@ -191,16 +214,16 @@ def init_config(self, session, secret_key, cli):

change = False

if self.config_binariesdir == None: # pylint: disable=access-member-before-definition
if self.config_binariesdir is None:
change = True
self.config_binariesdir = autodetect_calibre_binaries()
self.config_converterpath = autodetect_converter_binary(self.config_binariesdir)

if self.config_kepubifypath == None: # pylint: disable=access-member-before-definition
if self.config_kepubifypath is None:
change = True
self.config_kepubifypath = autodetect_kepubify_binary()

if self.config_rarfile_location == None: # pylint: disable=access-member-before-definition
if self.config_rarfile_location is None:
change = True
self.config_rarfile_location = autodetect_unrar_binary()
if change:
Expand Down Expand Up @@ -429,8 +452,7 @@ def _encrypt_fields(session, secret_key):
{_Settings.mail_password_e: crypter.encrypt(settings.mail_password.encode())})
if settings.config_ldap_serv_password:
session.query(_Settings).update(
{_Settings.config_ldap_serv_password_e:
crypter.encrypt(settings.config_ldap_serv_password.encode())})
{_Settings.config_ldap_serv_password_e: crypter.encrypt(settings.config_ldap_serv_password.encode())})
session.commit()


Expand Down Expand Up @@ -546,7 +568,7 @@ def load_configuration(session, secret_key):

def get_flask_session_key(_session):
flask_settings = _session.query(_Flask_Settings).one_or_none()
if flask_settings == None:
if flask_settings is None:
flask_settings = _Flask_Settings(os.urandom(32))
_session.add(flask_settings)
_session.commit()
Expand All @@ -557,6 +579,7 @@ def get_encryption_key(key_path):
key_file = os.path.join(key_path, ".key")
generate = True
error = ""
key = None
if os.path.exists(key_file) and os.path.getsize(key_file) > 32:
with open(key_file, "rb") as f:
key = f.read()
Expand Down
3 changes: 2 additions & 1 deletion cps/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,12 +171,13 @@
_extension = ""
if sys.platform == "win32":
_extension = ".exe"
SUPPORTED_CALIBRE_BINARIES = {binary:binary + _extension for binary in ["ebook-convert", "calibredb"]}
SUPPORTED_CALIBRE_BINARIES = {binary: binary + _extension for binary in ["ebook-convert", "calibredb"]}


def has_flag(value, bit_flag):
return bit_flag == (bit_flag & (value or 0))


def selected_roles(dictionary):
return sum(v for k, v in ALL_ROLES.items() if k in dictionary)

Expand Down
Loading

0 comments on commit 07e2a05

Please sign in to comment.