diff --git a/cps/admin.py b/cps/admin.py index 82fc196e..7fb096c4 100644 --- a/cps/admin.py +++ b/cps/admin.py @@ -1541,7 +1541,6 @@ def get_updater_status(): def ldap_import_create_user(user, user_data): user_login_field = extract_dynamic_field_from_filter(user, config.config_ldap_user_object) - try: username = user_data[user_login_field][0].decode('utf-8') except KeyError as ex: @@ -1555,6 +1554,15 @@ def ldap_import_create_user(user, user_data): log.warning("LDAP User %s Already in Database", user_data) return 0, None + user, error = ldap_create_user(username, user_data, config.config_default_role) + if user: + return 1, error + else: + return 0, error + + +def ldap_create_user(username, user_data, role): + ereader_mail = '' if 'mail' in user_data: useremail = user_data['mail'][0].decode('utf-8') @@ -1569,8 +1577,8 @@ def ldap_import_create_user(user, user_data): # check for duplicate email useremail = check_email(useremail) except Exception as ex: - log.warning("LDAP Email Error: {}, {}".format(user_data, ex)) - return 0, None + log.warning("LDAP Email Error: {}, {}".format(username, ex)) + return None, None content = ub.User() content.name = username content.password = '' # dummy password which will be replaced by ldap one @@ -1578,7 +1586,7 @@ def ldap_import_create_user(user, user_data): content.kindle_mail = ereader_mail content.default_language = config.config_default_language content.locale = config.config_default_locale - content.role = config.config_default_role + content.role = role content.sidebar_view = config.config_default_show content.allowed_tags = config.config_allowed_tags content.denied_tags = config.config_denied_tags @@ -1587,12 +1595,12 @@ def ldap_import_create_user(user, user_data): ub.session.add(content) try: ub.session.commit() - return 1, None # increase no of users + return content, None except Exception as ex: - log.warning("Failed to create LDAP user: %s - %s", user, ex) + log.warning("Failed to create LDAP user: %s - %s", username, ex) ub.session.rollback() message = _(u'Failed to Create at Least One LDAP User') - return 0, message + return None, message @admi.route('/import_ldap_users', methods=["POST"]) diff --git a/cps/constants.py b/cps/constants.py index 069630b6..0dca8ae9 100644 --- a/cps/constants.py +++ b/cps/constants.py @@ -128,7 +128,7 @@ LOGIN_OAUTH = 2 LDAP_AUTH_ANONYMOUS = 0 LDAP_AUTH_UNAUTHENTICATE = 1 -LDAP_AUTH_SIMPLE = 0 +LDAP_AUTH_SIMPLE = 2 DEFAULT_MAIL_SERVER = "mail.example.org" diff --git a/cps/services/simpleldap.py b/cps/services/simpleldap.py index dc915ceb..9e15b41c 100644 --- a/cps/services/simpleldap.py +++ b/cps/services/simpleldap.py @@ -124,8 +124,8 @@ def init_app(app, config): log.error(e) -def get_object_details(user=None,query_filter=None): - return _ldap.get_object_details(user, query_filter=query_filter) +def get_object_details(user=None, query_filter=None, group=None): + return _ldap.get_object_details(user=user, query_filter=query_filter, group=group) def bind(): diff --git a/cps/web.py b/cps/web.py index 789edd3d..70e22fd6 100755 --- a/cps/web.py +++ b/cps/web.py @@ -43,6 +43,7 @@ from werkzeug.security import generate_password_hash, check_password_hash from . import constants, logger, isoLanguages, services from . import db, ub, config, app from . import calibre_db, kobo_sync_status +from .admin import ldap_create_user from .search import render_search_results, render_adv_search_results from .gdriveutils import getFileFromEbooksFolder, do_gdrive_download from .helper import check_valid_domain, check_email, check_username, \ @@ -1352,14 +1353,20 @@ def login_post(): user = ub.session.query(ub.User).filter(func.lower(ub.User.name) == form.get('username', "").strip().lower()) \ .first() remember_me = bool(form.get('remember_me')) - if config.config_login_type == constants.LOGIN_LDAP and services.ldap and user and form['password'] != "": + if config.config_login_type == constants.LOGIN_LDAP and services.ldap and (user or os.environ.get("CALIBRE_LDAP_AUTO_CREATE", None)) and form['password'] != "": login_result, error = services.ldap.bind_user(form['username'], form['password']) if login_result: - log.debug(u"You are now logged in as: '{}'".format(user.name)) - return handle_login_user(user, - remember_me, - _(u"you are now logged in as: '%(nickname)s'", nickname=user.name), - "success") + log.debug(u"You are now logged in as: '{}'".format(form['username'])) + if not user: + user, error = create_user(form['username']) + if not user: + log.info(error) + flash(_(u"Could not create user from ldap login: %(message)s", message=error), category="error") + else: + return handle_login_user(user, + remember_me, + _(u"you are now logged in as: '%(nickname)s'", nickname=user.name), + "success") elif login_result is None and user and check_password_hash(str(user.password), form['password']) \ and user.name != "Guest": log.info("Local Fallback Login as: '{}'".format(user.name)) @@ -1403,6 +1410,34 @@ def login_post(): return render_login(form.get("username", ""), form.get("password", "")) +def create_user(username): + try: + user_data = services.ldap.get_object_details(user=username) + except Exception as e: + log.error('LDAP user details failed: %s', e) + message = _(u'Failed to get LDAP User details') + return None, message + + admin_group_filter = os.environ.get("CALIBRE_LDAP_ADMIN_GROUP_FILTER", None) + role = constants.ROLE_USER + if admin_group_filter: + try: + log.debug(u"LDAP admin group filter: '{}'".format(admin_group_filter)) + group_data = services.ldap.get_object_details(user=username, query_filter=admin_group_filter) + if group_data: + log.debug(u"LDAP admin group is found: '{}'".format(group_data)) + role = constants.ROLE_ADMIN | constants.ROLE_DELETE_BOOKS | constants.ROLE_DOWNLOAD | constants.ROLE_UPLOAD | constants.ROLE_EDIT | constants.ROLE_EDIT_SHELFS | constants.ROLE_VIEWER + else: + log.debug(u"LDAP admin group is not found") + + except Exception as e: + log.error('LDAP admin group lookup failed: %s', e) + message = _(u'Failed to get LDAP admin group details') + return None, message + user, error = ldap_create_user(username, user_data, role) + return user, error + + @web.route('/logout') @login_required def logout():