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:
parent
b6d7207ec3
commit
eabc6e23be
24
cps/admin.py
24
cps/admin.py
@ -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'))
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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 %}
|
||||||
|
27
cps/web.py
27
cps/web.py
@ -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')
|
||||||
|
Loading…
Reference in New Issue
Block a user