Skip to content
Snippets Groups Projects
Verified Commit fe308727 authored by Tom Teichler's avatar Tom Teichler :beers:
Browse files

Merge branch 'master' into 3-sync-additional-ldap-fields-after-login

parents 1d8dcb26 02cc4ce5
No related branches found
No related tags found
1 merge request!2Resolve "Sync additional LDAP fields after login"
......@@ -3,7 +3,7 @@ from django.db.models.signals import post_save
from aleksis.core.util.apps import AppConfig
from .util.ldap_sync import ldap_create_user
from .util.ldap_sync import ldap_sync_from_user
class LDAPConfig(AppConfig):
name = "aleksis.apps.ldap"
......@@ -12,4 +12,4 @@ class LDAPConfig(AppConfig):
def ready(self) -> None:
super().ready()
User = get_user_model()
post_save.connect(ldap_create_user, sender=User)
post_save.connect(ldap_sync_from_user, sender=User)
......@@ -17,7 +17,6 @@ CONSTANCE_ADDITIONAL_FIELDS = {
CONSTANCE_CONFIG = {
"ENABLE_LDAP_SYNC": (True, _("Enable ldap sync"), bool),
"LDAP_SYNC_CREATE": (True, _("Match created persons to users"), bool),
"LDAP_SYNC_ON_UPDATE": (True, _("Also sync if user updates"), bool),
"LDAP_MATCHING_FIELDS": (
None,
......@@ -31,11 +30,13 @@ CONSTANCE_CONFIG = {
"LDAP_SYNC_FIELD_PHONE_NUMBER": (None, _("Field for phone number"), str),
"LDAP_SYNC_FIELD_MOBILE_NUMBER": (None, _("Field for mobile number"), str),
"LDAP_SYNC_FIELD_DATE_OF_BIRTH": (None, _("Field for date of birth"), str),
"ENABLE_LDAP_GROUP_SYNC": (True, _("Enable ldap group sync"), bool),
"LDAP_GROUP_SYNC_FIELD_SHORT_NAME": ("cn", _("Field for short name of group"), str),
"LDAP_GROUP_SYNC_FIELD_NAME": ("cn", _("Field for name of group"), str),
}
CONSTANCE_CONFIG_FIELDSETS = {
"LDAP-Sync settings": (
"ENABLE_LDAP_SYNC",
"LDAP_SYNC_CREATE",
"LDAP_SYNC_ON_UPDATE",
"LDAP_MATCHING_FIELDS",
"LDAP_SYNC_FIELD_STREET",
......@@ -45,5 +46,8 @@ CONSTANCE_CONFIG_FIELDSETS = {
"LDAP_SYNC_FIELD_PHONE_NUMBER",
"LDAP_SYNC_FIELD_MOBILE_NUMBER",
"LDAP_SYNC_FIELD_DATE_OF_BIRTH",
"ENABLE_LDAP_GROUP_SYNC",
"LDAP_GROUP_SYNC_FIELD_SHORT_NAME",
"LDAP_GROUP_SYNC_FIELD_NAME",
),
}
......@@ -4,37 +4,51 @@ from django.contrib.auth import get_user_model
from constance import config
def ldap_create_user(sender, instance, created, raw, using, update_fields, **kwargs):
""" Find ldap users by configurable matching fields and connect them to django users. """
def ldap_sync_from_user(sender, instance, created, raw, using, update_fields, **kwargs):
""" Synchronise Person meta-data and groups from ldap_user on User update. """
Person = apps.get_model("core", "Person")
Group = apps.get_model("core", "Group")
if config.ENABLE_LDAP_SYNC and (created or config.LDAP_SYNC_ON_UPDATE):
if config.ENABLE_LDAP_SYNC and (created or config.LDAP_SYNC_ON_UPDATE) and hasattr(instance, "ldap_user"):
# Check if there is an existing person connected to the user.
if not Person.objects.filter(user=instance).exists():
if config.LDAP_MATCHING_FIELDS == "match-email":
# Get or create a person matching to email field.
person, created = Person.objects.get_or_create(
email=instance.email,
defaults={
"first_name": instance.first_name,
"last_name": instance.last_name,
},
)
elif config.LDAP_MATCHING_FIELDS == "match-name":
# Get or create a person matching to the first and last name.
person, created = Person.objects.get_or_create(
first_name=instance.first_name,
last_name=instance.last_name,
defaults={"email": instance.email},
)
elif config.LDAP_MATCHING_FIELDS == "match-email-name":
# Get or create a person matching to the email and the first and last name.
person, created = Person.objects.get_or_create(
first_name=instance.first_name,
last_name=instance.last_name,
email=instance.email,
# Build filter criteria depending on config
matches = {}
if "-email" in config.LDAP_MATCHING_FIELDS:
matches["email"] = instance.email
if "-name" in config.LDAP_MATCHING_FIELDS:
matches["first_name"] = instance.first_name
matches["last_name"] = instance.last_name
try:
person = Person.objects.get(**matches)
except Person.DoesNotExist:
# Bail out of further processing
return
person.user = instance
person.save()
if config.ENABLE_LDAP_GROUP_SYNC:
# Resolve Group objects from LDAP group objects
group_objects = []
groups = instance.ldap_user._get_groups()
group_infos = list(groups._get_group_infos())
for ldap_group in group_infos:
group, created = Group.objects.update_or_create(
import_ref = ldap_group[0],
defaults = {
"short_name": ldap_group[1][config.LDAP_GROUP_SYNC_FIELD_SHORT_NAME][0][-16:],
"name": ldap_group[1][config.LDAP_GROUP_SYNC_FIELD_NAME][0][:60]
}
)
group_objects.append(group)
# Replace linked groups of logged-in user completely
instance.person.member_of.set(group_objects)
# Sync additional fields if enabled in config.
ldap_user = instance.ldap_user
person.street = ldap_user.attrs.data[config.LDAP_SYNC_FIELD_STREET]
......@@ -44,8 +58,3 @@ def ldap_create_user(sender, instance, created, raw, using, update_fields, **kwa
person.phone_number = ldap_user.attrs.data[config.LDAP_SYNC_FIELD_PHONE_NUMBER]
person.mobile_number = ldap_user.attrs.data[config.LDAP_SYNC_FIELD_MOBILE_NUMBER]
person.date_of_birth = ldap_user.attrs.data[config.LDAP_SYNC_FIELD_DATE_OF_BIRTH]
# Save person if enabled in config or no new person was created.
if config.LDAP_SYNC_CREATE or not created:
person.user = instance
person.save()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment