2019-07-13 18:45:48 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
# This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web)
|
|
|
|
# Copyright (C) 2018-2019 OzzieIsaacs, pwr
|
|
|
|
#
|
|
|
|
# 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/>.
|
|
|
|
|
|
|
|
from __future__ import division, print_function, unicode_literals
|
|
|
|
import base64
|
|
|
|
|
|
|
|
from flask_simpleldap import LDAP, LDAPException
|
2020-11-20 18:47:50 +00:00
|
|
|
from flask_simpleldap import ldap as pyLDAP
|
2019-07-13 18:45:48 +00:00
|
|
|
from .. import constants, logger
|
|
|
|
|
2020-04-13 20:23:58 +00:00
|
|
|
try:
|
|
|
|
from ldap.pkginfo import __version__ as ldapVersion
|
|
|
|
except ImportError:
|
|
|
|
pass
|
2019-07-13 18:45:48 +00:00
|
|
|
|
|
|
|
log = logger.create()
|
|
|
|
_ldap = LDAP()
|
|
|
|
|
|
|
|
|
|
|
|
def init_app(app, config):
|
|
|
|
if config.config_login_type != constants.LOGIN_LDAP:
|
|
|
|
return
|
|
|
|
|
|
|
|
app.config['LDAP_HOST'] = config.config_ldap_provider_url
|
|
|
|
app.config['LDAP_PORT'] = config.config_ldap_port
|
2020-11-22 10:19:14 +00:00
|
|
|
app.config['LDAP_CUSTOM_OPTIONS'] = {pyLDAP.OPT_REFERRALS: 0}
|
2020-04-13 20:23:58 +00:00
|
|
|
if config.config_ldap_encryption == 2:
|
2020-04-05 15:31:41 +00:00
|
|
|
app.config['LDAP_SCHEMA'] = 'ldaps'
|
|
|
|
else:
|
|
|
|
app.config['LDAP_SCHEMA'] = 'ldap'
|
2020-04-17 16:16:21 +00:00
|
|
|
if config.config_ldap_authentication > constants.LDAP_AUTH_ANONYMOUS:
|
|
|
|
if config.config_ldap_authentication > constants.LDAP_AUTH_UNAUTHENTICATE:
|
|
|
|
if config.config_ldap_serv_password is None:
|
|
|
|
config.config_ldap_serv_password = ''
|
|
|
|
app.config['LDAP_PASSWORD'] = base64.b64decode(config.config_ldap_serv_password)
|
|
|
|
else:
|
2020-04-18 09:47:44 +00:00
|
|
|
app.config['LDAP_PASSWORD'] = base64.b64decode("")
|
2020-04-17 16:16:21 +00:00
|
|
|
app.config['LDAP_USERNAME'] = config.config_ldap_serv_username
|
|
|
|
else:
|
2020-04-18 09:47:44 +00:00
|
|
|
app.config['LDAP_USERNAME'] = ""
|
|
|
|
app.config['LDAP_PASSWORD'] = base64.b64decode("")
|
2020-04-13 20:23:58 +00:00
|
|
|
if bool(config.config_ldap_cert_path):
|
2020-11-22 07:17:00 +00:00
|
|
|
app.config['LDAP_CUSTOM_OPTIONS'].update({
|
2020-11-20 18:47:50 +00:00
|
|
|
pyLDAP.OPT_X_TLS_REQUIRE_CERT: pyLDAP.OPT_X_TLS_DEMAND,
|
|
|
|
pyLDAP.OPT_X_TLS_CACERTFILE: config.config_ldap_cacert_path,
|
|
|
|
pyLDAP.OPT_X_TLS_CERTFILE: config.config_ldap_cert_path,
|
|
|
|
pyLDAP.OPT_X_TLS_KEYFILE: config.config_ldap_key_path,
|
|
|
|
pyLDAP.OPT_X_TLS_NEWCTX: 0
|
2020-11-22 07:17:00 +00:00
|
|
|
})
|
2020-11-20 18:47:50 +00:00
|
|
|
|
2019-07-13 18:45:48 +00:00
|
|
|
app.config['LDAP_BASE_DN'] = config.config_ldap_dn
|
|
|
|
app.config['LDAP_USER_OBJECT_FILTER'] = config.config_ldap_user_object
|
2020-04-05 15:31:41 +00:00
|
|
|
|
|
|
|
app.config['LDAP_USE_TLS'] = bool(config.config_ldap_encryption == 1)
|
|
|
|
app.config['LDAP_USE_SSL'] = bool(config.config_ldap_encryption == 2)
|
2019-07-13 18:45:48 +00:00
|
|
|
app.config['LDAP_OPENLDAP'] = bool(config.config_ldap_openldap)
|
2019-12-28 06:12:18 +00:00
|
|
|
app.config['LDAP_GROUP_OBJECT_FILTER'] = config.config_ldap_group_object_filter
|
|
|
|
app.config['LDAP_GROUP_MEMBERS_FIELD'] = config.config_ldap_group_members_field
|
2019-07-13 18:45:48 +00:00
|
|
|
|
2020-07-23 17:23:57 +00:00
|
|
|
try:
|
|
|
|
_ldap.init_app(app)
|
2020-11-20 18:47:50 +00:00
|
|
|
except ValueError:
|
|
|
|
if bool(config.config_ldap_cert_path):
|
2020-11-22 07:17:00 +00:00
|
|
|
app.config['LDAP_CUSTOM_OPTIONS'].pop(pyLDAP.OPT_X_TLS_NEWCTX)
|
2020-11-20 18:47:50 +00:00
|
|
|
try:
|
|
|
|
_ldap.init_app(app)
|
|
|
|
except RuntimeError as e:
|
|
|
|
log.error(e)
|
2020-07-23 17:23:57 +00:00
|
|
|
except RuntimeError as e:
|
|
|
|
log.error(e)
|
2019-07-13 18:45:48 +00:00
|
|
|
|
|
|
|
|
2019-12-28 06:12:18 +00:00
|
|
|
def get_object_details(user=None, group=None, query_filter=None, dn_only=False):
|
|
|
|
return _ldap.get_object_details(user, group, query_filter, dn_only)
|
|
|
|
|
|
|
|
|
|
|
|
def bind():
|
|
|
|
return _ldap.bind()
|
|
|
|
|
|
|
|
|
|
|
|
def get_group_members(group):
|
|
|
|
return _ldap.get_group_members(group)
|
|
|
|
|
2019-07-13 18:45:48 +00:00
|
|
|
|
|
|
|
def basic_auth_required(func):
|
|
|
|
return _ldap.basic_auth_required(func)
|
|
|
|
|
|
|
|
|
|
|
|
def bind_user(username, password):
|
|
|
|
'''Attempts a LDAP login.
|
|
|
|
|
|
|
|
:returns: True if login succeeded, False if login failed, None if server unavailable.
|
|
|
|
'''
|
|
|
|
try:
|
2020-04-13 20:23:58 +00:00
|
|
|
if _ldap.get_object_details(username):
|
|
|
|
result = _ldap.bind_user(username, password)
|
|
|
|
log.debug("LDAP login '%s': %r", username, result)
|
|
|
|
return result is not None, None
|
|
|
|
return None, None # User not found
|
2020-04-18 09:47:44 +00:00
|
|
|
except (TypeError, AttributeError, KeyError) as ex:
|
2020-04-13 20:23:58 +00:00
|
|
|
error = ("LDAP bind_user: %s" % ex)
|
|
|
|
return None, error
|
2019-07-13 18:45:48 +00:00
|
|
|
except LDAPException as ex:
|
|
|
|
if ex.message == 'Invalid credentials':
|
2020-12-03 13:22:37 +00:00
|
|
|
error = "LDAP admin login failed"
|
2020-04-13 20:23:58 +00:00
|
|
|
return None, error
|
2019-07-13 18:45:48 +00:00
|
|
|
if ex.message == "Can't contact LDAP server":
|
2020-04-13 20:23:58 +00:00
|
|
|
# log.warning('LDAP Server down: %s', ex)
|
|
|
|
error = ('LDAP Server down: %s' % ex)
|
|
|
|
return None, error
|
2019-07-13 18:45:48 +00:00
|
|
|
else:
|
2020-04-13 20:23:58 +00:00
|
|
|
error = ('LDAP Server error: %s' % ex.message)
|
|
|
|
return None, error
|