From 8fc5a7d5548e258262d9bf122475fd7905b6bfb5 Mon Sep 17 00:00:00 2001 From: Julian Rother <julianr@fsmpi.rwth-aachen.de> Date: Thu, 25 Feb 2021 17:03:31 +0100 Subject: [PATCH] Refactored processing of LDAP_USER_DEFAULT_ATTRIBUTES --- uffd/default_config.cfg | 5 ++++- uffd/user/models.py | 32 ++++++++++++++++++-------------- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/uffd/default_config.cfg b/uffd/default_config.cfg index 91d665ff..619b5fe8 100644 --- a/uffd/default_config.cfg +++ b/uffd/default_config.cfg @@ -15,8 +15,11 @@ LDAP_USER_MAIL_ATTRIBUTE="mail" LDAP_USER_MAIL_ALIASES=[] LDAP_USER_DEFAULT_ATTRIBUTES={ "sn": " ", + # All string values are subject to python str.format-style format expansion. To insert literal braces use "{{" and "}}". + # Variables: uid, loginname, displayname, mail and possibly other attributes of the User class "homeDirectory": "/home/{loginname}", - "gidNumber": LDAP_USER_GID + "gidNumber": LDAP_USER_GID, + # "multiValueAttribute": ["value1", "value2"], } LDAP_GROUP_SEARCH_BASE="ou=groups,dc=example,dc=com" diff --git a/uffd/user/models.py b/uffd/user/models.py index 40a829c3..8f839add 100644 --- a/uffd/user/models.py +++ b/uffd/user/models.py @@ -17,13 +17,18 @@ def get_next_uid(): raise Exception('No free uid found') return next_uid -class DictView: +class ObjectAttributeDict: def __init__(self, obj): self.obj = obj def __getitem__(self, key): return getattr(self.obj, key) +def format_with_attributes(fmtstr, obj): + # Do str.format-style string formatting with the attributes of an object + # E.g. format_with_attributes("/home/{loginname}", obj) = "/home/foobar" if obj.loginname = "foobar" + return fmtstr.format_map(ObjectAttributeDict(obj)) + class BaseUser(ldap.Model): ldap_search_base = lazyconfig_str('LDAP_USER_SEARCH_BASE') ldap_filter_params = lazyconfig_list('LDAP_USER_SEARCH_FILTER') @@ -40,19 +45,18 @@ class BaseUser(ldap.Model): groups = [] # Shuts up pylint, overwritten by back-reference roles = [] # Shuts up pylint, overwritten by back-reference - def dummy_attribute_defaults(self): - for name, patterns in current_app.config['LDAP_USER_DEFAULT_ATTRIBUTES'].items(): - if not isinstance(patterns, list): - patterns = [patterns] - values = [] - for pattern in patterns: - if isinstance(pattern, str): - values.append(pattern.format_map(DictView(self))) - else: - values.append(pattern) - self.ldap_object.setattr(name, values) - - ldap_add_hooks = ldap.Model.ldap_add_hooks + (dummy_attribute_defaults,) + def add_default_attributes(self): + for name, values in current_app.config['LDAP_USER_DEFAULT_ATTRIBUTES'].items(): + if not isinstance(values, list): + values = [values] + formatted_values = [] + for value in values: + if isinstance(value, str): + value = format_with_attributes(value, self) + formatted_values.append(value) + self.ldap_object.setattr(name, formatted_values) + + ldap_add_hooks = ldap.Model.ldap_add_hooks + (add_default_attributes,) # Write-only property def password(self, value): -- GitLab