sources/ldap: add default property mapping to mirror directory structure (#6990)

* sources/ldap: add default property mapping to mirror directory structure

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* add tests

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* adjust name

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
Jens L 2023-09-26 18:55:33 +02:00 committed by GitHub
parent 017771ddf7
commit 90aa5409cd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 27 additions and 3 deletions

View file

@ -133,7 +133,7 @@ class BaseLDAPSynchronizer:
def build_user_properties(self, user_dn: str, **kwargs) -> dict[str, Any]: def build_user_properties(self, user_dn: str, **kwargs) -> dict[str, Any]:
"""Build attributes for User object based on property mappings.""" """Build attributes for User object based on property mappings."""
props = self._build_object_properties(user_dn, self._source.property_mappings, **kwargs) props = self._build_object_properties(user_dn, self._source.property_mappings, **kwargs)
props["path"] = self._source.get_user_path() props.setdefault("path", self._source.get_user_path())
return props return props
def build_group_properties(self, group_dn: str, **kwargs) -> dict[str, Any]: def build_group_properties(self, group_dn: str, **kwargs) -> dict[str, Any]:
@ -151,7 +151,9 @@ class BaseLDAPSynchronizer:
continue continue
mapping: LDAPPropertyMapping mapping: LDAPPropertyMapping
try: try:
value = mapping.evaluate(user=None, request=None, ldap=kwargs, dn=object_dn) value = mapping.evaluate(
user=None, request=None, ldap=kwargs, dn=object_dn, source=self._source
)
if value is None: if value is None:
self._logger.warning("property mapping returned None", mapping=mapping) self._logger.warning("property mapping returned None", mapping=mapping)
continue continue

View file

@ -55,7 +55,7 @@ def mock_ad_connection(password: str) -> Connection:
"revision": 0, "revision": 0,
"objectSid": "user0", "objectSid": "user0",
"objectClass": "person", "objectClass": "person",
"distinguishedName": "cn=user0,ou=users,dc=goauthentik,dc=io", "distinguishedName": "cn=user0,ou=foo,ou=users,dc=goauthentik,dc=io",
"userAccountControl": ( "userAccountControl": (
UserAccountControl.ACCOUNTDISABLE + UserAccountControl.NORMAL_ACCOUNT UserAccountControl.ACCOUNTDISABLE + UserAccountControl.NORMAL_ACCOUNT
), ),

View file

@ -123,6 +123,7 @@ class LDAPSyncTests(TestCase):
user = User.objects.filter(username="user0_sn").first() user = User.objects.filter(username="user0_sn").first()
self.assertEqual(user.attributes["foo"], "bar") self.assertEqual(user.attributes["foo"], "bar")
self.assertFalse(user.is_active) self.assertFalse(user.is_active)
self.assertEqual(user.path, "goauthentik.io/sources/ldap/users/foo")
self.assertFalse(User.objects.filter(username="user1_sn").exists()) self.assertFalse(User.objects.filter(username="user1_sn").exists())
def test_sync_users_openldap(self): def test_sync_users_openldap(self):

View file

@ -4,6 +4,27 @@ metadata:
blueprints.goauthentik.io/system: "true" blueprints.goauthentik.io/system: "true"
name: System - LDAP Source - Mappings name: System - LDAP Source - Mappings
entries: entries:
- identifiers:
managed: goauthentik.io/sources/ldap/default-dn-path
model: authentik_sources_ldap.ldappropertymapping
attrs:
name: "authentik default LDAP Mapping: DN to User Path"
object_field: "path"
expression: |
dn = ldap.get("distinguishedName")
path_elements = []
for pair in dn.split(","):
attr, _, value = pair.partition("=")
# Ignore elements from the Root DSE and the canonical name of the object
if attr.lower() in ["cn", "dc"]:
continue
path_elements.append(value)
path_elements.reverse()
path = source.get_user_path()
if len(path_elements) > 0:
path = f"{path}/{'/'.join(path_elements)}"
return path
- identifiers: - identifiers:
managed: goauthentik.io/sources/ldap/default-name managed: goauthentik.io/sources/ldap/default-name
model: authentik_sources_ldap.ldappropertymapping model: authentik_sources_ldap.ldappropertymapping