From f736a15c12b83347ec39bc37691aa376cad0fcc1 Mon Sep 17 00:00:00 2001 From: Ozzieisaacs Date: Sun, 2 Jun 2019 18:43:09 +0200 Subject: [PATCH 1/5] Fix for restart of newer versions of tornado during update Fix for updater with Beta Versions --- cps/server.py | 9 +++++---- cps/updater.py | 21 ++++++++++++++------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/cps/server.py b/cps/server.py index 0531a729..98baddf3 100644 --- a/cps/server.py +++ b/cps/server.py @@ -103,6 +103,7 @@ class server: ssl_options=ssl) http_server.listen(web.ub.config.config_port) self.wsgiserver=IOLoop.instance() + web.py3_gevent_link = self.wsgiserver self.wsgiserver.start() # wait for stop signal self.wsgiserver.close(True) @@ -142,10 +143,10 @@ class server: # ToDo: Somehow caused by circular import under python3 refactor if sys.version_info > (3, 0): if not self.wsgiserver: - if gevent_present: - self.wsgiserver = web.py3_gevent_link - else: - self.wsgiserver = IOLoop.instance() + # if gevent_present: + self.wsgiserver = web.py3_gevent_link + #else: + # self.wsgiserver = IOLoop.instance() if self.wsgiserver: if gevent_present: self.wsgiserver.close() diff --git a/cps/updater.py b/cps/updater.py index b2e5af09..7592b326 100644 --- a/cps/updater.py +++ b/cps/updater.py @@ -426,18 +426,25 @@ class Updater(threading.Thread): minor_version_update = int(commit[i]['tag_name'].split('.')[1]) patch_version_update = int(commit[i]['tag_name'].split('.')[2]) + current_version[0] = int(current_version[0]) + current_version[1] = int(current_version[1]) + try: + current_version[2] = int(current_version[2]) + except ValueError: + current_version[2] = int(current_version[2].split(' ')[0])-1 + # Check if major versions are identical search for newest nonenqual commit and update to this one - if major_version_update == int(current_version[0]): - if (minor_version_update == int(current_version[1]) and - patch_version_update > int(current_version[2])) or \ - minor_version_update > int(current_version[1]): + if major_version_update == current_version[0]: + if (minor_version_update == current_version[1] and + patch_version_update > current_version[2]) or \ + minor_version_update > current_version[1]: parents.append([commit[i]['tag_name'],commit[i]['body'].replace('\r\n', '

')]) i -= 1 continue - if major_version_update < int(current_version[0]): + if major_version_update < current_version[0]: i -= 1 continue - if major_version_update > int(current_version[0]): + if major_version_update > current_version[0]: # found update update to last version before major update, unless current version is on last version # before major update if commit[i+1]['tag_name'].split('.')[1] == current_version[1]: @@ -466,7 +473,7 @@ class Updater(threading.Thread): 'update': True, 'success': True, 'message': _( - u'A new update is available. Click on the button below to update to the latest version.'), + u'Click on the button below to update to the latest stable version.'), 'history': parents }) self.updateFile = commit[0]['zipball_url'] From e4d801bbafc6ca0be6e6d3d169148d9fd7cd7a27 Mon Sep 17 00:00:00 2001 From: Krakinou Date: Sun, 2 Jun 2019 22:07:22 +0200 Subject: [PATCH 2/5] initial flask_simpleldap implementation --- cps/templates/config_edit.html | 46 ++++++++++- cps/ub.py | 45 +++++++---- cps/web.py | 136 +++++++++++++++++++++++++-------- optional-requirements-ldap.txt | 3 +- 4 files changed, 181 insertions(+), 49 deletions(-) diff --git a/cps/templates/config_edit.html b/cps/templates/config_edit.html index c12d3a9f..fe2f41e6 100644 --- a/cps/templates/config_edit.html +++ b/cps/templates/config_edit.html @@ -165,16 +165,58 @@

