3 commits - pykolab/auth pykolab/constants.py.in pykolab/setup

Jeroen van Meeuwen vanmeeuwen at kolabsys.com
Wed Jul 25 09:48:29 CEST 2012


 pykolab/auth/ldap/__init__.py    |   75 +++++++++++++++++++++----------
 pykolab/auth/ldap/syncrepl.py    |   94 +++++++++++++++++++++++++++++++++++++++
 pykolab/constants.py.in          |   12 ++--
 pykolab/setup/setup_roundcube.py |    1 
 4 files changed, 152 insertions(+), 30 deletions(-)

New commits:
commit 0c11c87422c730ab5202e452141fffb142f0dfbe
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date:   Wed Jul 25 09:48:12 2012 +0200

    Make sure to pass along conf to the roundcube template as well

diff --git a/pykolab/setup/setup_roundcube.py b/pykolab/setup/setup_roundcube.py
index c6b3dd1..88b7d24 100644
--- a/pykolab/setup/setup_roundcube.py
+++ b/pykolab/setup/setup_roundcube.py
@@ -82,6 +82,7 @@ def execute(*args, **kw):
             'ldap_user_base_dn': conf.get('ldap', 'user_base_dn'),
             'ldap_user_filter': conf.get('ldap', 'user_filter'),
             'mysql_uri': 'mysqli://roundcube:%s@localhost/roundcube' % (mysql_roundcube_password),
+            'conf': conf
         }
 
 


commit 4581f966d76d7375ae2616618e692f38e655eea9
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date:   Wed Jul 25 09:47:50 2012 +0200

    Prioritize Syncrepl over paged search control / vlv

diff --git a/pykolab/constants.py.in b/pykolab/constants.py.in
index 85f5c38..ccb347a 100644
--- a/pykolab/constants.py.in
+++ b/pykolab/constants.py.in
@@ -98,20 +98,20 @@ SUPPORTED_LDAP_CONTROLS = {
                 'func': '_persistent_search'
             },
         1: {
+                'desc': 'OpenLDAP Syncrepl (RFC4533)',
+                'oid': '1.3.6.1.4.1.4203.1.9.1.1',
+                'func': '_sync_repl'
+            },
+        2: {
                 'desc': 'Simple Paged Results Control',
                 'oid': '1.2.840.113556.1.4.319',
                 'func': '_paged_search'
             },
-        2: {
+        3: {
                 'desc': 'Virtual List View Control',
                 'oid': '2.16.840.1.113730.3.4.9',
                 'func': '_vlv_search'
             },
-        3: {
-                'desc': 'OpenLDAP Syncrepl (RFC4533)',
-                'oid': '1.3.6.1.4.1.4203.1.9.1.1',
-                'func': '_sync_repl'
-            }
     }
 
 #SUPPORTED_LDAP_CONTROLS = {


commit 8f5dacadddb345932df7b3f3c0a7b2511ae71268
Author: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen at kolabsys.com>
Date:   Wed Jul 25 09:47:12 2012 +0200

    Add syncrepl compatibility for OpenLDAP

diff --git a/pykolab/auth/ldap/__init__.py b/pykolab/auth/ldap/__init__.py
index 71f16ce..8d82d6a 100644
--- a/pykolab/auth/ldap/__init__.py
+++ b/pykolab/auth/ldap/__init__.py
@@ -782,8 +782,12 @@ class LDAP(pykolab.base.Base):
                     modlist.append((ldap.MOD_REPLACE, attribute, attrs[attribute]))
 
         dn = entry_dn
+
         if len(modlist) > 0:
-            self.ldap.modify_s(dn, modlist)
+            try:
+                self.ldap.modify_s(dn, modlist)
+            except:
+                log.error(_("Could not update dn %r") % (dn))
 
     def synchronize(self):
         """
@@ -911,6 +915,9 @@ class LDAP(pykolab.base.Base):
         """
         pass
 
+    def _change_add_None(self, *args, **kw):
+        pass
+
     def _change_add_resource(self, entry, change):
         """
             An entry of type resource was added.
@@ -1657,8 +1664,12 @@ class LDAP(pykolab.base.Base):
                 # This entry was in the start result set
                 eval("self._change_none_%s(entry, change_dict)" % (entry['type']))
             else:
-                change = psearch.CHANGE_TYPES_STR[change_dict['change_type']]
-                change = change.lower()
+                if isinstance(change_dict['change_type'], int):
+                    change = psearch.CHANGE_TYPES_STR[change_dict['change_type']]
+                    change = change.lower()
+                else:
+                    change = change_dict['change_type']
+
                 eval(
                         "self._change_%s_%s(entry, change_dict)" % (
                                 change,
@@ -1667,32 +1678,44 @@ class LDAP(pykolab.base.Base):
                     )
 
         # Typical for Paged Results Control
-        elif kw.has_key('user') and isinstance(kw['user'], list):
-            for entry_dn,entry_attrs in kw['user']:
+        elif kw.has_key('entry') and isinstance(kw['entry'], list):
+            for entry_dn,entry_attrs in kw['entry']:
                 entry = { 'dn': entry_dn }
+                entry_attrs = utils.normalize(entry_attrs)
                 for attr in entry_attrs.keys():
                     entry[attr.lower()] = entry_attrs[attr]
 
                 unique_attr = self.config_get('unique_attribute')
                 entry['id'] = entry[unique_attr]
 
-                result_attribute = conf.get('cyrus-sasl', 'result_attribute')
-
-                rcpt_addrs = self.recipient_policy(entry)
-
-                for key in rcpt_addrs.keys():
-                    entry[key] = rcpt_addrs[key]
+                try:
+                    entry['type'] = self._entry_type(entry)
+                except:
+                    entry['type'] = "unknown"
 
-                cache.get_entry(self.domain, entry)
+                log.debug(_("Entry type: %s") % (entry['type']), level=8)
 
-                self.imap.connect(domain=self.domain)
+                eval("self._change_none_%s(entry, None)" % (entry['type']))
 
-                if not self.imap.user_mailbox_exists(entry[result_attribute]):
-                    folder = self.imap.user_mailbox_create(
-                            entry[result_attribute]
-                        )
-
-                    server = self.imap.user_mailbox_server(folder)
+#                result_attribute = conf.get('cyrus-sasl', 'result_attribute')
+#
+#                rcpt_addrs = self.recipient_policy(entry)
+#
+#                log.debug(_("Recipient Addresses: %r") % (rcpt_addrs), level=9)
+#
+#                for key in rcpt_addrs.keys():
+#                    entry[key] = rcpt_addrs[key]
+#
+#                cache.get_entry(self.domain, entry)
+#
+#                self.imap.connect(domain=self.domain)
+#
+#                if not self.imap.user_mailbox_exists(entry[result_attribute]):
+#                    folder = self.imap.user_mailbox_create(
+#                            entry[result_attribute]
+#                        )
+#
+#                    server = self.imap.user_mailbox_server(folder)
 
     def _unbind(self):
         """
