mirror of
				https://github.com/janeczku/calibre-web
				synced 2025-10-31 07:13:02 +00:00 
			
		
		
		
	User and admin pages are working again
This commit is contained in:
		| @@ -38,7 +38,7 @@ from sqlalchemy.exc import IntegrityError | |||||||
| from gdriveutils import is_gdrive_ready, gdrive_support, downloadFile, deleteDatabaseOnChange, listRootFolders | from gdriveutils import is_gdrive_ready, gdrive_support, downloadFile, deleteDatabaseOnChange, listRootFolders | ||||||
| import helper | import helper | ||||||
| from werkzeug.security import generate_password_hash | from werkzeug.security import generate_password_hash | ||||||
| from sqlalchemy.sql.expression import text | from oauth_bb import oauth_check | ||||||
|  |  | ||||||
| try: | try: | ||||||
|     from goodreads.client import GoodreadsClient |     from goodreads.client import GoodreadsClient | ||||||
| @@ -591,7 +591,7 @@ def new_user(): | |||||||
|         content.sidebar_view = config.config_default_show |         content.sidebar_view = config.config_default_show | ||||||
|         content.mature_content = bool(config.config_default_show & ub.MATURE_CONTENT) |         content.mature_content = bool(config.config_default_show & ub.MATURE_CONTENT) | ||||||
|     return render_title_template("user_edit.html", new_user=1, content=content, translations=translations, |     return render_title_template("user_edit.html", new_user=1, content=content, translations=translations, | ||||||
|                                  languages=languages, title=_(u"Add new user"), page="newuser") |                                  languages=languages, title=_(u"Add new user"), page="newuser", registered_oauth=oauth_check) | ||||||
|  |  | ||||||
|  |  | ||||||
| @admi.route("/admin/mailsettings", methods=["GET", "POST"]) | @admi.route("/admin/mailsettings", methods=["GET", "POST"]) | ||||||
| @@ -767,7 +767,7 @@ def edit_user(user_id): | |||||||
|             flash(_(u"An unknown error occured."), category="error") |             flash(_(u"An unknown error occured."), category="error") | ||||||
|     return render_title_template("user_edit.html", translations=translations, languages=languages, new_user=0, |     return render_title_template("user_edit.html", translations=translations, languages=languages, new_user=0, | ||||||
|                                  content=content, downloads=downloads, title=_(u"Edit User %(nick)s", |                                  content=content, downloads=downloads, title=_(u"Edit User %(nick)s", | ||||||
|                                                                                nick=content.nickname), page="edituser") |                                                                                nick=content.nickname), page="edituser", registered_oauth=oauth_check) | ||||||
|  |  | ||||||
|  |  | ||||||
| @admi.route("/admin/resetpassword/<int:user_id>") | @admi.route("/admin/resetpassword/<int:user_id>") | ||||||
|   | |||||||
							
								
								
									
										39
									
								
								cps/ldap.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								cps/ldap.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | |||||||
