From f767a2b68adf522a841c00e93dc3a08925368a55 Mon Sep 17 00:00:00 2001
From: Julian Rother <julian@jrother.eu>
Date: Sat, 25 Sep 2021 00:39:24 +0200
Subject: [PATCH] Improve filter_present pre-evaluation to reduces API calls

---
 server.py | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/server.py b/server.py
index 670351b..502d168 100644
--- a/server.py
+++ b/server.py
@@ -38,6 +38,7 @@ class UserDirectory(SimpleFilterMixin, BaseDirectory):
 		self.group_dn_base = DN('ou=groups') + DN(dn_base)
 		self.structuralobjectclass = b'inetorgperson'
 		self.objectclasses = [b'top', b'inetorgperson', b'organizationalperson', b'person', b'posixaccount']
+		self.attributes = ['structuralobjectclass', 'objectclass', 'cn', 'displayname', 'givenname', 'homedirectory', 'mail', 'sn', 'uid', 'uidnumber', 'memberof']
 
 	def generate_result(self, user):
 		attributes = CaseInsensitiveDict(
@@ -91,6 +92,11 @@ class UserDirectory(SimpleFilterMixin, BaseDirectory):
 			value = str(DN.from_str(value.decode())).encode()
 		return super().filter_equal(attribute, value)
 
+	def filter_present(self, attribute):
+		if attribute not in self.attributes:
+			return False
+		return super().filter_present(attribute)
+
 class GroupDirectory(SimpleFilterMixin, BaseDirectory):
 	def __init__(self, api, dn_base):
 		self.api = api
@@ -99,6 +105,7 @@ class GroupDirectory(SimpleFilterMixin, BaseDirectory):
 		self.user_dn_base = DN('ou=users') + DN(dn_base)
 		self.structuralobjectclass = b'groupOfUniqueNames'
 		self.objectclasses = [b'top', b'groupOfUniqueNames', b'posixGroup']
+		self.attributes = ['structuralobjectclass', 'objectclass', 'cn', 'description', 'gidnumber', 'uniquemember']
 
 	def generate_result(self, group):
 		attributes = CaseInsensitiveDict(
@@ -145,6 +152,11 @@ class GroupDirectory(SimpleFilterMixin, BaseDirectory):
 			value = str(DN.from_str(value.decode())).encode()
 		return super().filter_equal(attribute, value)
 
+	def filter_present(self, attribute):
+		if attribute not in self.attributes:
+			return False
+		return super().filter_present(attribute)
+
 class MailDirectory(SimpleFilterMixin, BaseDirectory):
 	def __init__(self, api, dn_base):
 		self.api = api
@@ -152,6 +164,7 @@ class MailDirectory(SimpleFilterMixin, BaseDirectory):
 		self.dn_base = DN('ou=postfix') + DN(dn_base)
 		self.structuralobjectclass = b'postfixVirtual'
 		self.objectclasses = [b'top', b'postfixVirtual']
+		self.attributes = ['structuralobjectclass', 'objectclass', 'uid', 'mailacceptinggeneralid', 'maildrop']
 
 	def generate_result(self, mail):
 		attributes = CaseInsensitiveDict(
@@ -190,6 +203,11 @@ class MailDirectory(SimpleFilterMixin, BaseDirectory):
 			if eval_ldap_filter(obj, expr):
 				yield dn, obj
 
+	def filter_present(self, attribute):
+		if attribute not in self.attributes:
+			return False
+		return super().filter_present(attribute)
+
 class RequestHandler(SimpleLDAPRequestHandler):
 	subschema = RFC2307BIS_SUBSCHEMA
 
-- 
GitLab