Fixes from tests

This commit is contained in:
Ozzieisaacs 2019-12-28 16:18:21 +01:00
parent 62e8bee2a8
commit 01381488f4
8 changed files with 1884 additions and 4573 deletions

View File

@ -639,15 +639,20 @@ def edit_user(user_id):
@admi.route("/admin/resetpassword/<int:user_id>") @admi.route("/admin/resetpassword/<int:user_id>")
@login_required @login_required
@admin_required @admin_required
def reset_password(user_id): def reset_user_password(user_id):
if not config.config_public_reg: if not config.config_public_reg:
abort(404) abort(404)
if current_user is not None and current_user.is_authenticated: if current_user is not None and current_user.is_authenticated:
ret, message = reset_password(user_id) ret, message = reset_password(user_id)
if ret == 1: if ret == 1:
log.debug(u"Password for user %(user)s reset", user=message)
flash(_(u"Password for user %(user)s reset", user=message), category="success") flash(_(u"Password for user %(user)s reset", user=message), category="success")
else: elif ret == 0:
log.error(u"An unknown error occurred. Please try again later.")
flash(_(u"An unknown error occurred. Please try again later."), category="error") flash(_(u"An unknown error occurred. Please try again later."), category="error")
else:
log.error(u"Please configure the SMTP mail settings first...")
flash(_(u"Please configure the SMTP mail settings first..."), category="error")
return redirect(url_for('admin.admin')) return redirect(url_for('admin.admin'))
@ -681,6 +686,7 @@ def send_logfile(logtype):
@admi.route("/get_update_status", methods=['GET']) @admi.route("/get_update_status", methods=['GET'])
@login_required_if_no_ano @login_required_if_no_ano
def get_update_status(): def get_update_status():
log.info(u"Update status requested")
return updater_thread.get_available_updates(request.method, locale=get_locale()) return updater_thread.get_available_updates(request.method, locale=get_locale())

View File

@ -38,7 +38,7 @@ class _Settings(_Base):
__tablename__ = 'settings' __tablename__ = 'settings'
id = Column(Integer, primary_key=True) id = Column(Integer, primary_key=True)
mail_server = Column(String, default='mail.example.org') mail_server = Column(String, default=constants.DEFAULT_MAIL_SERVER)
mail_port = Column(Integer, default=25) mail_port = Column(Integer, default=25)
mail_use_ssl = Column(SmallInteger, default=0) mail_use_ssl = Column(SmallInteger, default=0)
mail_login = Column(String, default='mail@example.com') mail_login = Column(String, default='mail@example.com')
@ -189,6 +189,10 @@ class _ConfigSQL(object):
def get_mail_settings(self): def get_mail_settings(self):
return {k:v for k, v in self.__dict__.items() if k.startswith('mail_')} return {k:v for k, v in self.__dict__.items() if k.startswith('mail_')}
def get_mail_server_configured(self):
return not bool(self.mail_server == constants.DEFAULT_MAIL_SERVER)
def set_from_dictionary(self, dictionary, field, convertor=None, default=None): def set_from_dictionary(self, dictionary, field, convertor=None, default=None):
'''Possibly updates a field of this object. '''Possibly updates a field of this object.
The new value, if present, is grabbed from the given dictionary, and optionally passed through a convertor. The new value, if present, is grabbed from the given dictionary, and optionally passed through a convertor.

View File

