forked from Github-Mirrors/canaille
Moved LDAP configuration entry to BACKENDS.LDAP
This commit is contained in:
parent
cc45ed4be9
commit
e2b96af1ee
17 changed files with 97 additions and 71 deletions
|
@ -11,11 +11,12 @@ Changed
|
|||
|
||||
- Renamed user model attributes to match SCIM naming convention. :pr:`123`
|
||||
- Moved OIDC related configuration entries in ``OIDC``
|
||||
- Moved ``LDAP`` configuration entry to ``BACKENDS.LDAP``
|
||||
|
||||
Fixed
|
||||
*****
|
||||
|
||||
- ``OIDC.JWT.MAPPING`` is really optional now.
|
||||
- ``OIDC.JWT.MAPPING`` configuration entry is really optional now.
|
||||
|
||||
[0.0.24] - 2023-04-07
|
||||
=====================
|
||||
|
|
|
@ -25,7 +25,9 @@ def profile_hash(*args):
|
|||
|
||||
|
||||
def login_placeholder():
|
||||
user_filter = current_app.config["LDAP"].get("USER_FILTER", User.DEFAULT_FILTER)
|
||||
user_filter = current_app.config["BACKENDS"]["LDAP"].get(
|
||||
"USER_FILTER", User.DEFAULT_FILTER
|
||||
)
|
||||
placeholders = []
|
||||
|
||||
if "cn={login}" in user_filter:
|
||||
|
|
|
@ -55,7 +55,7 @@ SECRET_KEY = "change me before you go in production"
|
|||
# written in the standard error output.
|
||||
# PATH = ""
|
||||
|
||||
[LDAP]
|
||||
[BACKENDS.LDAP]
|
||||
URI = "ldap://ldap"
|
||||
ROOT_DN = "dc=mydomain,dc=tld"
|
||||
BIND_DN = "cn=admin,dc=mydomain,dc=tld"
|
||||
|
|
|
@ -45,7 +45,7 @@ class User(LDAPObject):
|
|||
def get_from_login(cls, login=None, **kwargs):
|
||||
filter = (
|
||||
(
|
||||
current_app.config["LDAP"]
|
||||
current_app.config["BACKENDS"]["LDAP"]
|
||||
.get("USER_FILTER", User.DEFAULT_FILTER)
|
||||
.format(login=ldap.filter.escape_filter_chars(login))
|
||||
)
|
||||
|
@ -65,7 +65,7 @@ class User(LDAPObject):
|
|||
|
||||
def load_groups(self):
|
||||
group_filter = (
|
||||
current_app.config["LDAP"]
|
||||
current_app.config["BACKENDS"]["LDAP"]
|
||||
.get("GROUP_USER_FILTER", Group.DEFAULT_USER_FILTER)
|
||||
.format(user=self)
|
||||
)
|
||||
|
@ -107,10 +107,11 @@ class User(LDAPObject):
|
|||
return bool(self.password)
|
||||
|
||||
def check_password(self, password):
|
||||
conn = ldap.initialize(current_app.config["LDAP"]["URI"])
|
||||
conn = ldap.initialize(current_app.config["BACKENDS"]["LDAP"]["URI"])
|
||||
|
||||
conn.set_option(
|
||||
ldap.OPT_NETWORK_TIMEOUT, current_app.config["LDAP"].get("TIMEOUT")
|
||||
ldap.OPT_NETWORK_TIMEOUT,
|
||||
current_app.config["BACKENDS"]["LDAP"].get("TIMEOUT"),
|
||||
)
|
||||
|
||||
try:
|
||||
|
@ -213,7 +214,7 @@ class Group(LDAPObject):
|
|||
|
||||
@property
|
||||
def display_name(self):
|
||||
attribute = current_app.config["LDAP"].get(
|
||||
attribute = current_app.config["BACKENDS"]["LDAP"].get(
|
||||
"GROUP_NAME_ATTRIBUTE", Group.DEFAULT_NAME_ATTRIBUTE
|
||||
)
|
||||
return self[attribute][0]
|
||||
|
|
|
@ -14,28 +14,34 @@ def setup_ldap_models(config):
|
|||
from canaille.core.models import Group
|
||||
from canaille.core.models import User
|
||||
|
||||
LDAPObject.root_dn = config["LDAP"]["ROOT_DN"]
|
||||
LDAPObject.root_dn = config["BACKENDS"]["LDAP"]["ROOT_DN"]
|
||||
|
||||
user_base = config["LDAP"]["USER_BASE"].replace(f',{config["LDAP"]["ROOT_DN"]}', "")
|
||||
user_base = config["BACKENDS"]["LDAP"]["USER_BASE"].replace(
|
||||
f',{config["BACKENDS"]["LDAP"]["ROOT_DN"]}', ""
|
||||
)
|
||||
User.base = user_base
|
||||
User.rdn_attribute = config["LDAP"].get(
|
||||
User.rdn_attribute = config["BACKENDS"]["LDAP"].get(
|
||||
"USER_ID_ATTRIBUTE", User.DEFAULT_ID_ATTRIBUTE
|
||||
)
|
||||
object_class = config["LDAP"].get("USER_CLASS", User.DEFAULT_OBJECT_CLASS)
|
||||
object_class = config["BACKENDS"]["LDAP"].get(
|
||||
"USER_CLASS", User.DEFAULT_OBJECT_CLASS
|
||||
)
|
||||
User.ldap_object_class = (
|
||||
object_class if isinstance(object_class, list) else [object_class]
|
||||
)
|
||||
|
||||
group_base = (
|
||||
config["LDAP"]
|
||||
config["BACKENDS"]["LDAP"]
|
||||
.get("GROUP_BASE", "")
|
||||
.replace(f',{config["LDAP"]["ROOT_DN"]}', "")
|
||||
.replace(f',{config["BACKENDS"]["LDAP"]["ROOT_DN"]}', "")
|
||||
)
|
||||
Group.base = group_base or None
|
||||
Group.rdn_attribute = config["LDAP"].get(
|
||||
Group.rdn_attribute = config["BACKENDS"]["LDAP"].get(
|
||||
"GROUP_ID_ATTRIBUTE", Group.DEFAULT_ID_ATTRIBUTE
|
||||
)
|
||||
object_class = config["LDAP"].get("GROUP_CLASS", Group.DEFAULT_OBJECT_CLASS)
|
||||
object_class = config["BACKENDS"]["LDAP"].get(
|
||||
"GROUP_CLASS", Group.DEFAULT_OBJECT_CLASS
|
||||
)
|
||||
Group.ldap_object_class = (
|
||||
object_class if isinstance(object_class, list) else [object_class]
|
||||
)
|
||||
|
@ -49,17 +55,18 @@ def setup_backend(app):
|
|||
pass
|
||||
|
||||
try:
|
||||
g.ldap_connection = ldap.initialize(app.config["LDAP"]["URI"])
|
||||
g.ldap_connection = ldap.initialize(app.config["BACKENDS"]["LDAP"]["URI"])
|
||||
g.ldap_connection.set_option(
|
||||
ldap.OPT_NETWORK_TIMEOUT, app.config["LDAP"].get("TIMEOUT")
|
||||
ldap.OPT_NETWORK_TIMEOUT, app.config["BACKENDS"]["LDAP"].get("TIMEOUT")
|
||||
)
|
||||
g.ldap_connection.simple_bind_s(
|
||||
app.config["LDAP"]["BIND_DN"], app.config["LDAP"]["BIND_PW"]
|
||||
app.config["BACKENDS"]["LDAP"]["BIND_DN"],
|
||||
app.config["BACKENDS"]["LDAP"]["BIND_PW"],
|
||||
)
|
||||
|
||||
except ldap.SERVER_DOWN:
|
||||
message = _("Could not connect to the LDAP server '{uri}'").format(
|
||||
uri=app.config["LDAP"]["URI"]
|
||||
uri=app.config["BACKENDS"]["LDAP"]["URI"]
|
||||
)
|
||||
logging.error(message)
|
||||
return (
|
||||
|
@ -75,7 +82,7 @@ def setup_backend(app):
|
|||
|
||||
except ldap.INVALID_CREDENTIALS:
|
||||
message = _("LDAP authentication failed with user '{user}'").format(
|
||||
user=app.config["LDAP"]["BIND_DN"]
|
||||
user=app.config["BACKENDS"]["LDAP"]["BIND_DN"]
|
||||
)
|
||||
logging.error(message)
|
||||
return (
|
||||
|
@ -116,18 +123,22 @@ def validate_configuration(config):
|
|||
from canaille.core.models import User
|
||||
|
||||
try:
|
||||
conn = ldap.initialize(config["LDAP"]["URI"])
|
||||
conn.set_option(ldap.OPT_NETWORK_TIMEOUT, config["LDAP"].get("TIMEOUT"))
|
||||
conn.simple_bind_s(config["LDAP"]["BIND_DN"], config["LDAP"]["BIND_PW"])
|
||||
conn = ldap.initialize(config["BACKENDS"]["LDAP"]["URI"])
|
||||
conn.set_option(
|
||||
ldap.OPT_NETWORK_TIMEOUT, config["BACKENDS"]["LDAP"].get("TIMEOUT")
|
||||
)
|
||||
conn.simple_bind_s(
|
||||
config["BACKENDS"]["LDAP"]["BIND_DN"], config["BACKENDS"]["LDAP"]["BIND_PW"]
|
||||
)
|
||||
|
||||
except ldap.SERVER_DOWN as exc:
|
||||
raise ConfigurationException(
|
||||
f'Could not connect to the LDAP server \'{config["LDAP"]["URI"]}\''
|
||||
f'Could not connect to the LDAP server \'{config["BACKENDS"]["LDAP"]["URI"]}\''
|
||||
) from exc
|
||||
|
||||
except ldap.INVALID_CREDENTIALS as exc:
|
||||
raise ConfigurationException(
|
||||
f'LDAP authentication failed with user \'{config["LDAP"]["BIND_DN"]}\''
|
||||
f'LDAP authentication failed with user \'{config["BACKENDS"]["LDAP"]["BIND_DN"]}\''
|
||||
) from exc
|
||||
|
||||
try:
|
||||
|
@ -144,8 +155,8 @@ def validate_configuration(config):
|
|||
|
||||
except ldap.INSUFFICIENT_ACCESS as exc:
|
||||
raise ConfigurationException(
|
||||
f'LDAP user \'{config["LDAP"]["BIND_DN"]}\' cannot create '
|
||||
f'users at \'{config["LDAP"]["USER_BASE"]}\''
|
||||
f'LDAP user \'{config["BACKENDS"]["LDAP"]["BIND_DN"]}\' cannot create '
|
||||
f'users at \'{config["BACKENDS"]["LDAP"]["USER_BASE"]}\''
|
||||
) from exc
|
||||
|
||||
try:
|
||||
|
@ -169,8 +180,8 @@ def validate_configuration(config):
|
|||
|
||||
except ldap.INSUFFICIENT_ACCESS as exc:
|
||||
raise ConfigurationException(
|
||||
f'LDAP user \'{config["LDAP"]["BIND_DN"]}\' cannot create '
|
||||
f'groups at \'{config["LDAP"]["GROUP_BASE"]}\''
|
||||
f'LDAP user \'{config["BACKENDS"]["LDAP"]["BIND_DN"]}\' cannot create '
|
||||
f'groups at \'{config["BACKENDS"]["LDAP"]["GROUP_BASE"]}\''
|
||||
) from exc
|
||||
|
||||
finally:
|
||||
|
|
|
@ -6,9 +6,11 @@ import ldif
|
|||
|
||||
@contextmanager
|
||||
def ldap_connection(config):
|
||||
conn = ldap.initialize(config["LDAP"]["URI"])
|
||||
conn.set_option(ldap.OPT_NETWORK_TIMEOUT, config["LDAP"].get("TIMEOUT"))
|
||||
conn.simple_bind_s(config["LDAP"]["BIND_DN"], config["LDAP"]["BIND_PW"])
|
||||
conn = ldap.initialize(config["BACKENDS"]["LDAP"]["URI"])
|
||||
conn.set_option(ldap.OPT_NETWORK_TIMEOUT, config["BACKENDS"]["LDAP"].get("TIMEOUT"))
|
||||
conn.simple_bind_s(
|
||||
config["BACKENDS"]["LDAP"]["BIND_DN"], config["BACKENDS"]["LDAP"]["BIND_PW"]
|
||||
)
|
||||
|
||||
try:
|
||||
yield conn
|
||||
|
@ -31,5 +33,5 @@ def install_schema(config, schema_path):
|
|||
|
||||
except ldap.INSUFFICIENT_ACCESS as exc:
|
||||
raise InstallationException(
|
||||
f"The user '{config['LDAP']['BIND_DN']}' has insufficient permissions to install LDAP schemas."
|
||||
f"The user '{config['BACKENDS']['LDAP']['BIND_DN']}' has insufficient permissions to install LDAP schemas."
|
||||
) from exc
|
||||
|
|
|
@ -56,7 +56,7 @@ LEVEL = "DEBUG"
|
|||
# written in the standard error output.
|
||||
# PATH = ""
|
||||
|
||||
[LDAP]
|
||||
[BACKENDS.LDAP]
|
||||
URI = "ldap://ldap:389"
|
||||
ROOT_DN = "dc=mydomain,dc=tld"
|
||||
BIND_DN = "cn=admin,dc=mydomain,dc=tld"
|
||||
|
|
|
@ -56,7 +56,7 @@ LEVEL = "DEBUG"
|
|||
# written in the standard error output.
|
||||
# PATH = ""
|
||||
|
||||
[LDAP]
|
||||
[BACKENDS.LDAP]
|
||||
URI = "ldap://127.0.0.1:5389"
|
||||
ROOT_DN = "dc=mydomain,dc=tld"
|
||||
BIND_DN = "cn=admin,dc=mydomain,dc=tld"
|
||||
|
|
|
@ -60,8 +60,8 @@ LOGGING
|
|||
:PATH:
|
||||
*Optional.* The log file path. If not set, logs are written in the standard error output.
|
||||
|
||||
LDAP
|
||||
----
|
||||
BACKENDS.LDAP
|
||||
-------------
|
||||
|
||||
:URI:
|
||||
**Required.** The URI to the LDAP server.
|
||||
|
|
|
@ -8,7 +8,7 @@ def test_check_command(testclient):
|
|||
|
||||
|
||||
def test_check_command_fail(testclient):
|
||||
testclient.app.config["LDAP"]["URI"] = "ldap://invalid-ldap.com"
|
||||
testclient.app.config["BACKENDS"]["LDAP"]["URI"] = "ldap://invalid-ldap.com"
|
||||
runner = testclient.app.test_cli_runner()
|
||||
res = runner.invoke(cli, ["check"])
|
||||
assert res.exit_code == 1, res.stdout
|
||||
|
|
|
@ -18,7 +18,7 @@ def test_ldap_connection_remote(testclient, configuration, slapd_connection):
|
|||
|
||||
|
||||
def test_ldap_connection_remote_ldap_unreachable(testclient, configuration):
|
||||
configuration["LDAP"]["URI"] = "ldap://invalid-ldap.com"
|
||||
configuration["BACKENDS"]["LDAP"]["URI"] = "ldap://invalid-ldap.com"
|
||||
with pytest.raises(
|
||||
ConfigurationException,
|
||||
match=r"Could not connect to the LDAP server",
|
||||
|
@ -27,7 +27,7 @@ def test_ldap_connection_remote_ldap_unreachable(testclient, configuration):
|
|||
|
||||
|
||||
def test_ldap_connection_remote_ldap_wrong_credentials(testclient, configuration):
|
||||
configuration["LDAP"]["BIND_PW"] = "invalid-password"
|
||||
configuration["BACKENDS"]["LDAP"]["BIND_PW"] = "invalid-password"
|
||||
with pytest.raises(
|
||||
ConfigurationException,
|
||||
match=r"LDAP authentication failed with user",
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
def test_ldap_connection_remote_ldap_unreachable(testclient):
|
||||
testclient.app.config["TESTING"] = False
|
||||
|
||||
testclient.app.config["LDAP"]["URI"] = "ldap://invalid-ldap.com"
|
||||
testclient.app.config["BACKENDS"]["LDAP"]["URI"] = "ldap://invalid-ldap.com"
|
||||
|
||||
testclient.app.config["DEBUG"] = True
|
||||
res = testclient.get("/", status=500, expect_errors=True)
|
||||
|
@ -15,7 +15,7 @@ def test_ldap_connection_remote_ldap_unreachable(testclient):
|
|||
def test_ldap_connection_remote_ldap_wrong_credentials(testclient):
|
||||
testclient.app.config["TESTING"] = False
|
||||
|
||||
testclient.app.config["LDAP"]["BIND_PW"] = "invalid-password"
|
||||
testclient.app.config["BACKENDS"]["LDAP"]["BIND_PW"] = "invalid-password"
|
||||
|
||||
testclient.app.config["DEBUG"] = True
|
||||
res = testclient.get("/", status=500, expect_errors=True)
|
||||
|
|
|
@ -33,7 +33,7 @@ def test_environment_configuration(slapd_server, configuration, tmp_path):
|
|||
|
||||
os.environ["CONFIG"] = config_path
|
||||
app = create_app()
|
||||
assert app.config["LDAP"]["ROOT_DN"] == slapd_server.suffix
|
||||
assert app.config["BACKENDS"]["LDAP"]["ROOT_DN"] == slapd_server.suffix
|
||||
|
||||
del os.environ["CONFIG"]
|
||||
os.remove(config_path)
|
||||
|
|
|
@ -78,15 +78,17 @@ def configuration(slapd_server, smtpd):
|
|||
conf = {
|
||||
"SECRET_KEY": gen_salt(24),
|
||||
"LOGO": "/static/img/canaille-head.png",
|
||||
"LDAP": {
|
||||
"ROOT_DN": slapd_server.suffix,
|
||||
"URI": slapd_server.ldap_uri,
|
||||
"BIND_DN": slapd_server.root_dn,
|
||||
"BIND_PW": slapd_server.root_pw,
|
||||
"USER_BASE": "ou=users",
|
||||
"USER_FILTER": "(|(uid={login})(cn={login}))",
|
||||
"GROUP_BASE": "ou=groups",
|
||||
"TIMEOUT": 0.1,
|
||||
"BACKENDS": {
|
||||
"LDAP": {
|
||||
"ROOT_DN": slapd_server.suffix,
|
||||
"URI": slapd_server.ldap_uri,
|
||||
"BIND_DN": slapd_server.root_dn,
|
||||
"BIND_PW": slapd_server.root_pw,
|
||||
"USER_BASE": "ou=users",
|
||||
"USER_FILTER": "(|(uid={login})(cn={login}))",
|
||||
"GROUP_BASE": "ou=groups",
|
||||
"TIMEOUT": 0.1,
|
||||
},
|
||||
},
|
||||
"ACL": {
|
||||
"DEFAULT": {
|
||||
|
|
|
@ -334,18 +334,20 @@ def test_user_self_deletion(testclient, slapd_connection):
|
|||
|
||||
|
||||
def test_login_placeholder(testclient):
|
||||
testclient.app.config["LDAP"]["USER_FILTER"] = "(uid={login})"
|
||||
testclient.app.config["BACKENDS"]["LDAP"]["USER_FILTER"] = "(uid={login})"
|
||||
placeholder = testclient.get("/login").form["login"].attrs["placeholder"]
|
||||
assert placeholder == "jdoe"
|
||||
|
||||
testclient.app.config["LDAP"]["USER_FILTER"] = "(cn={login})"
|
||||
testclient.app.config["BACKENDS"]["LDAP"]["USER_FILTER"] = "(cn={login})"
|
||||
placeholder = testclient.get("/login").form["login"].attrs["placeholder"]
|
||||
assert placeholder == "John Doe"
|
||||
|
||||
testclient.app.config["LDAP"]["USER_FILTER"] = "(mail={login})"
|
||||
testclient.app.config["BACKENDS"]["LDAP"]["USER_FILTER"] = "(mail={login})"
|
||||
placeholder = testclient.get("/login").form["login"].attrs["placeholder"]
|
||||
assert placeholder == "john@doe.com"
|
||||
|
||||
testclient.app.config["LDAP"]["USER_FILTER"] = "(|(uid={login})(mail={login}))"
|
||||
testclient.app.config["BACKENDS"]["LDAP"][
|
||||
"USER_FILTER"
|
||||
] = "(|(uid={login})(mail={login}))"
|
||||
placeholder = testclient.get("/login").form["login"].attrs["placeholder"]
|
||||
assert placeholder == "jdoe or john@doe.com"
|
||||
|
|
|
@ -194,7 +194,7 @@ def test_guess_object_from_dn(slapd_connection, testclient, foo_group):
|
|||
|
||||
|
||||
def test_object_class_update(slapd_connection, testclient):
|
||||
testclient.app.config["LDAP"]["USER_CLASS"] = ["inetOrgPerson"]
|
||||
testclient.app.config["BACKENDS"]["LDAP"]["USER_CLASS"] = ["inetOrgPerson"]
|
||||
setup_ldap_models(testclient.app.config)
|
||||
|
||||
user1 = User(cn="foo1", sn="bar1")
|
||||
|
@ -203,7 +203,10 @@ def test_object_class_update(slapd_connection, testclient):
|
|||
assert user1.objectClass == ["inetOrgPerson"]
|
||||
assert User.get(id=user1.id).objectClass == ["inetOrgPerson"]
|
||||
|
||||
testclient.app.config["LDAP"]["USER_CLASS"] = ["inetOrgPerson", "extensibleObject"]
|
||||
testclient.app.config["BACKENDS"]["LDAP"]["USER_CLASS"] = [
|
||||
"inetOrgPerson",
|
||||
"extensibleObject",
|
||||
]
|
||||
setup_ldap_models(testclient.app.config)
|
||||
|
||||
user2 = User(cn="foo2", sn="bar2")
|
||||
|
|
|
@ -61,10 +61,10 @@ def test_install_keypair(configuration, tmpdir):
|
|||
|
||||
|
||||
def test_install_schemas(configuration, slapd_server):
|
||||
configuration["LDAP"]["ROOT_DN"] = slapd_server.suffix
|
||||
configuration["LDAP"]["URI"] = slapd_server.ldap_uri
|
||||
configuration["LDAP"]["BIND_DN"] = slapd_server.root_dn
|
||||
configuration["LDAP"]["BIND_PW"] = slapd_server.root_pw
|
||||
configuration["BACKENDS"]["LDAP"]["ROOT_DN"] = slapd_server.suffix
|
||||
configuration["BACKENDS"]["LDAP"]["URI"] = slapd_server.ldap_uri
|
||||
configuration["BACKENDS"]["LDAP"]["BIND_DN"] = slapd_server.root_dn
|
||||
configuration["BACKENDS"]["LDAP"]["BIND_PW"] = slapd_server.root_pw
|
||||
|
||||
conn = ldap.ldapobject.SimpleLDAPObject(slapd_server.ldap_uri)
|
||||
conn.protocol_version = 3
|
||||
|
@ -81,10 +81,12 @@ def test_install_schemas(configuration, slapd_server):
|
|||
|
||||
|
||||
def test_install_no_permissions_to_install_schemas(configuration, slapd_server):
|
||||
configuration["LDAP"]["ROOT_DN"] = slapd_server.suffix
|
||||
configuration["LDAP"]["URI"] = slapd_server.ldap_uri
|
||||
configuration["LDAP"]["BIND_DN"] = "uid=admin,ou=users,dc=mydomain,dc=tld"
|
||||
configuration["LDAP"]["BIND_PW"] = "admin"
|
||||
configuration["BACKENDS"]["LDAP"]["ROOT_DN"] = slapd_server.suffix
|
||||
configuration["BACKENDS"]["LDAP"]["URI"] = slapd_server.ldap_uri
|
||||
configuration["BACKENDS"]["LDAP"][
|
||||
"BIND_DN"
|
||||
] = "uid=admin,ou=users,dc=mydomain,dc=tld"
|
||||
configuration["BACKENDS"]["LDAP"]["BIND_PW"] = "admin"
|
||||
|
||||
conn = ldap.ldapobject.SimpleLDAPObject(slapd_server.ldap_uri)
|
||||
conn.protocol_version = 3
|
||||
|
@ -102,10 +104,10 @@ def test_install_no_permissions_to_install_schemas(configuration, slapd_server):
|
|||
|
||||
|
||||
def test_install_schemas_command(configuration, slapd_server):
|
||||
configuration["LDAP"]["ROOT_DN"] = slapd_server.suffix
|
||||
configuration["LDAP"]["URI"] = slapd_server.ldap_uri
|
||||
configuration["LDAP"]["BIND_DN"] = slapd_server.root_dn
|
||||
configuration["LDAP"]["BIND_PW"] = slapd_server.root_pw
|
||||
configuration["BACKENDS"]["LDAP"]["ROOT_DN"] = slapd_server.suffix
|
||||
configuration["BACKENDS"]["LDAP"]["URI"] = slapd_server.ldap_uri
|
||||
configuration["BACKENDS"]["LDAP"]["BIND_DN"] = slapd_server.root_dn
|
||||
configuration["BACKENDS"]["LDAP"]["BIND_PW"] = slapd_server.root_pw
|
||||
|
||||
conn = ldap.ldapobject.SimpleLDAPObject(slapd_server.ldap_uri)
|
||||
conn.protocol_version = 3
|
||||
|
|
Loading…
Reference in a new issue