forked from Github-Mirrors/canaille
Moved canaille.ldap_backend to canaille.backends.ldap
This commit is contained in:
parent
c4676ec572
commit
fa62c16768
25 changed files with 97 additions and 85 deletions
|
@ -1,5 +1,5 @@
|
||||||
include canaille/conf/*.sample.*
|
include canaille/conf/*.sample.*
|
||||||
graft canaille/ldap_backend/schemas
|
graft canaille/backends/ldap/schemas
|
||||||
graft canaille/templates
|
graft canaille/templates
|
||||||
graft canaille/themes
|
graft canaille/themes
|
||||||
graft canaille/translations
|
graft canaille/translations
|
||||||
|
|
|
@ -173,7 +173,7 @@ def create_app(config=None, validate=True):
|
||||||
sentry_sdk = setup_sentry(app)
|
sentry_sdk = setup_sentry(app)
|
||||||
try:
|
try:
|
||||||
from .oidc.oauth import setup_oauth
|
from .oidc.oauth import setup_oauth
|
||||||
from .ldap_backend.backend import init_backend
|
from .backends.ldap.backend import init_backend
|
||||||
from .app.i18n import setup_i18n
|
from .app.i18n import setup_i18n
|
||||||
|
|
||||||
setup_logging(app)
|
setup_logging(app)
|
||||||
|
|
|
@ -9,7 +9,7 @@ from flask.cli import with_appcontext
|
||||||
def with_backendcontext(func):
|
def with_backendcontext(func):
|
||||||
@functools.wraps(func)
|
@functools.wraps(func)
|
||||||
def _func(*args, **kwargs):
|
def _func(*args, **kwargs):
|
||||||
from canaille.ldap_backend.backend import (
|
from canaille.backends.ldap.backend import (
|
||||||
setup_backend,
|
setup_backend,
|
||||||
teardown_backend,
|
teardown_backend,
|
||||||
)
|
)
|
||||||
|
|
|
@ -16,7 +16,7 @@ def validate(config, validate_remote=False):
|
||||||
if not validate_remote:
|
if not validate_remote:
|
||||||
return
|
return
|
||||||
|
|
||||||
from canaille.ldap_backend.backend import validate_configuration
|
from canaille.backends.ldap.backend import validate_configuration
|
||||||
|
|
||||||
validate_configuration(config)
|
validate_configuration(config)
|
||||||
validate_smtp_configuration(config)
|
validate_smtp_configuration(config)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import ldap.filter
|
import ldap.filter
|
||||||
from canaille.ldap_backend.ldapobject import LDAPObject
|
from canaille.backends.ldap.ldapobject import LDAPObject
|
||||||
from flask import current_app
|
from flask import current_app
|
||||||
from flask import session
|
from flask import session
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from canaille.ldap_backend.installation import install_schema
|
from canaille.backends.ldap.installation import install_schema
|
||||||
from canaille.ldap_backend.installation import ldap_connection
|
from canaille.backends.ldap.installation import ldap_connection
|
||||||
from canaille.oidc.models import AuthorizationCode
|
from canaille.oidc.models import AuthorizationCode
|
||||||
from canaille.oidc.models import Client
|
from canaille.oidc.models import Client
|
||||||
from canaille.oidc.models import Consent
|
from canaille.oidc.models import Consent
|
||||||
|
@ -54,5 +54,5 @@ def setup_schemas(config):
|
||||||
install_schema(
|
install_schema(
|
||||||
config,
|
config,
|
||||||
os.path.dirname(os.path.dirname(__file__))
|
os.path.dirname(os.path.dirname(__file__))
|
||||||
+ "/ldap_backend/schemas/oauth2-openldap.ldif",
|
+ "/backends/ldap/schemas/oauth2-openldap.ldif",
|
||||||
)
|
)
|
||||||
|
|
|
@ -4,7 +4,7 @@ from authlib.oauth2.rfc6749 import AuthorizationCodeMixin
|
||||||
from authlib.oauth2.rfc6749 import ClientMixin
|
from authlib.oauth2.rfc6749 import ClientMixin
|
||||||
from authlib.oauth2.rfc6749 import TokenMixin
|
from authlib.oauth2.rfc6749 import TokenMixin
|
||||||
from authlib.oauth2.rfc6749 import util
|
from authlib.oauth2.rfc6749 import util
|
||||||
from canaille.ldap_backend.ldapobject import LDAPObject
|
from canaille.backends.ldap.ldapobject import LDAPObject
|
||||||
|
|
||||||
|
|
||||||
class Client(LDAPObject, ClientMixin):
|
class Client(LDAPObject, ClientMixin):
|
||||||
|
|
|
@ -10,7 +10,7 @@ services:
|
||||||
- ./ldif/memberof-config.ldif:/container/service/slapd/assets/config/bootstrap/ldif/03-memberOf.ldif:ro
|
- ./ldif/memberof-config.ldif:/container/service/slapd/assets/config/bootstrap/ldif/03-memberOf.ldif:ro
|
||||||
# memberof overlay is already present in openldap docker image but only for groupOfUniqueNames. We need to overwrite it (until canaille can handle groupOfUniqueNames).
|
# memberof overlay is already present in openldap docker image but only for groupOfUniqueNames. We need to overwrite it (until canaille can handle groupOfUniqueNames).
|
||||||
# https://github.com/osixia/docker-openldap/blob/master/image/service/slapd/assets/config/bootstrap/ldif/03-memberOf.ldif
|
# https://github.com/osixia/docker-openldap/blob/master/image/service/slapd/assets/config/bootstrap/ldif/03-memberOf.ldif
|
||||||
- ../canaille/ldap_backend/schemas/oauth2-openldap.ldif:/container/service/slapd/assets/config/bootstrap/ldif/custom/40-oauth2.ldif:ro
|
- ../canaille/backends/ldap/schemas/oauth2-openldap.ldif:/container/service/slapd/assets/config/bootstrap/ldif/custom/40-oauth2.ldif:ro
|
||||||
- ./ldif/bootstrap-users-tree.ldif:/container/service/slapd/assets/config/bootstrap/ldif/custom/50-bootstrap-users-tree.ldif:ro
|
- ./ldif/bootstrap-users-tree.ldif:/container/service/slapd/assets/config/bootstrap/ldif/custom/50-bootstrap-users-tree.ldif:ro
|
||||||
- ./ldif/bootstrap-oidc-tree.ldif:/container/service/slapd/assets/config/bootstrap/ldif/custom/50-bootstrap-oidc-tree.ldif:ro
|
- ./ldif/bootstrap-oidc-tree.ldif:/container/service/slapd/assets/config/bootstrap/ldif/custom/50-bootstrap-oidc-tree.ldif:ro
|
||||||
- ./ldif/bootstrap-users.ldif:/container/service/slapd/assets/config/bootstrap/ldif/custom/60-bootstrap-users.ldif:ro
|
- ./ldif/bootstrap-users.ldif:/container/service/slapd/assets/config/bootstrap/ldif/custom/60-bootstrap-users.ldif:ro
|
||||||
|
|
|
@ -14,7 +14,7 @@ slapd = slapd.Slapd(
|
||||||
"cosine.ldif",
|
"cosine.ldif",
|
||||||
"nis.ldif",
|
"nis.ldif",
|
||||||
"inetorgperson.ldif",
|
"inetorgperson.ldif",
|
||||||
"../canaille/ldap_backend/schemas/oauth2-openldap.ldif",
|
"../canaille/backends/ldap/schemas/oauth2-openldap.ldif",
|
||||||
"ldif/memberof-config.ldif",
|
"ldif/memberof-config.ldif",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
|
@ -68,8 +68,8 @@ Old fashion: Copy the schemas in your filesystem
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
test -d /etc/openldap/schema && sudo cp "$CANAILLE_INSTALL_DIR/env/lib/python*/site-packages/canaille/ldap_backend/schemas/*" /etc/openldap/schema
|
test -d /etc/openldap/schema && sudo cp "$CANAILLE_INSTALL_DIR/env/lib/python*/site-packages/canaille/backends/ldap/schemas/*" /etc/openldap/schema
|
||||||
test -d /etc/ldap/schema && sudo cp "$CANAILLE_INSTALL_DIR/env/lib/python*/site-packages/canaille/ldap_backend/schemas/*" /etc/ldap/schema
|
test -d /etc/ldap/schema && sudo cp "$CANAILLE_INSTALL_DIR/env/lib/python*/site-packages/canaille/backends/ldap/schemas/*" /etc/ldap/schema
|
||||||
sudo service slapd restart
|
sudo service slapd restart
|
||||||
|
|
||||||
New fashion: Use slapadd to add the schemas
|
New fashion: Use slapadd to add the schemas
|
||||||
|
@ -80,7 +80,7 @@ Be careful to stop your ldap server before running ``slapadd``
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
sudo service slapd stop
|
sudo service slapd stop
|
||||||
sudo -u openldap slapadd -n0 -l "$CANAILLE_INSTALL_DIR/env/lib/python*/site-packages/canaille/ldap_backend/schemas/*.ldif"
|
sudo -u openldap slapadd -n0 -l "$CANAILLE_INSTALL_DIR/env/lib/python*/site-packages/canaille/backends/ldap/schemas/*.ldif"
|
||||||
sudo service slapd start
|
sudo service slapd start
|
||||||
|
|
||||||
Generate the key pair
|
Generate the key pair
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
import os
|
import os
|
||||||
from unittest import mock
|
|
||||||
|
|
||||||
import ldap
|
|
||||||
import pytest
|
import pytest
|
||||||
from canaille import create_app
|
from canaille import create_app
|
||||||
from canaille.app.configuration import ConfigurationException
|
from canaille.app.configuration import ConfigurationException
|
||||||
|
@ -9,61 +7,9 @@ from canaille.app.configuration import validate
|
||||||
from flask_webtest import TestApp
|
from flask_webtest import TestApp
|
||||||
|
|
||||||
|
|
||||||
def test_ldap_connection_no_remote(testclient, configuration):
|
def test_smtp_connection_remote_smtp_unreachable(
|
||||||
validate(configuration)
|
testclient, slapd_connection, configuration
|
||||||
|
|
||||||
|
|
||||||
def test_ldap_connection_remote(testclient, configuration, slapd_connection):
|
|
||||||
validate(configuration, validate_remote=True)
|
|
||||||
|
|
||||||
|
|
||||||
def test_ldap_connection_remote_ldap_unreachable(testclient, configuration):
|
|
||||||
configuration["BACKENDS"]["LDAP"]["URI"] = "ldap://invalid-ldap.com"
|
|
||||||
with pytest.raises(
|
|
||||||
ConfigurationException,
|
|
||||||
match=r"Could not connect to the LDAP server",
|
|
||||||
):
|
):
|
||||||
validate(configuration, validate_remote=True)
|
|
||||||
|
|
||||||
|
|
||||||
def test_ldap_connection_remote_ldap_wrong_credentials(testclient, configuration):
|
|
||||||
configuration["BACKENDS"]["LDAP"]["BIND_PW"] = "invalid-password"
|
|
||||||
with pytest.raises(
|
|
||||||
ConfigurationException,
|
|
||||||
match=r"LDAP authentication failed with user",
|
|
||||||
):
|
|
||||||
validate(configuration, validate_remote=True)
|
|
||||||
|
|
||||||
|
|
||||||
def test_ldap_cannot_create_users(testclient, configuration, slapd_connection):
|
|
||||||
from canaille.core.models import User
|
|
||||||
|
|
||||||
def fake_init(*args, **kwarg):
|
|
||||||
raise ldap.INSUFFICIENT_ACCESS
|
|
||||||
|
|
||||||
with mock.patch.object(User, "__init__", fake_init):
|
|
||||||
with pytest.raises(
|
|
||||||
ConfigurationException,
|
|
||||||
match=r"cannot create users at",
|
|
||||||
):
|
|
||||||
validate(configuration, validate_remote=True)
|
|
||||||
|
|
||||||
|
|
||||||
def test_ldap_cannot_create_groups(testclient, configuration, slapd_connection):
|
|
||||||
from canaille.core.models import Group
|
|
||||||
|
|
||||||
def fake_init(*args, **kwarg):
|
|
||||||
raise ldap.INSUFFICIENT_ACCESS
|
|
||||||
|
|
||||||
with mock.patch.object(Group, "__init__", fake_init):
|
|
||||||
with pytest.raises(
|
|
||||||
ConfigurationException,
|
|
||||||
match=r"cannot create groups at",
|
|
||||||
):
|
|
||||||
validate(configuration, validate_remote=True)
|
|
||||||
|
|
||||||
|
|
||||||
def test_smtp_connection_remote_smtp_unreachable(testclient, configuration):
|
|
||||||
configuration["SMTP"]["HOST"] = "smtp://invalid-smtp.com"
|
configuration["SMTP"]["HOST"] = "smtp://invalid-smtp.com"
|
||||||
with pytest.raises(
|
with pytest.raises(
|
||||||
ConfigurationException,
|
ConfigurationException,
|
||||||
|
@ -72,7 +18,9 @@ def test_smtp_connection_remote_smtp_unreachable(testclient, configuration):
|
||||||
validate(configuration, validate_remote=True)
|
validate(configuration, validate_remote=True)
|
||||||
|
|
||||||
|
|
||||||
def test_smtp_connection_remote_smtp_wrong_credentials(testclient, configuration):
|
def test_smtp_connection_remote_smtp_wrong_credentials(
|
||||||
|
testclient, slapd_connection, configuration
|
||||||
|
):
|
||||||
configuration["SMTP"]["PASSWORD"] = "invalid-password"
|
configuration["SMTP"]["PASSWORD"] = "invalid-password"
|
||||||
with pytest.raises(
|
with pytest.raises(
|
||||||
ConfigurationException,
|
ConfigurationException,
|
||||||
|
@ -81,7 +29,9 @@ def test_smtp_connection_remote_smtp_wrong_credentials(testclient, configuration
|
||||||
validate(configuration, validate_remote=True)
|
validate(configuration, validate_remote=True)
|
||||||
|
|
||||||
|
|
||||||
def test_smtp_connection_remote_smtp_no_credentials(testclient, configuration):
|
def test_smtp_connection_remote_smtp_no_credentials(
|
||||||
|
testclient, slapd_connection, configuration
|
||||||
|
):
|
||||||
del configuration["SMTP"]["LOGIN"]
|
del configuration["SMTP"]["LOGIN"]
|
||||||
del configuration["SMTP"]["PASSWORD"]
|
del configuration["SMTP"]["PASSWORD"]
|
||||||
validate(configuration, validate_remote=True)
|
validate(configuration, validate_remote=True)
|
||||||
|
@ -97,7 +47,11 @@ def test_smtp_bad_tls(testclient, slapd_connection, smtpd, configuration):
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def themed_testclient(app, configuration):
|
def themed_testclient(
|
||||||
|
app,
|
||||||
|
configuration,
|
||||||
|
slapd_connection,
|
||||||
|
):
|
||||||
configuration["TESTING"] = True
|
configuration["TESTING"] = True
|
||||||
|
|
||||||
root = os.path.dirname(os.path.abspath(__file__))
|
root = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
@ -109,7 +63,7 @@ def themed_testclient(app, configuration):
|
||||||
return TestApp(app)
|
return TestApp(app)
|
||||||
|
|
||||||
|
|
||||||
def test_theme(testclient, themed_testclient):
|
def test_theme(testclient, themed_testclient, slapd_connection):
|
||||||
res = testclient.get("/login")
|
res = testclient.get("/login")
|
||||||
res.mustcontain(no="TEST_THEME")
|
res.mustcontain(no="TEST_THEME")
|
||||||
|
|
||||||
|
@ -117,7 +71,7 @@ def test_theme(testclient, themed_testclient):
|
||||||
res.mustcontain("TEST_THEME")
|
res.mustcontain("TEST_THEME")
|
||||||
|
|
||||||
|
|
||||||
def test_invalid_theme(configuration):
|
def test_invalid_theme(configuration, slapd_connection):
|
||||||
validate(configuration, validate_remote=False)
|
validate(configuration, validate_remote=False)
|
||||||
|
|
||||||
with pytest.raises(
|
with pytest.raises(
|
||||||
|
|
0
tests/backends/__init__.py
Normal file
0
tests/backends/__init__.py
Normal file
0
tests/backends/ldap/__init__.py
Normal file
0
tests/backends/ldap/__init__.py
Normal file
|
@ -1,14 +1,18 @@
|
||||||
import datetime
|
import datetime
|
||||||
|
from unittest import mock
|
||||||
|
|
||||||
import ldap.dn
|
import ldap.dn
|
||||||
|
import pytest
|
||||||
|
from canaille.app.configuration import ConfigurationException
|
||||||
|
from canaille.app.configuration import validate
|
||||||
|
from canaille.backends.ldap.backend import setup_ldap_models
|
||||||
|
from canaille.backends.ldap.ldapobject import LDAPObject
|
||||||
|
from canaille.backends.ldap.ldapobject import python_attrs_to_ldap
|
||||||
|
from canaille.backends.ldap.utils import ldap_to_python
|
||||||
|
from canaille.backends.ldap.utils import python_to_ldap
|
||||||
|
from canaille.backends.ldap.utils import Syntax
|
||||||
from canaille.core.models import Group
|
from canaille.core.models import Group
|
||||||
from canaille.core.models import User
|
from canaille.core.models import User
|
||||||
from canaille.ldap_backend.backend import setup_ldap_models
|
|
||||||
from canaille.ldap_backend.ldapobject import LDAPObject
|
|
||||||
from canaille.ldap_backend.ldapobject import python_attrs_to_ldap
|
|
||||||
from canaille.ldap_backend.utils import ldap_to_python
|
|
||||||
from canaille.ldap_backend.utils import python_to_ldap
|
|
||||||
from canaille.ldap_backend.utils import Syntax
|
|
||||||
|
|
||||||
|
|
||||||
def test_object_creation(slapd_connection):
|
def test_object_creation(slapd_connection):
|
||||||
|
@ -224,3 +228,57 @@ def test_object_class_update(slapd_connection, testclient):
|
||||||
|
|
||||||
user1.delete()
|
user1.delete()
|
||||||
user2.delete()
|
user2.delete()
|
||||||
|
|
||||||
|
|
||||||
|
def test_ldap_connection_no_remote(testclient, configuration):
|
||||||
|
validate(configuration)
|
||||||
|
|
||||||
|
|
||||||
|
def test_ldap_connection_remote(testclient, configuration, slapd_connection):
|
||||||
|
validate(configuration, validate_remote=True)
|
||||||
|
|
||||||
|
|
||||||
|
def test_ldap_connection_remote_ldap_unreachable(testclient, configuration):
|
||||||
|
configuration["BACKENDS"]["LDAP"]["URI"] = "ldap://invalid-ldap.com"
|
||||||
|
with pytest.raises(
|
||||||
|
ConfigurationException,
|
||||||
|
match=r"Could not connect to the LDAP server",
|
||||||
|
):
|
||||||
|
validate(configuration, validate_remote=True)
|
||||||
|
|
||||||
|
|
||||||
|
def test_ldap_connection_remote_ldap_wrong_credentials(testclient, configuration):
|
||||||
|
configuration["BACKENDS"]["LDAP"]["BIND_PW"] = "invalid-password"
|
||||||
|
with pytest.raises(
|
||||||
|
ConfigurationException,
|
||||||
|
match=r"LDAP authentication failed with user",
|
||||||
|
):
|
||||||
|
validate(configuration, validate_remote=True)
|
||||||
|
|
||||||
|
|
||||||
|
def test_ldap_cannot_create_users(testclient, configuration, slapd_connection):
|
||||||
|
from canaille.core.models import User
|
||||||
|
|
||||||
|
def fake_init(*args, **kwarg):
|
||||||
|
raise ldap.INSUFFICIENT_ACCESS
|
||||||
|
|
||||||
|
with mock.patch.object(User, "__init__", fake_init):
|
||||||
|
with pytest.raises(
|
||||||
|
ConfigurationException,
|
||||||
|
match=r"cannot create users at",
|
||||||
|
):
|
||||||
|
validate(configuration, validate_remote=True)
|
||||||
|
|
||||||
|
|
||||||
|
def test_ldap_cannot_create_groups(testclient, configuration, slapd_connection):
|
||||||
|
from canaille.core.models import Group
|
||||||
|
|
||||||
|
def fake_init(*args, **kwarg):
|
||||||
|
raise ldap.INSUFFICIENT_ACCESS
|
||||||
|
|
||||||
|
with mock.patch.object(Group, "__init__", fake_init):
|
||||||
|
with pytest.raises(
|
||||||
|
ConfigurationException,
|
||||||
|
match=r"cannot create groups at",
|
||||||
|
):
|
||||||
|
validate(configuration, validate_remote=True)
|
|
@ -2,9 +2,9 @@ import ldap.ldapobject
|
||||||
import pytest
|
import pytest
|
||||||
import slapd
|
import slapd
|
||||||
from canaille import create_app
|
from canaille import create_app
|
||||||
|
from canaille.backends.ldap.backend import setup_ldap_models
|
||||||
from canaille.core.models import Group
|
from canaille.core.models import Group
|
||||||
from canaille.core.models import User
|
from canaille.core.models import User
|
||||||
from canaille.ldap_backend.backend import setup_ldap_models
|
|
||||||
from canaille.oidc.installation import setup_ldap_tree
|
from canaille.oidc.installation import setup_ldap_tree
|
||||||
from flask import g
|
from flask import g
|
||||||
from flask_webtest import TestApp
|
from flask_webtest import TestApp
|
||||||
|
@ -52,7 +52,7 @@ def slapd_server():
|
||||||
slapd.init_tree()
|
slapd.init_tree()
|
||||||
for ldif in (
|
for ldif in (
|
||||||
"demo/ldif/memberof-config.ldif",
|
"demo/ldif/memberof-config.ldif",
|
||||||
"canaille/ldap_backend/schemas/oauth2-openldap.ldif",
|
"canaille/backends/ldap/schemas/oauth2-openldap.ldif",
|
||||||
"demo/ldif/bootstrap-users-tree.ldif",
|
"demo/ldif/bootstrap-users-tree.ldif",
|
||||||
"demo/ldif/bootstrap-oidc-tree.ldif",
|
"demo/ldif/bootstrap-oidc-tree.ldif",
|
||||||
):
|
):
|
||||||
|
|
|
@ -4,8 +4,8 @@ import ldap
|
||||||
import pytest
|
import pytest
|
||||||
from canaille import create_app
|
from canaille import create_app
|
||||||
from canaille.app.installation import InstallationException
|
from canaille.app.installation import InstallationException
|
||||||
|
from canaille.backends.ldap.ldapobject import LDAPObject
|
||||||
from canaille.commands import cli
|
from canaille.commands import cli
|
||||||
from canaille.ldap_backend.ldapobject import LDAPObject
|
|
||||||
from canaille.oidc.installation import setup_schemas
|
from canaille.oidc.installation import setup_schemas
|
||||||
from flask_webtest import TestApp
|
from flask_webtest import TestApp
|
||||||
from tests.conftest import CustomSlapdObject
|
from tests.conftest import CustomSlapdObject
|
||||||
|
|
Loading…
Reference in a new issue