@ -94,6 +94,7 @@ LOGIN_LDAP = 1
LOGIN_OAUTH = 2 LOGIN_OAUTH = 2
# LOGIN_OAUTH_GOOGLE = 3 # LOGIN_OAUTH_GOOGLE = 3
DEFAULT_MAIL_SERVER = "mail.example.org"
DEFAULT_PASSWORD = "admin123" DEFAULT_PASSWORD = "admin123"
DEFAULT_PORT = 8083 DEFAULT_PORT = 8083
@ -105,6 +106,7 @@ except ValueError:
del env_CALIBRE_PORT del env_CALIBRE_PORT
EXTENSIONS_AUDIO = {'mp3', 'm4a', 'm4b'} EXTENSIONS_AUDIO = {'mp3', 'm4a', 'm4b'}
EXTENSIONS_CONVERT = {'pdf', 'epub', 'mobi', 'azw3', 'docx', 'rtf', 'fb2', 'lit', 'lrf', 'txt', 'htmlz', 'rtf', 'odt'} EXTENSIONS_CONVERT = {'pdf', 'epub', 'mobi', 'azw3', 'docx', 'rtf', 'fb2', 'lit', 'lrf', 'txt', 'htmlz', 'rtf', 'odt'}
EXTENSIONS_UPLOAD = {'txt', 'pdf', 'epub', 'mobi', 'azw', 'azw3', 'cbr', 'cbz', 'cbt', 'djvu', 'prc', 'doc', 'docx', EXTENSIONS_UPLOAD = {'txt', 'pdf', 'epub', 'mobi', 'azw', 'azw3', 'cbr', 'cbz', 'cbt', 'djvu', 'prc', 'doc', 'docx',

View File

@ -125,7 +125,7 @@ def send_registration_mail(e_mail, user_name, default_password, resend=False):
if not resend: if not resend:
text += "Your new account at Calibre-Web has been created. Thanks for joining us!\r\n" text += "Your new account at Calibre-Web has been created. Thanks for joining us!\r\n"
text += "Please log in to your account using the following informations:\r\n" text += "Please log in to your account using the following informations:\r\n"
text += "User name: %s\n" % user_name text += "User name: %s\r\n" % user_name
text += "Password: %s\r\n" % default_password text += "Password: %s\r\n" % default_password
text += "Don't forget to change your password after first login.\r\n" text += "Don't forget to change your password after first login.\r\n"
text += "Sincerely\r\n\r\n" text += "Sincerely\r\n\r\n"
@ -416,6 +416,8 @@ def reset_password(user_id):
existing_user = ub.session.query(ub.User).filter(ub.User.id == user_id).first() existing_user = ub.session.query(ub.User).filter(ub.User.id == user_id).first()
password = generate_random_password() password = generate_random_password()
existing_user.password = generate_password_hash(password) existing_user.password = generate_password_hash(password)
if not config.get_mail_server_configured():
return (2, None)
try: try:
ub.session.commit() ub.session.commit()
send_registration_mail(existing_user.email, existing_user.nickname, password, True) send_registration_mail(existing_user.email, existing_user.nickname, password, True)

View File

@ -24,7 +24,7 @@ import signal
import socket import socket
try: try:
from gevent.pywsgi import WSGIServer from gevent.pyswsgi import WSGIServer
from gevent.pool import Pool from gevent.pool import Pool
from gevent import __version__ as _version from gevent import __version__ as _version
VERSION = 'Gevent ' + _version VERSION = 'Gevent ' + _version

View File

@ -15,7 +15,7 @@
</div> </div>
{% if ( g.user and g.user.role_passwd() or g.user.role_admin() ) and not content.role_anonymous() %} {% if ( g.user and g.user.role_passwd() or g.user.role_admin() ) and not content.role_anonymous() %}
{% if g.user and g.user.role_admin() and g.allow_registration and not new_user and not profile %} {% if g.user and g.user.role_admin() and g.allow_registration and not new_user and not profile %}
<div class="btn btn-default" id="resend_password"><a href="{{url_for('admin.reset_password', user_id = content.id) }}">{{_('Reset user Password')}}</a></div> <div class="btn btn-default" id="resend_password"><a href="{{url_for('admin.reset_user_password', user_id = content.id) }}">{{_('Reset user Password')}}</a></div>
{% else %} {% else %}
<div class="form-group"> <div class="form-group">
<label for="password">{{_('Password')}}</label> <label for="password">{{_('Password')}}</label>

View File

@ -1035,8 +1035,7 @@ def download_link(book_id, book_format):
@login_required @login_required
@download_required @download_required
def send_to_kindle(book_id, book_format, convert): def send_to_kindle(book_id, book_format, convert):
settings = config.get_mail_settings() if not config.get_mail_server_configured():
if settings.get("mail_server", "mail.example.org") == "mail.example.org":
flash(_(u"Please configure the SMTP mail settings first..."), category="error") flash(_(u"Please configure the SMTP mail settings first..."), category="error")
elif current_user.kindle_mail: elif current_user.kindle_mail:
result = send_mail(book_id, book_format, convert, current_user.kindle_mail, config.config_calibre_dir, result = send_mail(book_id, book_format, convert, current_user.kindle_mail, config.config_calibre_dir,
@ -1061,16 +1060,19 @@ def register():
abort(404) abort(404)
if current_user is not None and current_user.is_authenticated: if current_user is not None and current_user.is_authenticated:
return redirect(url_for('web.index')) return redirect(url_for('web.index'))
if not config.get_mail_server_configured():
flash(_(u"E-Mail server is not configured, please contact your administrator!"), category="error")
return render_title_template('register.html', title=_(u"register"), page="register")
if request.method == "POST": if request.method == "POST":
to_save = request.form.to_dict() to_save = request.form.to_dict()
if not to_save["nickname"] or not to_save["email"]: if not to_save["nickname"] or not to_save["email"]:
flash(_(u"Please fill out all fields!"), category="error") flash(_(u"Please fill out all fields!"), category="error")
return render_title_template('register.html', title=_(u"register"), page="register") return render_title_template('register.html', title=_(u"register"), page="register")
existing_user = ub.session.query(ub.User).filter(func.lower(ub.User.nickname) == to_save["nickname"] existing_user = ub.session.query(ub.User).filter(func.lower(ub.User.nickname) == to_save["nickname"]
.lower()).first() .lower()).first()
existing_email = ub.session.query(ub.User).filter(ub.User.email == to_save["email"].lower()).first() existing_email = ub.session.query(ub.User).filter(ub.User.email == to_save["email"].lower()).first()
if not existing_user and not existing_email: if not existing_user and not existing_email:
content = ub.User() content = ub.User()
# content.password = generate_password_hash(to_save["password"]) # content.password = generate_password_hash(to_save["password"])
@ -1110,10 +1112,12 @@ def register():
@web.route('/login', methods=['GET', 'POST']) @web.route('/login', methods=['GET', 'POST'])
def login(): def login():
if not config.db_configured: if not config.db_configured:
log.debug(u"Redirect to initial configuration")
return redirect(url_for('admin.basic_configuration')) return redirect(url_for('admin.basic_configuration'))
if current_user is not None and current_user.is_authenticated: if current_user is not None and current_user.is_authenticated:
return redirect(url_for('web.index')) return redirect(url_for('web.index'))
if config.config_login_type == constants.LOGIN_LDAP and not services.ldap: if config.config_login_type == constants.LOGIN_LDAP and not services.ldap:
log.error(u"Cannot activate LDAP authentication")
flash(_(u"Cannot activate LDAP authentication"), category="error") flash(_(u"Cannot activate LDAP authentication"), category="error")
if request.method == "POST": if request.method == "POST":
form = request.form.to_dict() form = request.form.to_dict()
@ -1123,10 +1127,12 @@ def login():
login_result = services.ldap.bind_user(form['username'], form['password']) login_result = services.ldap.bind_user(form['username'], form['password'])
if login_result: if login_result:
login_user(user, remember=True) login_user(user, remember=True)
log.debug(u"You are now logged in as: '%s'", user.nickname)
flash(_(u"you are now logged in as: '%(nickname)s'", nickname=user.nickname), flash(_(u"you are now logged in as: '%(nickname)s'", nickname=user.nickname),
category="success") category="success")
return redirect_back(url_for("web.index")) return redirect_back(url_for("web.index"))
if login_result is None: if login_result is None:
log.error('Could not login. LDAP server down, please contact your administrator')
flash(_(u"Could not login. LDAP server down, please contact your administrator"), category="error") flash(_(u"Could not login. LDAP server down, please contact your administrator"), category="error")
else: else:
ipAdress = request.headers.get('X-Forwarded-For', request.remote_addr) ipAdress = request.headers.get('X-Forwarded-For', request.remote_addr)
@ -1141,6 +1147,7 @@ def login():
flash(_(u"New Password was send to your email address"), category="info") flash(_(u"New Password was send to your email address"), category="info")
log.info('Password reset for user "%s" IP-adress: %s', form['username'], ipAdress) log.info('Password reset for user "%s" IP-adress: %s', form['username'], ipAdress)
else: else:
log.info(u"An unknown error occurred. Please try again later.")
flash(_(u"An unknown error occurred. Please try again later."), category="error") flash(_(u"An unknown error occurred. Please try again later."), category="error")
else: else:
flash(_(u"Please enter valid username to reset password"), category="error") flash(_(u"Please enter valid username to reset password"), category="error")
@ -1148,18 +1155,16 @@ def login():
else: else:
if user and check_password_hash(str(user.password), form['password']) and user.nickname != "Guest": if user and check_password_hash(str(user.password), form['password']) and user.nickname != "Guest":
login_user(user, remember=True) login_user(user, remember=True)
log.debug(u"You are now logged in as: '%s'", user.nickname)
flash(_(u"You are now logged in as: '%(nickname)s'", nickname=user.nickname), category="success") flash(_(u"You are now logged in as: '%(nickname)s'", nickname=user.nickname), category="success")
return redirect_back(url_for("web.index")) return redirect_back(url_for("web.index"))
else: else:
log.info('Login failed for user "%s" IP-adress: %s', form['username'], ipAdress) log.info('Login failed for user "%s" IP-adress: %s', form['username'], ipAdress)
flash(_(u"Wrong Username or Password"), category="error") flash(_(u"Wrong Username or Password"), category="error")
settings = config.get_mail_settings()
mail_configured = bool(settings.get("mail_server", "mail.example.org") != "mail.example.org")
next_url = url_for('web.index') next_url = url_for('web.index')
return render_title_template('login.html', title=_(u"login"), next_url=next_url, config=config, return render_title_template('login.html', title=_(u"login"), next_url=next_url, config=config,
mail = mail_configured, page="login") mail = config.get_mail_server_configured(), page="login")
@web.route('/logout') @web.route('/logout')
@ -1169,6 +1174,7 @@ def logout():
logout_user() logout_user()
if feature_support['oauth'] and (config.config_login_type == 2 or config.config_login_type == 3): if feature_support['oauth'] and (config.config_login_type == 2 or config.config_login_type == 3):
logout_oauth_user() logout_oauth_user()
log.debug(u"User logged out")
return redirect(url_for('web.login')) return redirect(url_for('web.login'))
@ -1180,7 +1186,7 @@ def remote_login():
ub.session.commit() ub.session.commit()
verify_url = url_for('web.verify_token', token=auth_token.auth_token, _external=true) verify_url = url_for('web.verify_token', token=auth_token.auth_token, _external=true)
log.debug(u"Remot Login request with token: %s", auth_token.auth_token)
return render_title_template('remote_login.html', title=_(u"login"), token=auth_token.auth_token, return render_title_template('remote_login.html', title=_(u"login"), token=auth_token.auth_token,
verify_url=verify_url, page="remotelogin") verify_url=verify_url, page="remotelogin")
@ -1194,6 +1200,7 @@ def verify_token(token):
# Token not found # Token not found
if auth_token is None: if auth_token is None:
flash(_(u"Token not found"), category="error") flash(_(u"Token not found"), category="error")
log.error(u"Remote Login token not found")
return redirect(url_for('web.index')) return redirect(url_for('web.index'))
# Token expired # Token expired
@ -1202,6 +1209,7 @@ def verify_token(token):
ub.session.commit() ub.session.commit()
flash(_(u"Token has expired"), category="error") flash(_(u"Token has expired"), category="error")
log.error(u"Remote Login token expired")
return redirect(url_for('web.index')) return redirect(url_for('web.index'))
# Update token with user information # Update token with user information
@ -1210,6 +1218,7 @@ def verify_token(token):
ub.session.commit() ub.session.commit()
flash(_(u"Success! Please return to your device"), category="success") flash(_(u"Success! Please return to your device"), category="success")
log.debug(u"Remote Login token for userid %s verified", auth_token.user_id)
return redirect(url_for('web.index')) return redirect(url_for('web.index'))
@ -1245,6 +1254,7 @@ def token_verified():
ub.session.commit() ub.session.commit()
data['status'] = 'success' data['status'] = 'success'
log.debug(u"Remote Login for userid %s succeded", user.id)
flash(_(u"you are now logged in as: '%(nickname)s'", nickname=user.nickname), category="success") flash(_(u"you are now logged in as: '%(nickname)s'", nickname=user.nickname), category="success")
response = make_response(json.dumps(data, ensure_ascii=False)) response = make_response(json.dumps(data, ensure_ascii=False))
@ -1272,8 +1282,6 @@ def profile():
downloads.append(db.session.query(db.Books).filter(db.Books.id == book.book_id).first()) downloads.append(db.session.query(db.Books).filter(db.Books.id == book.book_id).first())
else: else:
ub.delete_download(book.book_id) ub.delete_download(book.book_id)
# ub.session.query(ub.Downloads).filter(book.book_id == ub.Downloads.book_id).delete()
# ub.session.commit()
if request.method == "POST": if request.method == "POST":
to_save = request.form.to_dict() to_save = request.form.to_dict()
current_user.random_books = 0 current_user.random_books = 0
@ -1326,14 +1334,16 @@ def profile():
except IntegrityError: except IntegrityError:
ub.session.rollback() ub.session.rollback()
flash(_(u"Found an existing account for this e-mail address."), category="error") flash(_(u"Found an existing account for this e-mail address."), category="error")
log.debug(u"Found an existing account for this e-mail address.")
return render_title_template("user_edit.html", content=current_user, downloads=downloads, return render_title_template("user_edit.html", content=current_user, downloads=downloads,
translations=translations, translations=translations,
title=_(u"%(name)s's profile", name=current_user.nickname), page="me", title=_(u"%(name)s's profile", name=current_user.nickname), page="me",
registered_oauth=oauth_check, oauth_status=oauth_status) registered_oauth=oauth_check, oauth_status=oauth_status)
flash(_(u"Profile updated"), category="success") flash(_(u"Profile updated"), category="success")
log.debug(u"Profile updated")
return render_title_template("user_edit.html", translations=translations, profile=1, languages=languages, return render_title_template("user_edit.html", translations=translations, profile=1, languages=languages,
content=current_user, downloads=downloads, title= _(u"%(name)s's profile", content=current_user, downloads=downloads,
name=current_user.nickname), title= _(u"%(name)s's profile", name=current_user.nickname),
page="me", registered_oauth=oauth_check, oauth_status=oauth_status) page="me", registered_oauth=oauth_check, oauth_status=oauth_status)
@ -1347,6 +1357,7 @@ def read_book(book_id, book_format):
book = db.session.query(db.Books).filter(db.Books.id == book_id).filter(common_filters()).first() book = db.session.query(db.Books).filter(db.Books.id == book_id).filter(common_filters()).first()
if not book: if not book:
flash(_(u"Error opening eBook. File does not exist or file is not accessible:"), category="error") flash(_(u"Error opening eBook. File does not exist or file is not accessible:"), category="error")
log.debug(u"Error opening eBook. File does not exist or file is not accessible:")
return redirect(url_for("web.index")) return redirect(url_for("web.index"))
# check if book has bookmark # check if book has bookmark
@ -1356,20 +1367,25 @@ def read_book(book_id, book_format):
ub.Bookmark.book_id == book_id, ub.Bookmark.book_id == book_id,
ub.Bookmark.format == book_format.upper())).first() ub.Bookmark.format == book_format.upper())).first()
if book_format.lower() == "epub": 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=_(u"Read a Book"), bookmark=bookmark)
elif book_format.lower() == "pdf": 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=_(u"Read a Book"))
elif book_format.lower() == "txt": 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=_(u"Read a Book"))
else: else:
for fileExt in ["mp3", "m4b", "m4a"]: for fileExt in ["mp3", "m4b", "m4a"]:
if book_format.lower() == fileExt: if book_format.lower() == fileExt:
entries = db.session.query(db.Books).filter(db.Books.id == book_id).filter(common_filters()).first() entries = db.session.query(db.Books).filter(db.Books.id == book_id).filter(common_filters()).first()
log.debug(u"Start mp3 listening for %d", book_id)
return render_title_template('listenmp3.html', mp3file=book_id, audioformat=book_format.lower(), return render_title_template('listenmp3.html', mp3file=book_id, audioformat=book_format.lower(),
title=_(u"Read a Book"), entry=entries, bookmark=bookmark) title=_(u"Read a Book"), entry=entries, bookmark=bookmark)
for fileExt in ["cbr", "cbt", "cbz"]: for fileExt in ["cbr", "cbt", "cbz"]:
if book_format.lower() == fileExt: if book_format.lower() == fileExt:
all_name = str(book_id) all_name = str(book_id)
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=_(u"Read a Book"),
extension=fileExt) extension=fileExt)
# if feature_support['rar']: # if feature_support['rar']:
@ -1380,6 +1396,7 @@ def read_book(book_id, book_format):
# if book_format.lower() == fileext: # if book_format.lower() == fileext:
# return render_title_template('readcbr.html', comicfile=book_id, # return render_title_template('readcbr.html', comicfile=book_id,
# extension=fileext, title=_(u"Read a Book"), book=book) # extension=fileext, title=_(u"Read a Book"), book=book)
log.debug(u"Error opening eBook. File does not exist or file is not accessible:")
flash(_(u"Error opening eBook. File does not exist or file is not accessible."), category="error") flash(_(u"Error opening eBook. File does not exist or file is not accessible."), category="error")
return redirect(url_for("web.index")) return redirect(url_for("web.index"))
@ -1412,7 +1429,7 @@ def show_book(book_id):
matching_have_read_book = getattr(entries, 'custom_column_'+str(config.config_read_column)) matching_have_read_book = getattr(entries, 'custom_column_'+str(config.config_read_column))
have_read = len(matching_have_read_book) > 0 and matching_have_read_book[0].value have_read = len(matching_have_read_book) > 0 and matching_have_read_book[0].value
except KeyError: except KeyError:
log.error("Custom Column No.%d is not exisiting in calibre database", config.config_read_column) log.error("Custom Column No.%d is not existing in calibre database", config.config_read_column)
have_read = None have_read = None
else: else:
@ -1434,5 +1451,6 @@ def show_book(book_id):
is_xhr=request.is_xhr, title=entries.title, books_shelfs=book_in_shelfs, is_xhr=request.is_xhr, title=entries.title, books_shelfs=book_in_shelfs,
have_read=have_read, kindle_list=kindle_list, reader_list=reader_list, page="book") have_read=have_read, kindle_list=kindle_list, reader_list=reader_list, page="book")
else: else:
log.debug(u"Error opening eBook. File does not exist or file is not accessible:")
flash(_(u"Error opening eBook. File does not exist or file is not accessible:"), category="error") flash(_(u"Error opening eBook. File does not exist or file is not accessible:"), category="error")
return redirect(url_for("web.index")) return redirect(url_for("web.index"))

File diff suppressed because it is too large Load Diff