-
+
- +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + +
diff --git a/cps/ub.py b/cps/ub.py index b5f7db9c..f3aab574 100644 --- a/cps/ub.py +++ b/cps/ub.py @@ -148,14 +148,6 @@ class UserBase: def __repr__(self): return '' % self.nickname - #Login via LDAP method - @staticmethod - def try_login(username, password): - conn = get_ldap_connection() - conn.simple_bind_s( - config.config_ldap_dn.replace("%s", username), - password - ) # 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) @@ -315,8 +307,18 @@ class Settings(Base): config_goodreads_api_key = Column(String) config_goodreads_api_secret = Column(String) config_use_ldap = Column(Boolean) - config_ldap_provider_url = Column(String) + config_ldap_provider_url = Column(String, default='localhost') + config_ldap_port = Column(SmallInteger, default=389) + config_ldap_schema = Column(String, default='ldap') + config_ldap_serv_username = Column(String) + config_ldap_serv_password = Column(String) + config_ldap_use_ssl = Column(Boolean, default=False) + config_ldap_use_tls = Column(Boolean, default=False) + config_ldap_require_cert = Column(Boolean, default=False) + config_ldap_cert_path = Column(String) config_ldap_dn = Column(String) + config_ldap_user_object = Column(String) + config_ldap_openldap = Column(Boolean) config_mature_content_tags = Column(String) config_logfile = Column(String) config_ebookconverter = Column(Integer, default=0) @@ -392,7 +394,17 @@ class Config: self.config_goodreads_api_secret = data.config_goodreads_api_secret self.config_use_ldap = data.config_use_ldap self.config_ldap_provider_url = data.config_ldap_provider_url + self.config_ldap_port = data.config_ldap_port + self.config_ldap_schema = data.config_ldap_schema + self.config_ldap_serv_username = data.config_ldap_serv_username + self.config_ldap_serv_password = data.config_ldap_serv_password + self.config_ldap_use_ssl = data.config_ldap_use_ssl + self.config_ldap_use_tls = data.config_ldap_use_ssl + self.config_ldap_require_cert = data.config_ldap_require_cert + self.config_ldap_cert_path = data.config_ldap_cert_path self.config_ldap_dn = data.config_ldap_dn + self.config_ldap_user_object = data.config_ldap_user_object + self.config_ldap_openldap = data.config_ldap_openldap if data.config_mature_content_tags: self.config_mature_content_tags = data.config_mature_content_tags else: @@ -681,7 +693,17 @@ def migrate_Database(): conn = engine.connect() conn.execute("ALTER TABLE Settings ADD column `config_use_ldap` INTEGER DEFAULT 0") conn.execute("ALTER TABLE Settings ADD column `config_ldap_provider_url` String DEFAULT ''") + conn.execute("ALTER TABLE Settings ADD column `config_ldap_port` INTEGER DEFAULT ''") + conn.execute("ALTER TABLE Settings ADD column `config_ldap_schema ` String DEFAULT ''") + conn.execute("ALTER TABLE Settings ADD column `config_ldap_serv_username` String DEFAULT ''") + conn.execute("ALTER TABLE Settings ADD column `config_ldap_serv_password` String DEFAULT ''") + conn.execute("ALTER TABLE Settings ADD column `config_ldap_use_ssl` INTEGER DEFAULT 0") + conn.execute("ALTER TABLE Settings ADD column `cconfig_ldap_use_tls` INTEGER DEFAULT 0") + conn.execute("ALTER TABLE Settings ADD column `config_ldap_require_cert` INTEGER DEFAULT 0") + conn.execute("ALTER TABLE Settings ADD column `config_ldap_cert_path` String DEFAULT ''") conn.execute("ALTER TABLE Settings ADD column `config_ldap_dn` String DEFAULT ''") + conn.execute("ALTER TABLE Settings ADD column `config_ldap_user_object` String DEFAULT ''") + conn.execute("ALTER TABLE Settings ADD column `config_ldap_openldap` INTEGER DEFAULT 0") session.commit() try: session.query(exists().where(Settings.config_theme)).scalar() @@ -799,11 +821,6 @@ else: migrate_Database() clean_database() -#get LDAP connection -def get_ldap_connection(): - import ldap - conn = ldap.initialize('ldap://{}'.format(config.config_ldap_provider_url)) - return conn # Generate global Settings Object accessible from every file config = Config() diff --git a/cps/web.py b/cps/web.py index dbc4c268..59ba9540 100644 --- a/cps/web.py +++ b/cps/web.py @@ -57,6 +57,7 @@ from redirect import redirect_back import time import server from reverseproxy import ReverseProxied +from __builtin__ import True try: from googleapiclient.errors import HttpError @@ -107,6 +108,11 @@ try: except ImportError: from flask_login.__about__ import __version__ as flask_loginVersion +try: + from flask_simpleldap import LDAP, LDAPException + ldap_support = True +except ImportError: + ldap_support = False # Global variables current_milli_time = lambda: int(round(time.time() * 1000)) @@ -176,6 +182,31 @@ lm.anonymous_user = ub.Anonymous app.secret_key = os.getenv('SECRET_KEY', 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT') db.setup_db() +if ldap_support and config.config_use_ldap: + app.confgi['LDAP_HOST'] = config.config_ldap_provider_url + app.config['LDAP_PORT'] = config.config_ldap_port + app.config['LDAP_SCHEMA'] = config.config_ldap_schema + app.config['LDAP_USERNAME'] = config.config_ldap_serv_username + app.config['LDAP_PASSWORD'] = config.config_ldap_serv_password + if config.config_ldap_use_ssl: + app.config['LDAP_USE_SSL'] = True + if config.config_ldap_use_tls: + app.config['LDAP_USE_TLS'] = True + app.config['LDAP_REQUIRE_CERT'] = config.config_ldap_require_cert + if config.config_ldap_require_cert: + app.config['LDAP_CERT_PATH'] = config.config_ldap_cert_path + app.config['LDAP_BASE_DN'] = config.config_ldap_dn + app.config['LDAP_USER_OBJECT_FILTER'] = config.config_ldap_user_object + if config.config_openldap: + app.config['LDAP_OPENLDAP'] = True + +# app.config['LDAP_BASE_DN'] = 'ou=users,dc=yunohost,dc=org' +# app.config['LDAP_USER_OBJECT_FILTER'] = '(uid=%s)' + ldap = LDAP(app) +elif config.config_use_ldap and not ldap_support: + app.logger.error('Cannot activate ldap support, did you run \'pip install --target vendor -r optional-requirements-ldap.txt\'?') + + with open(os.path.join(config.get_main_dir, 'cps/translations/iso639.pickle'), 'rb') as f: language_table = cPickle.load(f) @@ -256,6 +287,13 @@ def requires_basic_auth_if_no_ano(f): return decorated +def basic_auth_required_check(condition): + def decorator(f): + if condition and ldap_support: + return ldap.basic_auth_required(f) + return requires_basic_auth_if_no_ano(f) + return decorator + # simple pagination for the feed class Pagination(object): @@ -690,31 +728,31 @@ def before_request(): # Routing functions @app.route("/opds") -@requires_basic_auth_if_no_ano +@basic_auth_required_check(config.config_use_ldap) def feed_index(): return render_xml_template('index.xml') @app.route("/opds/osd") -@requires_basic_auth_if_no_ano +@basic_auth_required_check(config.config_use_ldap) def feed_osd(): return render_xml_template('osd.xml', lang='en-EN') @app.route("/opds/search/") -@requires_basic_auth_if_no_ano +@basic_auth_required_check(config.config_use_ldap) def feed_cc_search(query): return feed_search(query.strip()) @app.route("/opds/search", methods=["GET"]) -@requires_basic_auth_if_no_ano +@basic_auth_required_check(config.config_use_ldap) def feed_normal_search(): return feed_search(request.args.get("query").strip()) @app.route("/opds/new") -@requires_basic_auth_if_no_ano +@basic_auth_required_check(config.config_use_ldap) def feed_new(): off = request.args.get("offset") or 0 entries, __, pagination = fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1), @@ -723,7 +761,7 @@ def feed_new(): @app.route("/opds/discover") -@requires_basic_auth_if_no_ano +@basic_auth_required_check(config.config_use_ldap) def feed_discover(): entries = db.session.query(db.Books).filter(common_filters()).order_by(func.random())\ .limit(config.config_books_per_page) @@ -732,7 +770,7 @@ def feed_discover(): @app.route("/opds/rated") -@requires_basic_auth_if_no_ano +@basic_auth_required_check(config.config_use_ldap) def feed_best_rated(): off = request.args.get("offset") or 0 entries, __, pagination = fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1), @@ -741,7 +779,7 @@ def feed_best_rated(): @app.route("/opds/hot") -@requires_basic_auth_if_no_ano +@basic_auth_required_check(config.config_use_ldap) def feed_hot(): off = request.args.get("offset") or 0 all_books = ub.session.query(ub.Downloads, ub.func.count(ub.Downloads.book_id)).order_by( @@ -766,7 +804,7 @@ def feed_hot(): @app.route("/opds/author") -@requires_basic_auth_if_no_ano +@basic_auth_required_check(config.config_use_ldap) def feed_authorindex(): off = request.args.get("offset") or 0 entries = db.session.query(db.Authors).join(db.books_authors_link).join(db.Books).filter(common_filters())\ @@ -777,7 +815,7 @@ def feed_authorindex(): @app.route("/opds/author/") -@requires_basic_auth_if_no_ano +@basic_auth_required_check(config.config_use_ldap) def feed_author(book_id): off = request.args.get("offset") or 0 entries, __, pagination = fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1), @@ -786,7 +824,7 @@ def feed_author(book_id): @app.route("/opds/publisher") -@requires_basic_auth_if_no_ano +@basic_auth_required_check(config.config_use_ldap) def feed_publisherindex(): off = request.args.get("offset") or 0 entries = db.session.query(db.Publishers).join(db.books_publishers_link).join(db.Books).filter(common_filters())\ @@ -797,7 +835,7 @@ def feed_publisherindex(): @app.route("/opds/publisher/") -@requires_basic_auth_if_no_ano +@basic_auth_required_check(config.config_use_ldap) def feed_publisher(book_id): off = request.args.get("offset") or 0 entries, __, pagination = fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1), @@ -807,7 +845,7 @@ def feed_publisher(book_id): @app.route("/opds/category") -@requires_basic_auth_if_no_ano +@basic_auth_required_check(config.config_use_ldap) def feed_categoryindex(): off = request.args.get("offset") or 0 entries = db.session.query(db.Tags).join(db.books_tags_link).join(db.Books).filter(common_filters())\ @@ -818,7 +856,7 @@ def feed_categoryindex(): @app.route("/opds/category/") -@requires_basic_auth_if_no_ano +@basic_auth_required_check(config.config_use_ldap) def feed_category(book_id): off = request.args.get("offset") or 0 entries, __, pagination = fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1), @@ -827,7 +865,7 @@ def feed_category(book_id): @app.route("/opds/series") -@requires_basic_auth_if_no_ano +@basic_auth_required_check(config.config_use_ldap) def feed_seriesindex(): off = request.args.get("offset") or 0 entries = db.session.query(db.Series).join(db.books_series_link).join(db.Books).filter(common_filters())\ @@ -838,7 +876,7 @@ def feed_seriesindex(): @app.route("/opds/series/") -@requires_basic_auth_if_no_ano +@basic_auth_required_check(config.config_use_ldap) def feed_series(book_id): off = request.args.get("offset") or 0 entries, __, pagination = fill_indexpage((int(off) / (int(config.config_books_per_page)) + 1), @@ -848,7 +886,7 @@ def feed_series(book_id): @app.route("/opds/shelfindex/", defaults={'public': 0}) @app.route("/opds/shelfindex/") -@requires_basic_auth_if_no_ano +@basic_auth_required_check(config.config_use_ldap) def feed_shelfindex(public): off = request.args.get("offset") or 0 if public is not 0: @@ -863,7 +901,7 @@ def feed_shelfindex(public): @app.route("/opds/shelf/") -@requires_basic_auth_if_no_ano +@basic_auth_required_check(config.config_use_ldap) def feed_shelf(book_id): off = request.args.get("offset") or 0 if current_user.is_anonymous: @@ -887,7 +925,7 @@ def feed_shelf(book_id): @app.route("/opds/download///") -@requires_basic_auth_if_no_ano +@basic_auth_required_check(config.config_use_ldap) @download_required def get_opds_download_link(book_id, book_format): book_format = book_format.split(".")[0] @@ -911,7 +949,7 @@ def get_opds_download_link(book_id, book_format): @app.route("/ajax/book/") -@requires_basic_auth_if_no_ano +@basic_auth_required_check(config.config_use_ldap) def get_metadata_calibre_companion(uuid): entry = db.session.query(db.Books).filter(db.Books.uuid.like("%" + uuid + "%")).first() if entry is not None: @@ -2157,7 +2195,7 @@ def serve_book(book_id, book_format): @app.route("/opds/cover_240_240/") @app.route("/opds/cover_90_90/") @app.route("/opds/cover/") -@requires_basic_auth_if_no_ano +@basic_auth_required_check(config.config_use_ldap) def feed_get_cover(book_id): book = db.session.query(db.Books).filter(db.Books.id == book_id).first() return helper.get_book_cover(book.path) @@ -2360,20 +2398,22 @@ def login(): return redirect(url_for('basic_configuration')) if current_user is not None and current_user.is_authenticated: return redirect(url_for('index')) + if config.config_use_ldap and not ldap_support: + flash(_(u"Cannot activate LDAP authentication"), category="error") if request.method == "POST": form = request.form.to_dict() user = ub.session.query(ub.User).filter(func.lower(ub.User.nickname) == form['username'].strip().lower()).first() - if config.config_use_ldap and user: - import ldap + if ldap_support and config.config_use_ldap and 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("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") + if ldap.bind_user(form['username'], form['password']) is not None: + 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("index")) + except LDAPException as exception: + app.logger.error( 'Login Error: ' + str(exception)) + ipAdress = request.headers.get('X-Forwarded-For', request.remote_addr) + app.logger.info('LDAP Login failed for user "' + form['username'] + ', IP-address :' + ipAdress) + flash(_(u"Wrong Username or Password"), category="error") elif user and check_password_hash(user.password, form['password']) and user.nickname is not "Guest": login_user(user, remember=True) flash(_(u"you are now logged in as: '%(nickname)s'", nickname=user.nickname), category="success") @@ -3099,7 +3139,7 @@ def configuration_helper(origin): if "config_ebookconverter" in to_save: content.config_ebookconverter = int(to_save["config_ebookconverter"]) - #LDAP configuratop, + #LDAP configuration, if "config_use_ldap" in to_save and to_save["config_use_ldap"] == "on": if not "config_ldap_provider_url" in to_save or not "config_ldap_dn" in to_save: ub.session.commit() @@ -3108,11 +3148,43 @@ def configuration_helper(origin): gdrive=gdriveutils.gdrive_support, gdriveError=gdriveError, goodreads=goodreads_support, title=_(u"Basic Configuration"), page="config") + elif not "config_ldap_serv_username" in to_save or not "config_ldap_serv_password" in to_save: + ub.session.commit() + flash(_(u'Please enter a LDAP service account and password'), category="error") + return render_title_template("config_edit.html", content=config, origin=origin, + gdrive=gdriveutils.gdrive_support, gdriveError=gdriveError, + goodreads=goodreads_support, title=_(u"Basic Configuration"), + page="config") else: content.config_use_ldap = 1 content.config_ldap_provider_url = to_save["config_ldap_provider_url"] + content.config_ldap_port = to_save["config_ldap_port"] + content.config_ldap_schema = to_save["config_ldap_schema"] + content.config_ldap_serv_username = to_save["config_ldap_serv_username"] + content.config_ldap_serv_password = to_save["config_ldap_serv_password"] + if content.config_ldap_use_ssl in to_save and to_save["config_ldap_use_ssl"] == "on": + content.config_ldap_use_ssl = 1 + if content.config_ldap_use_tls in to_save and to_save["config_ldap_use_tls"] == "on": + content.config_ldap_use_tls = 1 + if content.config_ldap_require_cert in to_save and to_save["config_ldap_require_cert"] == "on": + content.config_ldap_require_cert = 1 + if "config_ldap_cert_path " in to_save: + if content.config_ldap_cert_path != to_save["config_ldap_cert_path "]: + if os.path.isfile(to_save["config_ldap_cert_path "]) or to_save["config_ldap_cert_path "] is u"": + content.config_certfile = to_save["config_ldap_cert_path "] + else: + ub.session.commit() + flash(_(u'Certfile location is not valid, please enter correct path'), category="error") + return render_title_template("config_edit.html", content=config, origin=origin, + gdrive=gdriveutils.gdrive_support, gdriveError=gdriveError, + goodreads=goodreads_support, title=_(u"Basic Configuration"), + page="config") content.config_ldap_dn = to_save["config_ldap_dn"] + content.config_ldap_user_object = to_save["config_ldap_user_object"] + if content.config_ldap_openldap in to_save and to_save["config_ldap_openldap"] == "on": + content.config_ldap_openldap = 1 db_change = True + reboot_required = True # Remote login configuration content.config_remote_login = ("config_remote_login" in to_save and to_save["config_remote_login"] == "on") diff --git a/optional-requirements-ldap.txt b/optional-requirements-ldap.txt index 98519145..a6740501 100644 --- a/optional-requirements-ldap.txt +++ b/optional-requirements-ldap.txt @@ -1 +1,2 @@ -python_ldap>=3.0.0 \ No newline at end of file +python_ldap>=3.0.0 +flask-simpleldap \ No newline at end of file From 97d12b94f687d78923bf068369b13d6d5b182b99 Mon Sep 17 00:00:00 2001 From: Krakinou Date: Tue, 4 Jun 2019 00:47:49 +0200 Subject: [PATCH 3/5] Correct settings update --- cps/templates/config_edit.html | 36 +++++++++++------------ cps/ub.py | 50 +++++++++++++++++++++++++++++++ cps/web.py | 54 ++++++++++++++++++---------------- 3 files changed, 97 insertions(+), 43 deletions(-) diff --git a/cps/templates/config_edit.html b/cps/templates/config_edit.html index fe2f41e6..e63b8566 100644 --- a/cps/templates/config_edit.html +++ b/cps/templates/config_edit.html @@ -164,58 +164,58 @@ {% endif %}
- +
- +
- +
- +
- +
- +
- - + +
- - + +
- - + +
- - + +
- +
- +
- - + +
diff --git a/cps/ub.py b/cps/ub.py index f3aab574..e8f9947d 100644 --- a/cps/ub.py +++ b/cps/ub.py @@ -692,17 +692,67 @@ def migrate_Database(): except exc.OperationalError: conn = engine.connect() conn.execute("ALTER TABLE Settings ADD column `config_use_ldap` INTEGER DEFAULT 0") + session.commit() + try: + session.query(exists().where(Settings.config_ldap_provider_url)).scalar() + except exc.OperationalError: + conn = engine.connect() conn.execute("ALTER TABLE Settings ADD column `config_ldap_provider_url` String DEFAULT ''") + session.commit() + try: + session.query(exists().where(Settings.config_ldap_port)).scalar() + except exc.OperationalError: + conn = engine.connect() conn.execute("ALTER TABLE Settings ADD column `config_ldap_port` INTEGER DEFAULT ''") + session.commit() + try: + session.query(exists().where(Settings.config_ldap_schema)).scalar() + except exc.OperationalError: + conn = engine.connect() conn.execute("ALTER TABLE Settings ADD column `config_ldap_schema ` String DEFAULT ''") + session.commit() + try: + session.query(exists().where(Settings.config_ldap_serv_username)).scalar() + except exc.OperationalError: + conn = engine.connect() conn.execute("ALTER TABLE Settings ADD column `config_ldap_serv_username` String DEFAULT ''") conn.execute("ALTER TABLE Settings ADD column `config_ldap_serv_password` String DEFAULT ''") + session.commit() + try: + session.query(exists().where(Settings.config_ldap_use_ssl)).scalar() + except exc.OperationalError: + conn = engine.connect() conn.execute("ALTER TABLE Settings ADD column `config_ldap_use_ssl` INTEGER DEFAULT 0") + session.commit() + try: + session.query(exists().where(Settings.config_ldap_use_tls)).scalar() + except exc.OperationalError: + conn = engine.connect() conn.execute("ALTER TABLE Settings ADD column `cconfig_ldap_use_tls` INTEGER DEFAULT 0") + session.commit() + try: + session.query(exists().where(Settings.config_ldap_require_cert)).scalar() + except exc.OperationalError: + conn = engine.connect() conn.execute("ALTER TABLE Settings ADD column `config_ldap_require_cert` INTEGER DEFAULT 0") conn.execute("ALTER TABLE Settings ADD column `config_ldap_cert_path` String DEFAULT ''") + session.commit() + try: + session.query(exists().where(Settings.config_ldap_dn)).scalar() + except exc.OperationalError: + conn = engine.connect() conn.execute("ALTER TABLE Settings ADD column `config_ldap_dn` String DEFAULT ''") + session.commit() + try: + session.query(exists().where(Settings.config_ldap_user_object)).scalar() + except exc.OperationalError: + conn = engine.connect() conn.execute("ALTER TABLE Settings ADD column `config_ldap_user_object` String DEFAULT ''") + session.commit() + try: + session.query(exists().where(Settings.config_ldap_openldap)).scalar() + except exc.OperationalError: + conn = engine.connect() conn.execute("ALTER TABLE Settings ADD column `config_ldap_openldap` INTEGER DEFAULT 0") session.commit() try: diff --git a/cps/web.py b/cps/web.py index 59ba9540..9bed45e8 100644 --- a/cps/web.py +++ b/cps/web.py @@ -183,7 +183,7 @@ app.secret_key = os.getenv('SECRET_KEY', 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT') db.setup_db() if ldap_support and config.config_use_ldap: - app.confgi['LDAP_HOST'] = config.config_ldap_provider_url + app.config['LDAP_HOST'] = config.config_ldap_provider_url app.config['LDAP_PORT'] = config.config_ldap_port app.config['LDAP_SCHEMA'] = config.config_ldap_schema app.config['LDAP_USERNAME'] = config.config_ldap_serv_username @@ -197,7 +197,7 @@ if ldap_support and config.config_use_ldap: app.config['LDAP_CERT_PATH'] = config.config_ldap_cert_path app.config['LDAP_BASE_DN'] = config.config_ldap_dn app.config['LDAP_USER_OBJECT_FILTER'] = config.config_ldap_user_object - if config.config_openldap: + if config.config_ldap_openldap: app.config['LDAP_OPENLDAP'] = True # app.config['LDAP_BASE_DN'] = 'ou=users,dc=yunohost,dc=org' @@ -3140,15 +3140,16 @@ def configuration_helper(origin): content.config_ebookconverter = int(to_save["config_ebookconverter"]) #LDAP configuration, + content.config_use_ldap = 0 if "config_use_ldap" in to_save and to_save["config_use_ldap"] == "on": - if not "config_ldap_provider_url" in to_save or not "config_ldap_dn" in to_save: + if not to_save["config_ldap_provider_url"] or not to_save["config_ldap_port"] or not to_save["config_ldap_dn"] or not to_save["config_ldap_user_object"]: ub.session.commit() - flash(_(u'Please enter a LDAP provider and a DN'), category="error") + flash(_(u'Please enter a LDAP provider, port, DN and user object identifier'), category="error") return render_title_template("config_edit.html", content=config, origin=origin, gdrive=gdriveutils.gdrive_support, gdriveError=gdriveError, goodreads=goodreads_support, title=_(u"Basic Configuration"), page="config") - elif not "config_ldap_serv_username" in to_save or not "config_ldap_serv_password" in to_save: + elif not to_save["config_ldap_serv_username"] or not to_save["config_ldap_serv_password"]: ub.session.commit() flash(_(u'Please enter a LDAP service account and password'), category="error") return render_title_template("config_edit.html", content=config, origin=origin, @@ -3162,29 +3163,32 @@ def configuration_helper(origin): content.config_ldap_schema = to_save["config_ldap_schema"] content.config_ldap_serv_username = to_save["config_ldap_serv_username"] content.config_ldap_serv_password = to_save["config_ldap_serv_password"] - if content.config_ldap_use_ssl in to_save and to_save["config_ldap_use_ssl"] == "on": - content.config_ldap_use_ssl = 1 - if content.config_ldap_use_tls in to_save and to_save["config_ldap_use_tls"] == "on": - content.config_ldap_use_tls = 1 - if content.config_ldap_require_cert in to_save and to_save["config_ldap_require_cert"] == "on": - content.config_ldap_require_cert = 1 - if "config_ldap_cert_path " in to_save: - if content.config_ldap_cert_path != to_save["config_ldap_cert_path "]: - if os.path.isfile(to_save["config_ldap_cert_path "]) or to_save["config_ldap_cert_path "] is u"": - content.config_certfile = to_save["config_ldap_cert_path "] - else: - ub.session.commit() - flash(_(u'Certfile location is not valid, please enter correct path'), category="error") - return render_title_template("config_edit.html", content=config, origin=origin, - gdrive=gdriveutils.gdrive_support, gdriveError=gdriveError, - goodreads=goodreads_support, title=_(u"Basic Configuration"), - page="config") content.config_ldap_dn = to_save["config_ldap_dn"] content.config_ldap_user_object = to_save["config_ldap_user_object"] - if content.config_ldap_openldap in to_save and to_save["config_ldap_openldap"] == "on": - content.config_ldap_openldap = 1 - db_change = True reboot_required = True + content.config_ldap_use_ssl = 0 + content.config_ldap_use_tls = 0 + content.config_ldap_require_cert = 0 + content.config_ldap_openldap = 0 + if "config_ldap_use_ssl" in to_save and to_save["config_ldap_use_ssl"] == "on": + content.config_ldap_use_ssl = 1 + if "config_ldap_use_tls" in to_save and to_save["config_ldap_use_tls"] == "on": + content.config_ldap_use_tls = 1 + if "config_ldap_require_cert" in to_save and to_save["config_ldap_require_cert"] == "on": + content.config_ldap_require_cert = 1 + if "config_ldap_openldap" in to_save and to_save["config_ldap_openldap"] == "on": + content.config_ldap_openldap = 1 + if "config_ldap_cert_path " in to_save: + if content.config_ldap_cert_path != to_save["config_ldap_cert_path "]: + if os.path.isfile(to_save["config_ldap_cert_path "]) or to_save["config_ldap_cert_path "] is u"": + content.config_certfile = to_save["config_ldap_cert_path "] + else: + ub.session.commit() + flash(_(u'Certfile location is not valid, please enter correct path'), category="error") + return render_title_template("config_edit.html", content=config, origin=origin, + gdrive=gdriveutils.gdrive_support, gdriveError=gdriveError, + goodreads=goodreads_support, title=_(u"Basic Configuration"), + page="config") # Remote login configuration content.config_remote_login = ("config_remote_login" in to_save and to_save["config_remote_login"] == "on") From 79286c93842134ff6b0a31fa7d734a534b842b86 Mon Sep 17 00:00:00 2001 From: Krakinou Date: Sat, 8 Jun 2019 00:54:45 +0200 Subject: [PATCH 4/5] encode password --- cps/web.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cps/web.py b/cps/web.py index 9bed45e8..5c31df5f 100644 --- a/cps/web.py +++ b/cps/web.py @@ -186,8 +186,8 @@ if ldap_support and config.config_use_ldap: app.config['LDAP_HOST'] = config.config_ldap_provider_url app.config['LDAP_PORT'] = config.config_ldap_port app.config['LDAP_SCHEMA'] = config.config_ldap_schema - app.config['LDAP_USERNAME'] = config.config_ldap_serv_username - app.config['LDAP_PASSWORD'] = config.config_ldap_serv_password + app.config['LDAP_USERNAME'] = config.config_ldap_user_object.replace('%s', config.config_ldap_serv_username) + ',' + config.config_ldap_dn + app.config['LDAP_PASSWORD'] = base64.b64decode(config.config_ldap_serv_password) if config.config_ldap_use_ssl: app.config['LDAP_USE_SSL'] = True if config.config_ldap_use_tls: @@ -3162,7 +3162,7 @@ def configuration_helper(origin): content.config_ldap_port = to_save["config_ldap_port"] content.config_ldap_schema = to_save["config_ldap_schema"] content.config_ldap_serv_username = to_save["config_ldap_serv_username"] - content.config_ldap_serv_password = to_save["config_ldap_serv_password"] + content.config_ldap_serv_password = base64.b64encode(to_save["config_ldap_serv_password"]) content.config_ldap_dn = to_save["config_ldap_dn"] content.config_ldap_user_object = to_save["config_ldap_user_object"] reboot_required = True From 304db0d20ea465d98ce1e12cfe81c4e7a616be31 Mon Sep 17 00:00:00 2001 From: Krakinou Date: Fri, 14 Jun 2019 22:55:17 +0200 Subject: [PATCH 5/5] Solve typo --- cps/ub.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cps/ub.py b/cps/ub.py index e8f9947d..f0091f2f 100644 --- a/cps/ub.py +++ b/cps/ub.py @@ -403,7 +403,7 @@ class Config: self.config_ldap_require_cert = data.config_ldap_require_cert self.config_ldap_cert_path = data.config_ldap_cert_path self.config_ldap_dn = data.config_ldap_dn - self.config_ldap_user_object = data.config_ldap_user_object + self.config_ldap_user_object = data.config_ldap_user_object self.config_ldap_openldap = data.config_ldap_openldap if data.config_mature_content_tags: self.config_mature_content_tags = data.config_mature_content_tags @@ -709,7 +709,7 @@ def migrate_Database(): session.query(exists().where(Settings.config_ldap_schema)).scalar() except exc.OperationalError: conn = engine.connect() - conn.execute("ALTER TABLE Settings ADD column `config_ldap_schema ` String DEFAULT ''") + conn.execute("ALTER TABLE Settings ADD column `config_ldap_schema` String DEFAULT ''") session.commit() try: session.query(exists().where(Settings.config_ldap_serv_username)).scalar() @@ -728,7 +728,7 @@ def migrate_Database(): session.query(exists().where(Settings.config_ldap_use_tls)).scalar() except exc.OperationalError: conn = engine.connect() - conn.execute("ALTER TABLE Settings ADD column `cconfig_ldap_use_tls` INTEGER DEFAULT 0") + conn.execute("ALTER TABLE Settings ADD column `config_ldap_use_tls` INTEGER DEFAULT 0") session.commit() try: session.query(exists().where(Settings.config_ldap_require_cert)).scalar()