|  | #!/usr/bin/env python | ||||||
|  | # -*- coding: utf-8 -*- | ||||||
|  |  | ||||||
|  | #  This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) | ||||||
|  | #    Copyright (C) 2018-2019 Krakinou | ||||||
|  | # | ||||||
|  | #  This program is free software: you can redistribute it and/or modify | ||||||
|  | #  it under the terms of the GNU General Public License as published by | ||||||
|  | #  the Free Software Foundation, either version 3 of the License, or | ||||||
|  | #  (at your option) any later version. | ||||||
|  | # | ||||||
|  | #  This program is distributed in the hope that it will be useful, | ||||||
|  | #  but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  | #  GNU General Public License for more details. | ||||||
|  | # | ||||||
|  | #  You should have received a copy of the GNU General Public License | ||||||
|  | #  along with this program. If not, see <http://www.gnu.org/licenses/>. | ||||||
|  |  | ||||||
|  | import ldap | ||||||
|  | from cps import ub, app, request | ||||||
|  | from flask import flash, url_for | ||||||
|  | from redirect import redirect_back | ||||||
|  | from flask_login import login_user | ||||||
|  | from flask_babel import gettext as _ | ||||||
|  |  | ||||||
|  | def login(form, user): | ||||||
|  |     try: | ||||||
|  |         ub.User.try_login(form['username'], form['password']) | ||||||
|  |         login_user(user, remember=True) | ||||||
|  |         flash(_(u"you are now logged in as: '%(nickname)s'", nickname=user.nickname), category="success") | ||||||
|  |         return redirect_back(url_for("web.index")) | ||||||
|  |     except ldap.INVALID_CREDENTIALS: | ||||||
|  |         ipAdress = request.headers.get('X-Forwarded-For', request.remote_addr) | ||||||
|  |         app.logger.info('LDAP Login failed for user "' + form['username'] + '" IP-adress: ' + ipAdress) | ||||||
|  |         flash(_(u"Wrong Username or Password"), category="error") | ||||||
|  |  | ||||||
|  | def logout(): | ||||||
|  |     pass | ||||||
| @@ -25,16 +25,33 @@ from flask_dance.contrib.google import make_google_blueprint, google | |||||||
| from flask_dance.consumer import oauth_authorized, oauth_error | from flask_dance.consumer import oauth_authorized, oauth_error | ||||||
| from sqlalchemy.orm.exc import NoResultFound | from sqlalchemy.orm.exc import NoResultFound | ||||||
| from oauth import OAuthBackend | from oauth import OAuthBackend | ||||||
| from flask import flash, session, redirect, url_for, request | from flask import flash, session, redirect, url_for, request, make_response, abort | ||||||
|  | import json | ||||||
| from cps import config, app | from cps import config, app | ||||||
| import ub | import ub | ||||||
| from flask_login import login_user, login_required, current_user | from flask_login import login_user, login_required, current_user | ||||||
| from flask_babel import gettext as _ | from flask_babel import gettext as _ | ||||||
| from web import github_oauth_required | # from web import github_oauth_required | ||||||
|  | from functools import wraps | ||||||
|  |  | ||||||
|  |  | ||||||
| oauth_check = {} | oauth_check = {} | ||||||
|  |  | ||||||
|  | def github_oauth_required(f): | ||||||
|  |     @wraps(f) | ||||||
|  |     def inner(*args, **kwargs): | ||||||
|  |         if config.config_use_github_oauth: | ||||||
|  |             return f(*args, **kwargs) | ||||||
|  |         if request.is_xhr: | ||||||
|  |             data = {'status': 'error', 'message': 'Not Found'} | ||||||
|  |             response = make_response(json.dumps(data, ensure_ascii=False)) | ||||||
|  |             response.headers["Content-Type"] = "application/json; charset=utf-8" | ||||||
|  |             return response, 404 | ||||||
|  |         abort(404) | ||||||
|  |  | ||||||
|  |     return inner | ||||||
|  |  | ||||||
|  |  | ||||||
| def register_oauth_blueprint(blueprint, show_name): | def register_oauth_blueprint(blueprint, show_name): | ||||||
|     if blueprint.name != "": |     if blueprint.name != "": | ||||||
|         oauth_check[blueprint.name] = show_name |         oauth_check[blueprint.name] = show_name | ||||||
| @@ -246,7 +263,7 @@ def github_error(blueprint, error, error_description=None, error_uri=None): | |||||||
|     ) |     ) | ||||||
|     flash(msg, category="error") |     flash(msg, category="error") | ||||||
|  |  | ||||||
|  | ''' | ||||||
| @oauth.route('/github') | @oauth.route('/github') | ||||||
| @github_oauth_required | @github_oauth_required | ||||||
| def github_login(): | def github_login(): | ||||||
| @@ -277,7 +294,7 @@ def google_login(): | |||||||
|         return bind_oauth_or_register(google_blueprint.name, account_info_json['id'], 'google.login') |         return bind_oauth_or_register(google_blueprint.name, account_info_json['id'], 'google.login') | ||||||
|     flash(_(u"Google Oauth error, please retry later."), category="error") |     flash(_(u"Google Oauth error, please retry later."), category="error") | ||||||
|     return redirect(url_for('login')) |     return redirect(url_for('login')) | ||||||
|  | ''' | ||||||
|  |  | ||||||
| @oauth_error.connect_via(google_blueprint) | @oauth_error.connect_via(google_blueprint) | ||||||
| def google_error(blueprint, error, error_description=None, error_uri=None): | def google_error(blueprint, error, error_description=None, error_uri=None): | ||||||
| @@ -292,8 +309,8 @@ def google_error(blueprint, error, error_description=None, error_uri=None): | |||||||
|     ) |     ) | ||||||
|     flash(msg, category="error") |     flash(msg, category="error") | ||||||
|  |  | ||||||
|  | ''' | ||||||
| @oauth.route('/unlink/google', methods=["GET"]) | @oauth.route('/unlink/google', methods=["GET"]) | ||||||
| @login_required | @login_required | ||||||
| def google_login_unlink(): | def google_login_unlink(): | ||||||
|     return unlink_oauth(google_blueprint.name) |     return unlink_oauth(google_blueprint.name)''' | ||||||
|   | |||||||
							
								
								
									
										22
									
								
								cps/ub.py
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								cps/ub.py
									
									
									
									
									
								
							| @@ -23,6 +23,7 @@ from sqlalchemy import exc | |||||||
