From 8904ab96309ae1319df5a947224687afa1963fbb Mon Sep 17 00:00:00 2001
From: Julian Rother <julianr@fsmpi.rwth-aachen.de>
Date: Sat, 20 Feb 2021 01:11:13 +0100
Subject: [PATCH] Added lazyconfig_* functions to configure LDAP models with
 app config

---
 .pylintrc           |  1 +
 uffd/lazyconfig.py  | 54 +++++++++++++++++++++++++++++++++++++++++++++
 uffd/mail/models.py |  7 +++---
 uffd/user/models.py |  9 ++++----
 4 files changed, 64 insertions(+), 7 deletions(-)
 create mode 100644 uffd/lazyconfig.py

diff --git a/.pylintrc b/.pylintrc
index c1e847af..a0c4d731 100644
--- a/.pylintrc
+++ b/.pylintrc
@@ -146,6 +146,7 @@ disable=missing-module-docstring,
         too-few-public-methods,
         method-hidden,
         bad-continuation,
+        too-many-ancestors,
 
 # Enable the message, report, category or checker with the given id(s). You can
 # either give multiple identifier separated by comma (,) or put this option
diff --git a/uffd/lazyconfig.py b/uffd/lazyconfig.py
new file mode 100644
index 00000000..d31df173
--- /dev/null
+++ b/uffd/lazyconfig.py
@@ -0,0 +1,54 @@
+from collections import UserString, UserList
+
+from flask import current_app
+
+class LazyConfigString(UserString):
+	def __init__(self, seq=None, key=None, default=None, error=True):
+		# pylint: disable=super-init-not-called
+		self.__seq = seq
+		self.__key = key
+		self.__default = default
+		self.__error = error
+
+	@property
+	def data(self):
+		if self.__seq is not None:
+			obj = self.__seq
+		elif self.__error:
+			obj = current_app.config[self.__key]
+		else:
+			obj = current_app.config.get(self.__key, self.__default)
+		return str(obj)
+
+	def __bytes__(self):
+		return self.data.encode()
+
+	def __get__(self, obj, owner=None):
+		return self.data
+
+def lazyconfig_str(key, **kwargs):
+	return LazyConfigString(None, key, **kwargs)
+
+class LazyConfigList(UserList):
+	def __init__(self, seq=None, key=None, default=None, error=True):
+		# pylint: disable=super-init-not-called
+		self.__seq = seq
+		self.__key = key
+		self.__default = default
+		self.__error = error
+
+	@property
+	def data(self):
+		if self.__seq is not None:
+			obj = self.__seq
+		elif self.__error:
+			obj = current_app.config[self.__key]
+		else:
+			obj = current_app.config.get(self.__key, self.__default)
+		return obj
+
+	def __get__(self, obj, owner=None):
+		return self.data
+
+def lazyconfig_list(key, **kwargs):
+	return LazyConfigList(None, key, **kwargs)
diff --git a/uffd/mail/models.py b/uffd/mail/models.py
index 8f15ea3d..26b7c82a 100644
--- a/uffd/mail/models.py
+++ b/uffd/mail/models.py
@@ -1,11 +1,12 @@
 from uffd.ldap import LDAPModel, LDAPAttribute
+from uffd.lazyconfig import lazyconfig_str, lazyconfig_list
 
 class Mail(LDAPModel):
-	ldap_base = 'ou=postfix,dc=example,dc=com'
+	ldap_base = lazyconfig_str('LDAP_BASE_MAIL')
 	ldap_dn_attribute = 'uid'
-	ldap_dn_base = 'ou=postfix,dc=example,dc=com'
+	ldap_dn_base = lazyconfig_str('LDAP_BASE_MAIL')
 	ldap_filter = '(objectClass=postfixVirtual)'
-	ldap_object_classes = ['top', 'postfixVirtual']
+	ldap_object_classes = lazyconfig_list('MAIL_LDAP_OBJECTCLASSES')
 
 	uid = LDAPAttribute('uid')
 	receivers = LDAPAttribute('mailacceptinggeneralid', multi=True)
diff --git a/uffd/user/models.py b/uffd/user/models.py
index d79a8bb7..88308dc1 100644
--- a/uffd/user/models.py
+++ b/uffd/user/models.py
@@ -5,6 +5,7 @@ from flask import current_app
 from ldap3.utils.hashed import hashed, HASHED_SALTED_SHA512
 
 from uffd.ldap import LDAPModel, LDAPAttribute, LDAPRelation
+from uffd.lazyconfig import lazyconfig_str, lazyconfig_list
 
 def get_next_uid():
 	max_uid = current_app.config['LDAP_USER_MIN_UID']
@@ -17,11 +18,11 @@ def get_next_uid():
 	return next_uid
 
 class User(LDAPModel):
-	ldap_base = 'ou=users,dc=example,dc=com'
+	ldap_base = lazyconfig_str('LDAP_BASE_USER')
 	ldap_dn_attribute = 'uid'
-	ldap_dn_base = 'ou=users,dc=example,dc=com'
+	ldap_dn_base = lazyconfig_str('LDAP_BASE_USER')
 	ldap_filter = '(objectClass=person)'
-	ldap_object_classes = ['top', 'inetOrgPerson', 'organizationalPerson', 'person', 'posixAccount']
+	ldap_object_classes = lazyconfig_list('LDAP_USER_OBJECTCLASSES')
 
 	uid = LDAPAttribute('uidNumber', default=get_next_uid)
 	loginname = LDAPAttribute('uid')
@@ -101,7 +102,7 @@ class User(LDAPModel):
 		return True
 
 class Group(LDAPModel):
-	ldap_base = 'ou=groups,dc=example,dc=com'
+	ldap_base = lazyconfig_str('LDAP_BASE_GROUPS')
 	ldap_filter = '(objectClass=groupOfUniqueNames)'
 
 	gid = LDAPAttribute('gidNumber')
-- 
GitLab