return conn
- def _query(self, query, attrlist=None, limit=0):
+ def _query(self, query, attrlist=None, limit=0, search_base=None, scope=None):
logging.debug("Performing LDAP query: %s" % query)
t = time.time()
- results = self.ldap.search_ext_s(self.search_base, ldap.SCOPE_SUBTREE,
- query, attrlist=attrlist, sizelimit=limit)
+ results = self.ldap.search_ext_s(search_base or self.search_base,
+ scope or ldap.SCOPE_SUBTREE, query, attrlist=attrlist, sizelimit=limit)
# Log time it took to perform the query
logging.debug("Query took %.2fms" % ((time.time() - t) * 1000.0))
return results
def _search(self, query, attrlist=None, limit=0):
- for dn, attrs in self._query(query, attrlist=attrlist, limit=limit):
- yield Account(self.backend, dn, attrs)
+ dns = self._search_dns(query, limit=limit)
+
+ return self._get_accounts_from_dns(dns)
+
+ def _search_dns(self, query, limit=0):
+ # Query cache
+ dns = self.memcache.get("accounts:search:%s" % query)
+ if dns is None:
+ # Return DNs only for this search query
+ dns = []
+ for dn, attrs in self._query(query, attrlist=["dn"], limit=limit):
+ dns.append(dn)
+
+ # Cache for 10 min
+ self.memcache.set("accounts:search:%s" % query, dns, 600)
+
+ return dns
+
+ def _get_accounts_from_dns(self, dns):
+ for dn in dns:
+ yield self._get_account_from_dn(dn)
+
+ def _get_account_from_dn(self, dn):
+ attrs = self.memcache.get("accounts:%s:attrs" % dn)
+ if attrs is None:
+ attrs = self._get_attrs(dn)
+ assert attrs, dn
+
+ # Cache all attributes for 5 min
+ self.memcache.set("accounts:%s:attrs" % dn, attrs, 300)
+
+ return Account(self.backend, dn, attrs)
+
+ def _get_attrs(self, dn):
+ """
+ Fetches all attributes for the given distinguished name
+ """
+ results = self._query("(objectClass=*)", search_base=dn, limit=1)
+
+ for dn, attrs in results:
+ return attrs
def search(self, query):
# Search for exact matches
def get_by_mail(self, mail):
return self._search_one("(&(objectClass=inetOrgPerson)(mail=%s))" % mail)
- find = get_by_uid
-
def find_account(self, s):
account = self.get_by_uid(s)
if account:
# Run modify operation
self.ldap.modify_s(self.dn, modlist)
+ # Delete cached attributes
+ self.memcache.delete("accounts:%s:attrs")
+
def _set(self, key, values):
current = self._get(key)