| from sqlalchemy.ext.declarative import declarative_base | from sqlalchemy.ext.declarative import declarative_base | ||||||
| from sqlalchemy.orm import * | from sqlalchemy.orm import * | ||||||
| from flask_login import AnonymousUserMixin | from flask_login import AnonymousUserMixin | ||||||
|  | from flask_dance.consumer.backend.sqla import OAuthConsumerMixin | ||||||
| import sys | import sys | ||||||
| import os | import os | ||||||
| import logging | import logging | ||||||
| @@ -32,6 +33,11 @@ import datetime | |||||||
| from binascii import hexlify | from binascii import hexlify | ||||||
| import cli | import cli | ||||||
|  |  | ||||||
|  | try: | ||||||
|  |     import ldap | ||||||
|  | except ImportError: | ||||||
|  |     pass | ||||||
|  |  | ||||||
| engine = create_engine('sqlite:///{0}'.format(cli.settingspath), echo=False) | engine = create_engine('sqlite:///{0}'.format(cli.settingspath), echo=False) | ||||||
| Base = declarative_base() | Base = declarative_base() | ||||||
|  |  | ||||||
| @@ -176,13 +182,12 @@ class UserBase: | |||||||
|         return '<User %r>' % self.nickname |         return '<User %r>' % self.nickname | ||||||
|  |  | ||||||
|     #Login via LDAP method |     #Login via LDAP method | ||||||
|     ''''@staticmethod |     @staticmethod | ||||||
|     def try_login(username, password): |     def try_login(username, password): | ||||||
|         conn = get_ldap_connection() |         conn = get_ldap_connection() | ||||||
|         conn.simple_bind_s( |         conn.simple_bind_s( | ||||||
|              config.config_ldap_dn.replace("%s", username), |              config.config_ldap_dn.replace("%s", username), | ||||||
|              password |              password) | ||||||
|         )''' |  | ||||||
|  |  | ||||||
| # Baseclass for Users in Calibre-Web, settings which are depending on certain users are stored here. It is derived from | # Baseclass for Users in Calibre-Web, settings which are depending on certain users are stored here. It is derived from | ||||||
| # User Base (all access methods are declared there) | # User Base (all access methods are declared there) | ||||||
| @@ -202,11 +207,11 @@ class User(UserBase, Base): | |||||||
|     default_language = Column(String(3), default="all") |     default_language = Column(String(3), default="all") | ||||||
|     mature_content = Column(Boolean, default=True) |     mature_content = Column(Boolean, default=True) | ||||||
|  |  | ||||||
| ''' |  | ||||||
| class OAuth(OAuthConsumerMixin, Base): | class OAuth(OAuthConsumerMixin, Base): | ||||||
|     provider_user_id = Column(String(256)) |     provider_user_id = Column(String(256)) | ||||||
|     user_id = Column(Integer, ForeignKey(User.id)) |     user_id = Column(Integer, ForeignKey(User.id)) | ||||||
|     user = relationship(User)''' |     user = relationship(User) | ||||||
|  |  | ||||||
|  |  | ||||||
| # Class for anonymous user is derived from User base and completly overrides methods and properties for the | # Class for anonymous user is derived from User base and completly overrides methods and properties for the | ||||||
| @@ -776,6 +781,13 @@ def clean_database(): | |||||||
|     session.query(RemoteAuthToken).filter(now > RemoteAuthToken.expiration).delete() |     session.query(RemoteAuthToken).filter(now > RemoteAuthToken.expiration).delete() | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #get LDAP connection | ||||||
|  | def get_ldap_connection(): | ||||||
|  |     conn = ldap.initialize('ldap://{}'.format(config.config_ldap_provider_url)) | ||||||
|  |     return conn | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def create_default_config(): | def create_default_config(): | ||||||
|     settings = Settings() |     settings = Settings() | ||||||
|     settings.mail_server = "mail.example.com" |     settings.mail_server = "mail.example.com" | ||||||
|   | |||||||
							
								
								
									
										53
									
								
								cps/web.py
									
									
									
									
									
								
							
							
						
						
									
										53
									
								
								cps/web.py
									
									
									
									
									
								
							| @@ -26,8 +26,6 @@ from flask import render_template, request, redirect, url_for, send_from_directo | |||||||
