Update requirements

Catch error for invalid oauth tokens
Fixes for displaying error messages on deleting books from list
Fixes for displaying error messages on deleting bookformats
This commit is contained in:
Ozzie Isaacs 2021-04-13 19:08:02 +02:00
parent d32b2ca524
commit 67775bc797
7 changed files with 514 additions and 121 deletions

View File

@ -245,7 +245,7 @@ def list_users():
off = int(request.args.get("offset") or 0) off = int(request.args.get("offset") or 0)
limit = int(request.args.get("limit") or 10) limit = int(request.args.get("limit") or 10)
search = request.args.get("search") search = request.args.get("search")
sort = request.args.get("sort", "state") sort = request.args.get("sort", "id")
order = request.args.get("order", "").lower() order = request.args.get("order", "").lower()
state = None state = None
if sort == "state": if sort == "state":
@ -254,7 +254,7 @@ def list_users():
if sort != "state" and order: if sort != "state" and order:
order = text(sort + " " + order) order = text(sort + " " + order)
elif not state: elif not state:
order = ub.User.name.desc() order = ub.User.id.asc()
all_user = ub.session.query(ub.User) all_user = ub.session.query(ub.User)
if not config.config_anonbrowse: if not config.config_anonbrowse:
@ -371,7 +371,7 @@ def edit_list_user(param):
'message':_(u"No admin user remaining, can't remove admin role", 'message':_(u"No admin user remaining, can't remove admin role",
nick=user.name)}), mimetype='application/json') nick=user.name)}), mimetype='application/json')
user.role &= ~int(vals['field_index']) user.role &= ~int(vals['field_index'])
elif param == 'sidebar_view': elif param.startswith('sidebar'):
if user.name == "Guest" and int(vals['field_index']) == constants.SIDEBAR_READ_AND_UNREAD: if user.name == "Guest" and int(vals['field_index']) == constants.SIDEBAR_READ_AND_UNREAD:
raise Exception(_("Guest can't have this view")) raise Exception(_("Guest can't have this view"))
if vals['value'] == 'true': if vals['value'] == 'true':

View File

@ -315,19 +315,19 @@ def delete_book(book_id, book_format, jsonResponse):
result, error = helper.delete_book(book, config.config_calibre_dir, book_format=book_format.upper()) result, error = helper.delete_book(book, config.config_calibre_dir, book_format=book_format.upper())
if not result: if not result:
if jsonResponse: if jsonResponse:
return json.dumps({"location": url_for("editbook.edit_book"), return json.dumps([{"location": url_for("editbook.edit_book", book_id=book_id),
"type": "alert", "type": "danger",
"format": "", "format": "",
"error": error}), "message": error}])
else: else:
flash(error, category="error") flash(error, category="error")
return redirect(url_for('editbook.edit_book', book_id=book_id)) return redirect(url_for('editbook.edit_book', book_id=book_id))
if error: if error:
if jsonResponse: if jsonResponse:
warning = {"location": url_for("editbook.edit_book"), warning = {"location": url_for("editbook.edit_book", book_id=book_id),
"type": "warning", "type": "warning",
"format": "", "format": "",
"error": error} "message": error}
else: else:
flash(error, category="warning") flash(error, category="warning")
if not book_format: if not book_format:
@ -339,6 +339,15 @@ def delete_book(book_id, book_format, jsonResponse):
except Exception as ex: except Exception as ex:
log.debug_or_exception(ex) log.debug_or_exception(ex)
calibre_db.session.rollback() calibre_db.session.rollback()
if jsonResponse:
return json.dumps([{"location": url_for("editbook.edit_book", book_id=book_id),
"type": "danger",
"format": "",
"message": ex}])
else:
flash(str(ex), category="error")
return redirect(url_for('editbook.edit_book', book_id=book_id))
else: else:
# book not found # book not found
log.error('Book with id "%s" could not be deleted: not found', book_id) log.error('Book with id "%s" could not be deleted: not found', book_id)

View File

@ -30,6 +30,7 @@ from flask_babel import gettext as _
from flask_dance.consumer import oauth_authorized, oauth_error from flask_dance.consumer import oauth_authorized, oauth_error
from flask_dance.contrib.github import make_github_blueprint, github from flask_dance.contrib.github import make_github_blueprint, github
from flask_dance.contrib.google import make_google_blueprint, google from flask_dance.contrib.google import make_google_blueprint, google
from oauthlib.oauth2 import TokenExpiredError, InvalidGrantError
from flask_login import login_user, current_user, login_required from flask_login import login_user, current_user, login_required
from sqlalchemy.orm.exc import NoResultFound from sqlalchemy.orm.exc import NoResultFound
@ -146,6 +147,7 @@ def bind_oauth_or_register(provider_id, provider_user_id, redirect_url, provider
ub.session.add(oauth_entry) ub.session.add(oauth_entry)
ub.session.commit() ub.session.commit()
flash(_(u"Link to %(oauth)s Succeeded", oauth=provider_name), category="success") flash(_(u"Link to %(oauth)s Succeeded", oauth=provider_name), category="success")
log.info("Link to {} Succeeded".format(provider_name))
return redirect(url_for('web.profile')) return redirect(url_for('web.profile'))
except Exception as ex: except Exception as ex:
log.debug_or_exception(ex) log.debug_or_exception(ex)
@ -194,6 +196,7 @@ def unlink_oauth(provider):
ub.session.commit() ub.session.commit()
logout_oauth_user() logout_oauth_user()
flash(_(u"Unlink to %(oauth)s Succeeded", oauth=oauth_check[provider]), category="success") flash(_(u"Unlink to %(oauth)s Succeeded", oauth=oauth_check[provider]), category="success")
log.info("Unlink to {} Succeeded".format(oauth_check[provider]))
except Exception as ex: except Exception as ex:
log.debug_or_exception(ex) log.debug_or_exception(ex)
ub.session.rollback() ub.session.rollback()
@ -257,11 +260,13 @@ if ub.oauth_support:
def github_logged_in(blueprint, token): def github_logged_in(blueprint, token):
if not token: if not token:
flash(_(u"Failed to log in with GitHub."), category="error") flash(_(u"Failed to log in with GitHub."), category="error")
log.error("Failed to log in with GitHub")
return False return False
resp = blueprint.session.get("/user") resp = blueprint.session.get("/user")
if not resp.ok: if not resp.ok:
flash(_(u"Failed to fetch user info from GitHub."), category="error") flash(_(u"Failed to fetch user info from GitHub."), category="error")
log.error("Failed to fetch user info from GitHub")
return False return False
github_info = resp.json() github_info = resp.json()
@ -273,11 +278,13 @@ if ub.oauth_support:
def google_logged_in(blueprint, token): def google_logged_in(blueprint, token):
if not token: if not token:
flash(_(u"Failed to log in with Google."), category="error") flash(_(u"Failed to log in with Google."), category="error")
log.error("Failed to log in with Google")
return False return False
resp = blueprint.session.get("/oauth2/v2/userinfo") resp = blueprint.session.get("/oauth2/v2/userinfo")
if not resp.ok: if not resp.ok:
flash(_(u"Failed to fetch user info from Google."), category="error") flash(_(u"Failed to fetch user info from Google."), category="error")
log.error("Failed to fetch user info from Google")
return False return False
google_info = resp.json() google_info = resp.json()
@ -318,11 +325,16 @@ if ub.oauth_support:
def github_login(): def github_login():
if not github.authorized: if not github.authorized:
return redirect(url_for('github.login')) return redirect(url_for('github.login'))
try:
account_info = github.get('/user') account_info = github.get('/user')
if account_info.ok: if account_info.ok:
account_info_json = account_info.json() account_info_json = account_info.json()
return bind_oauth_or_register(oauthblueprints[0]['id'], account_info_json['id'], 'github.login', 'github') return bind_oauth_or_register(oauthblueprints[0]['id'], account_info_json['id'], 'github.login', 'github')
flash(_(u"GitHub Oauth error, please retry later."), category="error") flash(_(u"GitHub Oauth error, please retry later."), category="error")
log.error("GitHub Oauth error, please retry later")
except (InvalidGrantError, TokenExpiredError) as e:
flash(_(u"GitHub Oauth error: {}").format(e), category="error")
log.error(e)
return redirect(url_for('web.login')) return redirect(url_for('web.login'))
@ -337,11 +349,16 @@ def github_login_unlink():
def google_login(): def google_login():
if not google.authorized: if not google.authorized:
return redirect(url_for("google.login")) return redirect(url_for("google.login"))
try:
resp = google.get("/oauth2/v2/userinfo") resp = google.get("/oauth2/v2/userinfo")
if resp.ok: if resp.ok:
account_info_json = resp.json() account_info_json = resp.json()
return bind_oauth_or_register(oauthblueprints[1]['id'], account_info_json['id'], 'google.login', 'google') return bind_oauth_or_register(oauthblueprints[1]['id'], account_info_json['id'], 'google.login', 'google')
flash(_(u"Google Oauth error, please retry later."), category="error") flash(_(u"Google Oauth error, please retry later."), category="error")
log.error("Google Oauth error, please retry later")
except (InvalidGrantError, TokenExpiredError) as e:
flash(_(u"Google Oauth error: {}").format(e), category="error")
log.error(e)
return redirect(url_for('web.login')) return redirect(url_for('web.login'))

View File

@ -92,7 +92,7 @@
{% for message in get_flashed_messages(with_categories=True) %} {% for message in get_flashed_messages(with_categories=True) %}
{%if message[0] == "error" %} {%if message[0] == "error" %}
<div class="row-fluid text-center" style="margin-top: -20px;"> <div class="row-fluid text-center" style="margin-top: -20px;">
<div id="flash_alert" class="alert alert-danger">{{ message[1] }}</div> <div id="flash_danger" class="alert alert-danger">{{ message[1] }}</div>
</div> </div>
{%endif%} {%endif%}
{%if message[0] == "info" %} {%if message[0] == "info" %}

View File

@ -756,7 +756,7 @@ def list_books():
off = int(request.args.get("offset") or 0) off = int(request.args.get("offset") or 0)
limit = int(request.args.get("limit") or config.config_books_per_page) limit = int(request.args.get("limit") or config.config_books_per_page)
search = request.args.get("search") search = request.args.get("search")
sort = request.args.get("sort", "state") sort = request.args.get("sort", "id")
order = request.args.get("order", "").lower() order = request.args.get("order", "").lower()
state = None state = None

View File

@ -26,7 +26,7 @@ python-ldap>=3.0.0,<3.4.0
Flask-SimpleLDAP>=1.4.0,<1.5.0 Flask-SimpleLDAP>=1.4.0,<1.5.0
#oauth #oauth
Flask-Dance>=1.4.0,<3.1.0 Flask-Dance>=1.4.0,<4.1.0
SQLAlchemy-Utils>=0.33.5,<0.38.0 SQLAlchemy-Utils>=0.33.5,<0.38.0
# extracting metadata # extracting metadata

File diff suppressed because one or more lines are too long