From 379d1b68135be3978e91f39c64274104b4046dd2 Mon Sep 17 00:00:00 2001 From: Dominik George <dominik.george@teckids.org> Date: Fri, 27 Mar 2020 22:59:27 +0000 Subject: [PATCH] Dynamically generate constance configs for sync fields --- aleksis/apps/ldap/apps.py | 5 +++- aleksis/apps/ldap/settings.py | 15 +--------- aleksis/apps/ldap/util/ldap_sync.py | 46 ++++++++++++++++++++++++----- 3 files changed, 44 insertions(+), 22 deletions(-) diff --git a/aleksis/apps/ldap/apps.py b/aleksis/apps/ldap/apps.py index 88f4909..66bec2e 100644 --- a/aleksis/apps/ldap/apps.py +++ b/aleksis/apps/ldap/apps.py @@ -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_sync_from_user +from .util.ldap_sync import ldap_sync_from_user, update_constance_config_fields class LDAPConfig(AppConfig): name = "aleksis.apps.ldap" @@ -11,5 +11,8 @@ class LDAPConfig(AppConfig): def ready(self) -> None: super().ready() + + update_constance_config_fields() + User = get_user_model() post_save.connect(ldap_sync_from_user, sender=User) diff --git a/aleksis/apps/ldap/settings.py b/aleksis/apps/ldap/settings.py index 47f9cd7..5bc325f 100644 --- a/aleksis/apps/ldap/settings.py +++ b/aleksis/apps/ldap/settings.py @@ -1,3 +1,4 @@ +from django.apps import apps from django.utils.translation import gettext_lazy as _ CONSTANCE_ADDITIONAL_FIELDS = { @@ -23,13 +24,6 @@ CONSTANCE_CONFIG = { _("LDAP sync matching fields"), "matching-fields-select", ), - "LDAP_SYNC_FIELD_STREET": (None, _("Field for street"), str), - "LDAP_SYNC_FIELD_HOUSENUMBER": (None, _("Field for house number"), str), - "LDAP_SYNC_FIELD_POSTAL_CODE": (None, _("Field for postal code"), str), - "LDAP_SYNC_FIELD_PLACE": (None, _("Field for place"), str), - "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), @@ -39,13 +33,6 @@ CONSTANCE_CONFIG_FIELDSETS = { "ENABLE_LDAP_SYNC", "LDAP_SYNC_ON_UPDATE", "LDAP_MATCHING_FIELDS", - "LDAP_SYNC_FIELD_STREET", - "LDAP_SYNC_FIELD_HOUSENUMBER", - "LDAP_SYNC_FIELD_POSTAL_CODE", - "LDAP_SYNC_FIELD_PLACE", - "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", diff --git a/aleksis/apps/ldap/util/ldap_sync.py b/aleksis/apps/ldap/util/ldap_sync.py index 3873507..be0239e 100644 --- a/aleksis/apps/ldap/util/ldap_sync.py +++ b/aleksis/apps/ldap/util/ldap_sync.py @@ -1,9 +1,37 @@ from django.apps import apps +from django.conf import settings from django.contrib.auth import get_user_model from constance import config +def setting_name_from_field(model, field): + """ Generate a constance setting name from a model field """ + + return "LDAP_ADDITIONAL_FIELD_%s_%s" % (model._meta.label, field.name) + + +def update_constance_config_fields(): + """ Auto-generate sync field settings from models """ + + Person = apps.get_model("core", "Person") + for model in (Person,): + # Collect fields that are matchable + setting_names = [] + for field in model._meta.fields: + if field.editable and not field.auto_created: + setting_name = setting_name_from_field(model, field) + setting_desc = field.verbose_name + + settings.CONSTANCE_CONFIG[setting_name] = ("", setting_desc, str) + setting_names.append(setting_name) + + # Add separate constance section if settings were generated + if setting_names: + fieldset_name = "LDAP-Sync: Additional fields for %s" % model._meta.verbose_name + settings.CONSTANCE_CONFIG_FIELDSETS[fieldset_name] = setting_names + + 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. """ @@ -28,6 +56,17 @@ def ldap_sync_from_user(sender, instance, created, raw, using, update_fields, ** return person.user = instance + + # Synchronise additional fields if enabled + for field in Person._meta.fields: + if field.editable and not field.auto_created: + setting_name = setting_name_from_field(Person, field) + + # Try sync if constance setting for this field is non-empty + ldap_field = getattr(config, setting_name, "") + if ldap_field and ldap_field in instance.ldap_user.attrs.data: + setattr(person, field._meta.name, instance.ldap_user.attrs.data[ldap_field]) + person.save() if config.ENABLE_LDAP_GROUP_SYNC: @@ -51,10 +90,3 @@ def ldap_sync_from_user(sender, instance, created, raw, using, update_fields, ** # Sync additional fields if enabled in config. ldap_user = instance.ldap_user - person.street = ldap_user.attrs.data[config.LDAP_SYNC_FIELD_STREET] - person.housenumber = ldap_user.attrs.data[config.LDAP_SYNC_FIELD_HOUSENUMBER] - person.postal_code = ldap_user.attrs.data[config.LDAP_SYNC_FIELD_POSTAL_CODE] - person.place = ldap_user.attrs.data[config.LDAP_SYNC_FIELD_PLACE] - 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] -- GitLab