1
0
mirror of https://github.com/janeczku/calibre-web synced 2024-12-01 05:49:58 +00:00

Test Email now send to user's email address (#834)

Added forgot/reset password routine (#1098, #1063)
This commit is contained in:
Ozzieisaacs 2019-12-15 17:08:17 +01:00
parent b6d7207ec3
commit eabc6e23be
4 changed files with 52 additions and 26 deletions

View File

@ -36,11 +36,10 @@ from flask_babel import gettext as _
from sqlalchemy import and_ from sqlalchemy import and_
from sqlalchemy.exc import IntegrityError from sqlalchemy.exc import IntegrityError
from sqlalchemy.sql.expression import func from sqlalchemy.sql.expression import func
from werkzeug.security import generate_password_hash
from . import constants, logger, helper, services from . import constants, logger, helper, services
from . import db, ub, web_server, get_locale, config, updater_thread, babel, gdriveutils from . import db, ub, web_server, get_locale, config, updater_thread, babel, gdriveutils
from .helper import speaking_language, check_valid_domain, send_test_mail, generate_random_password, send_registration_mail from .helper import speaking_language, check_valid_domain, send_test_mail, reset_password, generate_password_hash
from .gdriveutils import is_gdrive_ready, gdrive_support from .gdriveutils import is_gdrive_ready, gdrive_support
from .web import admin_required, render_title_template, before_request, unconfigured, login_required_if_no_ano from .web import admin_required, render_title_template, before_request, unconfigured, login_required_if_no_ano
@ -524,15 +523,15 @@ def update_mailsettings():
config.save() config.save()
if to_save.get("test"): if to_save.get("test"):
if current_user.kindle_mail: if current_user.email:
result = send_test_mail(current_user.kindle_mail, current_user.nickname) result = send_test_mail(current_user.email, current_user.nickname)
if result is None: if result is None:
flash(_(u"Test e-mail successfully send to %(kindlemail)s", kindlemail=current_user.kindle_mail), flash(_(u"Test e-mail successfully send to %(kindlemail)s", kindlemail=current_user.email),
category="success") category="success")
else: else:
flash(_(u"There was an error sending the Test e-mail: %(res)s", res=result), category="error") flash(_(u"There was an error sending the Test e-mail: %(res)s", res=result), category="error")
else: else:
flash(_(u"Please configure your kindle e-mail address first..."), category="error") flash(_(u"Please configure your e-mail address first..."), category="error")
else: else:
flash(_(u"E-mail server settings updated"), category="success") flash(_(u"E-mail server settings updated"), category="success")
@ -644,15 +643,10 @@ def reset_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:
existing_user = ub.session.query(ub.User).filter(ub.User.id == user_id).first() ret, message = reset_password(user_id)
password = generate_random_password() if ret == 1:
existing_user.password = generate_password_hash(password) flash(_(u"Password for user %(user)s reset", user=message), category="success")
try: else:
ub.session.commit()
send_registration_mail(existing_user.email, existing_user.nickname, password, True)
flash(_(u"Password for user %(user)s reset", user=existing_user.nickname), category="success")
except Exception:
ub.session.rollback()
flash(_(u"An unknown error occurred. Please try again later."), category="error") flash(_(u"An unknown error occurred. Please try again later."), category="error")
return redirect(url_for('admin.admin')) return redirect(url_for('admin.admin'))

View File

@ -41,6 +41,7 @@ from flask_babel import gettext as _
from flask_login import current_user from flask_login import current_user
from sqlalchemy.sql.expression import true, false, and_, or_, text, func from sqlalchemy.sql.expression import true, false, and_, or_, text, func
from werkzeug.datastructures import Headers from werkzeug.datastructures import Headers
from werkzeug.security import generate_password_hash
try: try:
from urllib.parse import quote from urllib.parse import quote
@ -407,6 +408,19 @@ def delete_book_gdrive(book, book_format):
return error return error
def reset_password(user_id):
existing_user = ub.session.query(ub.User).filter(ub.User.id == user_id).first()
password = generate_random_password()
existing_user.password = generate_password_hash(password)
try:
ub.session.commit()
send_registration_mail(existing_user.email, existing_user.nickname, password, True)
return (1, existing_user.nickname)
except Exception:
ub.session.rollback()
return (0, None)
def generate_random_password(): def generate_random_password():
s = "abcdefghijklmnopqrstuvwxyz01234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%&*()?" s = "abcdefghijklmnopqrstuvwxyz01234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%&*()?"
passlen = 8 passlen = 8

View File

@ -18,6 +18,9 @@
</label> </label>
</div> </div>
<button type="submit" name="submit" class="btn btn-default">{{_('Submit')}}</button> <button type="submit" name="submit" class="btn btn-default">{{_('Submit')}}</button>
{% if config.config_login_type == 0 and mail%}
<button type="submit" name="forgot" value="forgot" class="btn btn-default">{{_('Forgot password')}}</button>
{% endif %}
{% if config.config_remote_login %} {% if config.config_remote_login %}
<a href="{{url_for('web.remote_login')}}" class="pull-right">{{_('Log in with magic link')}}</a> <a href="{{url_for('web.remote_login')}}" class="pull-right">{{_('Log in with magic link')}}</a>
{% endif %} {% endif %}

View File

@ -38,8 +38,7 @@ from flask import render_template, request, redirect, send_from_directory, make_
from flask_babel import gettext as _ from flask_babel import gettext as _
from flask_login import login_user, logout_user, login_required, current_user from flask_login import login_user, logout_user, login_required, current_user
from sqlalchemy.exc import IntegrityError from sqlalchemy.exc import IntegrityError
from sqlalchemy.sql.expression import text, func, true, false, not_, and_, \ from sqlalchemy.sql.expression import text, func, true, false, not_, and_, exists
exists
from werkzeug.exceptions import default_exceptions from werkzeug.exceptions import default_exceptions
from werkzeug.datastructures import Headers from werkzeug.datastructures import Headers
from werkzeug.security import generate_password_hash, check_password_hash from werkzeug.security import generate_password_hash, check_password_hash
@ -50,7 +49,7 @@ from .gdriveutils import getFileFromEbooksFolder, do_gdrive_download
from .helper import common_filters, get_search_results, fill_indexpage, speaking_language, check_valid_domain, \ from .helper import common_filters, get_search_results, fill_indexpage, speaking_language, check_valid_domain, \
order_authors, get_typeahead, render_task_status, json_serial, get_cc_columns, \ order_authors, get_typeahead, render_task_status, json_serial, get_cc_columns, \
get_book_cover, get_download_link, send_mail, generate_random_password, send_registration_mail, \ get_book_cover, get_download_link, send_mail, generate_random_password, send_registration_mail, \
check_send_to_kindle, check_read_formats, lcase, tags_filters check_send_to_kindle, check_read_formats, lcase, tags_filters, reset_password
from .pagination import Pagination from .pagination import Pagination
from .redirect import redirect_back from .redirect import redirect_back
@ -1043,7 +1042,7 @@ def download_link(book_id, book_format):
@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() settings = config.get_mail_settings()
if settings.get("mail_server", "mail.example.com") == "mail.example.com": 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,
@ -1139,18 +1138,34 @@ def login():
ipAdress = request.headers.get('X-Forwarded-For', request.remote_addr) ipAdress = request.headers.get('X-Forwarded-For', request.remote_addr)
log.info('LDAP Login failed for user "%s" IP-adress: %s', form['username'], ipAdress) log.info('LDAP 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")
else:
ipAdress = request.headers.get('X-Forwarded-For', request.remote_addr)
if 'forgot' in form and form['forgot'] == 'forgot':
if user != None and user.nickname != "Guest":
ret, __ = reset_password(user.id)
if ret == 1:
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)
else:
flash(_(u"An unknown error occurred. Please try again later."), category="error")
else:
flash(_(u"Please enter valid username to reset password"), category="error")
log.info('Username missing for password reset IP-adress: %s', ipAdress)
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)
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"))
ipAdress = request.headers.get('X-Forwarded-For', request.remote_addr) 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, page="login") return render_title_template('login.html', title=_(u"login"), next_url=next_url, config=config,
mail = mail_configured, page="login")
@web.route('/logout') @web.route('/logout')