@@ -1848,7 +1871,7 @@ class LDAP(pykolab.base.Base):
                 break
 
             if callback:
-                callback(user=_result_data)
+                callback(entry=_result_data)
 
             _results.extend(_result_data)
             if (pages % 2) == 0:
@@ -1911,20 +1934,24 @@ class LDAP(pykolab.base.Base):
             secondary_domains=[]
         ):
 
+        import ldapurl
         import syncrepl
 
+        ldap_url = ldapurl.LDAPUrl(self.config_get('ldap_uri'))
+
         ldap_sync_conn = syncrepl.DNSync(
-                '/var/lib/pykolab/syncrepl.db',
+                '/var/lib/kolab/syncrepl_%s.db' % (self.domain),
                 ldap_url.initializeUrl(),
-                trace_level=ldapmodule_trace_level,
-                trace_file=ldapmodule_trace_file
+                trace_level=2,
+                callback=self._synchronize_callback
             )
 
         msgid = ldap_sync_conn.syncrepl_search(
                 base_dn,
                 scope,
                 mode='refreshAndPersist',
-                filterstr=filterstr
+                filterstr=filterstr,
+                attrlist=attrlist,
             )
 
         try:
diff --git a/pykolab/auth/ldap/syncrepl.py b/pykolab/auth/ldap/syncrepl.py
new file mode 100644
index 0000000..e02e086
--- /dev/null
+++ b/pykolab/auth/ldap/syncrepl.py
@@ -0,0 +1,94 @@
+#!/usr/bin/python
+
+import anydbm
+import ldap
+import ldap.syncrepl
+import ldapurl
+
+from pykolab import utils
+
+class DNSync(ldap.ldapobject.LDAPObject,ldap.syncrepl.SyncreplConsumer):
+
+    callback = None
+
+    def __init__(self, filename, *args, **kwargs):
+        if kwargs.has_key('callback'):
+            self.callback = kwargs['callback']
+            del kwargs['callback']
+
+        ldap.ldapobject.LDAPObject.__init__(self, *args, **kwargs)
+        self.__db = anydbm.open(filename, 'c', 0640)
+        self.__presentUUIDs = {}
+
+    def syncrepl_set_cookie(self,cookie):
+        self.__db['cookie'] = cookie
+
+    def syncrepl_get_cookie(self):
+        if 'cookie' in self.__db:
+            return self.__db['cookie']
+
+    def syncrepl_delete(self, uuids):
+        for uuid in uuids:
+            dn = self.__db[uuid]
+
+            if not self.callback == None:
+                self.callback(
+                        change_type='delete',
+                        previous_dn=None,
+                        change_number=None,
+                        dn=dn,
+                        entry={}
+                    )
+
+            del self.__db[uuid]
+
+    def syncrepl_present(self, uuids, refreshDeletes=False):
+        if uuids is None:
+            if refreshDeletes is False:
+                nonpresent = []
+                for uuid in self.__db.keys():
+                    if uuid == 'cookie': continue
+                    if uuid in self.__presentUUIDs: continue
+                    nonpresent.append(uuid)
+                self.syncrepl_delete(nonpresent)
+            self.__presentUUIDs = {}
+        else:
+            for uuid in uuids:
+                self.__presentUUIDs[uuid] = True
+
+    def syncrepl_entry(self, dn, attrs, uuid):
+        attrs = utils.normalize(attrs)
+
+        if uuid in self.__db:
+            odn = self.__db[uuid]
+            if odn != dn:
+                if not self.callback == None:
+                    self.callback(
+                            change_type='moddn',
+                            previous_dn=odn,
+                            change_number=None,
+                            dn=dn,
+                            entry=attrs
+                        )
+
+            else:
+                if not self.callback == None:
+                    self.callback(
+                            change_type='modify',
+                            previous_dn=None,
+                            change_number=None,
+                            dn=self.__db[uuid],
+                            entry=attrs
+                        )
+
+        else:
+            if not self.callback == None:
+                self.callback(
+                        change_type='add',
+                        previous_dn=None,
+                        change_number=None,
+                        dn=dn,
+                        entry=attrs
+                    )
+
+        self.__db[uuid] = dn





More information about the commits mailing list