| from werkzeug.exceptions import default_exceptions | from werkzeug.exceptions import default_exceptions | ||||||
| import helper | import helper | ||||||
| import os | import os | ||||||
| # from sqlalchemy.sql.expression import func |  | ||||||
| # from sqlalchemy.sql.expression import false |  | ||||||
| from sqlalchemy.exc import IntegrityError | from sqlalchemy.exc import IntegrityError | ||||||
| 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 flask_babel import gettext as _ | from flask_babel import gettext as _ | ||||||
| @@ -36,21 +34,31 @@ from werkzeug.datastructures import Headers | |||||||
| from babel import Locale as LC | from babel import Locale as LC | ||||||
| from babel.dates import format_date | from babel.dates import format_date | ||||||
| from babel.core import UnknownLocaleError | from babel.core import UnknownLocaleError | ||||||
| from functools import wraps |  | ||||||
| import base64 | import base64 | ||||||
| from sqlalchemy.sql import * | from sqlalchemy.sql import * | ||||||
| import json | import json | ||||||
| import datetime | import datetime | ||||||
| from iso639 import languages as isoLanguages | from iso639 import languages as isoLanguages | ||||||
| import os.path |  | ||||||
| import re | import re | ||||||
| import db | import db | ||||||
| import gdriveutils | import gdriveutils | ||||||
| from redirect import redirect_back | from redirect import redirect_back | ||||||
| from cps import lm, babel, ub, config, get_locale, language_table, app | from cps import lm, babel, ub, config, get_locale, language_table, app | ||||||
| from pagination import Pagination | from pagination import Pagination | ||||||
| # from admin import check_valid_domain | from sqlalchemy.sql.expression import text | ||||||
| # from oauth_bb import oauth_check, register_user_with_oauth |  | ||||||
|  | from oauth_bb import oauth_check, register_user_with_oauth, logout_oauth_user, get_oauth_status | ||||||
|  |  | ||||||
|  | '''try: | ||||||
|  |     oauth_support = True | ||||||
|  | except ImportError: | ||||||
|  |     oauth_support = False''' | ||||||
|  |  | ||||||
|  | try: | ||||||
|  |     import ldap | ||||||
|  |     ldap_support = True | ||||||
|  | except ImportError: | ||||||
|  |     ldap_support = False | ||||||
|  |  | ||||||
| try: | try: | ||||||
|     from googleapiclient.errors import HttpError |     from googleapiclient.errors import HttpError | ||||||
| @@ -70,7 +78,7 @@ except ImportError: | |||||||
|     levenshtein_support = False |     levenshtein_support = False | ||||||
|  |  | ||||||
| try: | try: | ||||||
|     from functools import reduce |     from functools import reduce, wraps | ||||||
| except ImportError: | except ImportError: | ||||||
|     pass  # We're not using Python 3 |     pass  # We're not using Python 3 | ||||||
|  |  | ||||||
| @@ -169,21 +177,6 @@ def remote_login_required(f): | |||||||
|     return inner |     return inner | ||||||
|  |  | ||||||
|  |  | ||||||
| def github_oauth_required(f): |  | ||||||
|     @wraps(f) |  | ||||||
|     def inner(*args, **kwargs): |  | ||||||
|         if config.config_use_github_oauth: |  | ||||||
|             return f(*args, **kwargs) |  | ||||||
|         if request.is_xhr: |  | ||||||
|             data = {'status': 'error', 'message': 'Not Found'} |  | ||||||
|             response = make_response(json.dumps(data, ensure_ascii=False)) |  | ||||||
|             response.headers["Content-Type"] = "application/json; charset=utf-8" |  | ||||||
|             return response, 404 |  | ||||||
|         abort(404) |  | ||||||
|  |  | ||||||
|     return inner |  | ||||||
|  |  | ||||||
|  |  | ||||||
| def google_oauth_required(f): | def google_oauth_required(f): | ||||||
|     @wraps(f) |     @wraps(f) | ||||||
|     def inner(*args, **kwargs): |     def inner(*args, **kwargs): | ||||||
| @@ -1299,7 +1292,8 @@ def register(): | |||||||
|                 try: |                 try: | ||||||
|                     ub.session.add(content) |                     ub.session.add(content) | ||||||
|                     ub.session.commit() |                     ub.session.commit() | ||||||
|                     # register_user_with_oauth(content) |                     if oauth_support: | ||||||
|  |                         register_user_with_oauth(content) | ||||||
|                     helper.send_registration_mail(to_save["email"], to_save["nickname"], password) |                     helper.send_registration_mail(to_save["email"], to_save["nickname"], password) | ||||||
|                 except Exception: |                 except Exception: | ||||||
|                     ub.session.rollback() |                     ub.session.rollback() | ||||||
| @@ -1316,7 +1310,8 @@ def register(): | |||||||
|             flash(_(u"This username or e-mail address is already in use."), category="error") |             flash(_(u"This username or e-mail address is already in use."), category="error") | ||||||
|             return render_title_template('register.html', title=_(u"register"), page="register") |             return render_title_template('register.html', title=_(u"register"), page="register") | ||||||
|  |  | ||||||
|     # register_user_with_oauth() |     if oauth_support: | ||||||
|  |         register_user_with_oauth() | ||||||
|     return render_title_template('register.html', config=config, title=_(u"register"), page="register") |     return render_title_template('register.html', config=config, title=_(u"register"), page="register") | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -1330,7 +1325,7 @@ def login(): | |||||||
|         form = request.form.to_dict() |         form = request.form.to_dict() | ||||||
|         user = ub.session.query(ub.User).filter(func.lower(ub.User.nickname) == form['username'].strip().lower())\ |         user = ub.session.query(ub.User).filter(func.lower(ub.User.nickname) == form['username'].strip().lower())\ | ||||||
|             .first() |             .first() | ||||||
|         if config.config_use_ldap and user: |         '''if config.config_use_ldap and user: | ||||||
|             import ldap |             import ldap | ||||||
|             try: |             try: | ||||||
|                 ub.User.try_login(form['username'], form['password']) |                 ub.User.try_login(form['username'], form['password']) | ||||||
| @@ -1341,7 +1336,8 @@ def login(): | |||||||
|                 ipAdress = request.headers.get('X-Forwarded-For', request.remote_addr) |                 ipAdress = request.headers.get('X-Forwarded-For', request.remote_addr) | ||||||
|                 app.logger.info('LDAP Login failed for user "' + form['username'] + '" IP-adress: ' + ipAdress) |                 app.logger.info('LDAP Login failed for user "' + form['username'] + '" IP-adress: ' + ipAdress) | ||||||
|                 flash(_(u"Wrong Username or Password"), category="error") |                 flash(_(u"Wrong Username or Password"), category="error") | ||||||
|         elif user and check_password_hash(user.password, form['password']) and user.nickname is not "Guest": |         el''' | ||||||
|  |         if user and check_password_hash(user.password, form['password']) and user.nickname is not "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")) | ||||||
| @@ -1362,7 +1358,8 @@ def login(): | |||||||
| def logout(): | def logout(): | ||||||
|     if current_user is not None and current_user.is_authenticated: |     if current_user is not None and current_user.is_authenticated: | ||||||
|         logout_user() |         logout_user() | ||||||
|         # logout_oauth_user() |         if oauth_support: | ||||||
|  |             logout_oauth_user() | ||||||
|     return redirect(url_for('web.login')) |     return redirect(url_for('web.login')) | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -1475,7 +1472,7 @@ def profile(): | |||||||
|     downloads = list() |     downloads = list() | ||||||
|     languages = speaking_language() |     languages = speaking_language() | ||||||
|     translations = babel.list_translations() + [LC('en')] |     translations = babel.list_translations() + [LC('en')] | ||||||
|     oauth_status = None  # oauth_status = get_oauth_status() |     oauth_status = get_oauth_status() | ||||||
|     for book in content.downloads: |     for book in content.downloads: | ||||||
|         downloadBook = db.session.query(db.Books).filter(db.Books.id == book.book_id).first() |         downloadBook = db.session.query(db.Books).filter(db.Books.id == book.book_id).first() | ||||||
|         if downloadBook: |         if downloadBook: | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Ozzieisaacs
					Ozzieisaacs