sources/ldap: add list_flatten function to property mappings, enable on managed LDAP mappings

closes #2199

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens Langhammer 2022-01-31 23:07:32 +01:00
parent a5adc4f8ed
commit e93be0de9a
4 changed files with 32 additions and 3 deletions

View File

@ -32,6 +32,7 @@ class BaseEvaluator:
self._globals = { self._globals = {
"regex_match": BaseEvaluator.expr_regex_match, "regex_match": BaseEvaluator.expr_regex_match,
"regex_replace": BaseEvaluator.expr_regex_replace, "regex_replace": BaseEvaluator.expr_regex_replace,
"list_flatten": BaseEvaluator.expr_flatten,
"ak_is_group_member": BaseEvaluator.expr_is_group_member, "ak_is_group_member": BaseEvaluator.expr_is_group_member,
"ak_user_by": BaseEvaluator.expr_user_by, "ak_user_by": BaseEvaluator.expr_user_by,
"ak_logger": get_logger(), "ak_logger": get_logger(),
@ -40,6 +41,15 @@ class BaseEvaluator:
self._context = {} self._context = {}
self._filename = "BaseEvalautor" self._filename = "BaseEvalautor"
@staticmethod
def expr_flatten(value: list[Any] | Any) -> Optional[Any]:
"""Flatten `value` if its a list"""
if isinstance(value, list):
if len(value) < 1:
return None
return value[0]
return value
@staticmethod @staticmethod
def expr_regex_match(value: Any, regex: str) -> bool: def expr_regex_match(value: Any, regex: str) -> bool:
"""Expression Filter to run re.search""" """Expression Filter to run re.search"""

View File

@ -35,21 +35,21 @@ class LDAPProviderManager(ObjectManager):
"goauthentik.io/sources/ldap/ms-userprincipalname", "goauthentik.io/sources/ldap/ms-userprincipalname",
name="authentik default Active Directory Mapping: userPrincipalName", name="authentik default Active Directory Mapping: userPrincipalName",
object_field="attributes.upn", object_field="attributes.upn",
expression="return ldap.get('userPrincipalName')", expression="return list_flatten(ldap.get('userPrincipalName'))",
), ),
EnsureExists( EnsureExists(
LDAPPropertyMapping, LDAPPropertyMapping,
"goauthentik.io/sources/ldap/ms-givenName", "goauthentik.io/sources/ldap/ms-givenName",
name="authentik default Active Directory Mapping: givenName", name="authentik default Active Directory Mapping: givenName",
object_field="attributes.givenName", object_field="attributes.givenName",
expression="return ldap.get('givenName')", expression="return list_flatten(ldap.get('givenName'))",
), ),
EnsureExists( EnsureExists(
LDAPPropertyMapping, LDAPPropertyMapping,
"goauthentik.io/sources/ldap/ms-sn", "goauthentik.io/sources/ldap/ms-sn",
name="authentik default Active Directory Mapping: sn", name="authentik default Active Directory Mapping: sn",
object_field="attributes.sn", object_field="attributes.sn",
expression="return ldap.get('sn')", expression="return list_flatten(ldap.get('sn'))",
), ),
# OpenLDAP specific mappings # OpenLDAP specific mappings
EnsureExists( EnsureExists(

View File

@ -18,6 +18,17 @@ Example:
user_email_local = regex_replace(request.user.email, '(.+)@.+', '') user_email_local = regex_replace(request.user.email, '(.+)@.+', '')
``` ```
### `list_flatten(value: list[Any] | Any) -> Optional[Any}`
Flatten a list by either returning its first element, None if the list is empty, or the passed in object if its not a list.
Example:
```python
user = list_flatten(["foo"])
# user = "foo"
```
### `ak_is_group_member(user: User, **group_filters) -> bool` ### `ak_is_group_member(user: User, **group_filters) -> bool`
Check if `user` is member of a group matching `**group_filters`. Check if `user` is member of a group matching `**group_filters`.

View File

@ -33,3 +33,11 @@ For FreeIPA, follow the [FreeIPA Integration](../freeipa/)
- Sync groups: Enable/disable group synchronization. Groups are synced in the background every 5 minutes. - Sync groups: Enable/disable group synchronization. Groups are synced in the background every 5 minutes.
- Sync parent group: Optionally set this group as the parent group for all synced groups. An example use case of this would be to import Active Directory groups under a root `imported-from-ad` group. - Sync parent group: Optionally set this group as the parent group for all synced groups. An example use case of this would be to import Active Directory groups under a root `imported-from-ad` group.
- Property mappings: Define which LDAP properties map to which authentik properties. The default set of property mappings is generated for Active Directory. See also [LDAP Property Mappings](../../../docs/property-mappings/#ldap-property-mapping) - Property mappings: Define which LDAP properties map to which authentik properties. The default set of property mappings is generated for Active Directory. See also [LDAP Property Mappings](../../../docs/property-mappings/#ldap-property-mapping)
## Property mappings
LDAP property mappings can be used to convert the raw LDAP response into an authentik user/group.
By default, authentik ships with some pre-configured mappings for the most common LDAP setups.
You can assign the value of a mapping to any user attribute, or save it as a custom attribute by prefixing the object field with `attribute.` Keep in mind though, data types from the LDAP server will be carried over. This means that with some implementations, where fields ar stored as array in LDAP, they will be saved as array in authentik. To prevent this, use the built-in `list_flatten` function.