summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com>2011-03-07 15:15:21 +0000
committerJeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com>2011-03-07 15:15:21 +0000
commit7227b5d35ccb95582dc879adddb5a93e93bb9647 (patch)
treea147443eb026e83674bbefbd511c924284c907b2
parent8888a7120e0993eb162895ce677e9b6b0f9e1e61 (diff)
downloadpykolab-7227b5d35ccb95582dc879adddb5a93e93bb9647.tar.gz
Update the imap abstraction layer to be a little more efficient, and make sure we handle multi-domain cases correctly
-rw-r--r--pykolab/imap/__init__.py178
1 files changed, 128 insertions, 50 deletions
diff --git a/pykolab/imap/__init__.py b/pykolab/imap/__init__.py
index 342ad5b..bfee0f7 100644
--- a/pykolab/imap/__init__.py
+++ b/pykolab/imap/__init__.py
@@ -17,6 +17,8 @@
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
+import re
+
import pykolab.auth
from pykolab.conf import Conf
@@ -40,7 +42,13 @@ class IMAP(object):
if not self.imap:
if self.conf.get('kolab', 'imap_backend') == 'cyrus-imap':
import cyruslib
- self.imap = cyruslib.CYRUS(self.conf.get('cyrus-imap', 'uri'))
+ try:
+ self.imap = cyruslib.CYRUS(self.conf.get('cyrus-imap', 'uri'))
+ # TODO: Actually handle the error
+ except cyruslib.CYRUSError, e:
+ (code, error, message) = e
+ raise cyruslib.CYRUSError, e
+
if self.conf.debuglevel > 8:
self.imap.VERBOSE = 1
self.imap.login('cyrus-admin', 'VerySecret')
@@ -53,17 +61,25 @@ class IMAP(object):
del self.imap
self.imap = None
- def create_user_folders(self):
+ def create_user_folders(self, users, primary_domain, secondary_domains):
inbox_folders = []
- folders = self.list_user_folders()
+ folders = self.list_user_folders(primary_domain, secondary_domains)
# See if the folder belongs to any of the users
_match_attr = self.conf.get('cyrus-sasl', 'result_attribute')
- for user in self.auth.users():
- if user.has_key(_match_attr):
- inbox_folders.append(user[_match_attr])
+ #print domain
+
+ if not users:
+ users = self.auth.users(primary_domain)
+
+ for user in users:
+ if type(user) == dict:
+ if user.has_key(_match_attr):
+ inbox_folders.append(user[_match_attr])
+ elif type(user) == str:
+ inbox_folders.append(user)
for folder in inbox_folders:
additional_folders = None
@@ -71,19 +87,22 @@ class IMAP(object):
if folders.index(folder) > -1:
continue
else:
+ # TODO: Perhaps this block is moot
self.log.info(_("Creating new INBOX for user: %s") %(folder))
self.imap.cm("user/%s" %(folder))
self.imap.sq("user/%s" %(folder), 0)
-# additional_folders = self.conf.plugins.exec_hook("create_user_folders", args=(folder))
+ additional_folders = self.conf.plugins.exec_hook("create_user_folders", args=(folder))
except:
self.log.info(_("Creating new INBOX for user: %s") %(folder))
self.imap.cm("user/%s" %(folder))
self.imap.sq("user/%s" %(folder), 0)
-# additional_folders = self.conf.plugins.exec_hook("create_user_folders", args=(folder))
+ additional_folders = self.conf.plugins.exec_hook("create_user_folders", args=(folder))
if not additional_folders == None:
self.create_user_additional_folders(folder, additional_folders)
+ return inbox_folders
+
def create_user_additional_folders(self, folder, additional_folders):
for additional_folder in additional_folders.keys():
_add_folder = {}
@@ -110,39 +129,60 @@ class IMAP(object):
"%s" %(additional_folders[additional_folder]["annotations"][annotation])
)
- def set_user_folder_quota(self):
+ def set_user_folder_quota(self, users=[], primary_domain=None, secondary_domain=[], folders=[]):
self._connect()
_quota_attr = self.conf.get('cyrus-imap', 'quota_attribute')
_inbox_folder_attr = self.conf.get('cyrus-sasl', 'result_attribute')
- for user in self.auth.users():
+ default_quota = self.auth.domain_default_quota(primary_domain)
+
+ #print "Default quota", default_quota
+
+ if default_quota == "":
+ default_quota = 0
+
+ if len(users) == 0:
+ users = self.auth.list_users(domain)
+
+ for user in users:
quota = None
- if user.has_key(_quota_attr):
- if type(user[_quota_attr]) == list:
- quota = user[_quota_attr].pop(0)
- elif type(user[_quota_attr]) == str:
- quota = user[_quota_attr]
- else:
- quota = 0
+ if type(user) == dict:
+ if user.has_key(_quota_attr):
+ if type(user[_quota_attr]) == list:
+ quota = user[_quota_attr].pop(0)
+ elif type(user[_quota_attr]) == str:
+ quota = user[_quota_attr]
+ else:
+ quota = 0
- if not user.has_key(_inbox_folder_attr):
- continue
- else:
- if type(user[_inbox_folder_attr]) == list:
- folder = "user/%s" % user[_inbox_folder_attr].pop(0)
- elif type(user[_inbox_folder_attr]) == str:
- folder = "user/%s" % user[_inbox_folder_attr]
+ if not user.has_key(_inbox_folder_attr):
+ continue
+ else:
+ if type(user[_inbox_folder_attr]) == list:
+ folder = "user/%s" % user[_inbox_folder_attr].pop(0)
+ elif type(user[_inbox_folder_attr]) == str:
+ folder = "user/%s" % user[_inbox_folder_attr]
+ elif type(user) == str:
+ quota = self.auth.get_user_attribute(user, 'quota')
+ #print type(quota), quota
+ folder = "user/%s" %(user)
(used,current_quota) = self.imap.lq(folder)
- new_quota = self.conf.plugins.exec_hook("set_user_folder_quota", args=(used, current_quota, int(quota)))
+ new_quota = self.conf.plugins.exec_hook("set_user_folder_quota", args=(used, current_quota, int(quota), default_quota))
+
+ #print type(new_quota), new_quota
+
+ if new_quota == None:
+ continue
- if new_quota and not new_quota == int(quota):
- self.log.debug(_("Setting new quota for folder %s to %r") %(folder, new_quota), level=9)
- quota = new_quota
- self.auth.set_user_attribute(user['dn'], _quota_attr, new_quota)
+ if not int(new_quota) == int(quota):
+ self.log.debug(_("Setting new authz quota for folder %s to %r") %(folder, int(new_quota)), level=6)
+ quota = int(new_quota)
+ print user
+ self.auth.set_user_attribute(primary_domain, user, _quota_attr, new_quota)
self.log.debug(_("Quota for %s currently is %s") %(folder, current_quota), level=7)
@@ -150,22 +190,30 @@ class IMAP(object):
self.log.debug(_("Correcting quota for %s to %s (currently %s)") %(folder, quota, current_quota), level=7)
self.imap.sq(folder, quota)
- def expunge_user_folders(self):
- self._connect()
+ def expunge_user_folders(self, inbox_folders=None):
+ """
+ Delete folders that have no equivalent user qualifier in the list
+ of users passed to this function, ...
- inbox_folders = []
+ TODO: Explain the domain parameter, and actually get it to work
+ properly. This also relates to threading for multi-domain
+ deployments.
- folders = self.list_user_folders()
+ Parameters:
- # See if the folder belongs to any of the users
- _match_attr = self.conf.get('cyrus-sasl', 'result_attribute')
+ users
+ A list of users. Can be a list of user qualifiers, e.g.
+ [ 'user1', 'user2' ] or a list of user attribute
+ dictionaries, e.g. [ { 'user1': { 'attr': 'value' } } ]
- for user in self.auth.users():
- if user.has_key(_match_attr):
- if not user[_match_attr] in inbox_folders:
- inbox_folders.append(user[_match_attr])
+ primary_domain, secondary_domains
+ """
+ self._connect()
- inbox_folders = list(set(inbox_folders))
+ if inbox_folders == None:
+ inbox_folders = []
+
+ folders = self.list_user_folders()
for folder in folders:
self.log.debug(_("Checking folder: %s") %(folder), level=1)
@@ -179,29 +227,59 @@ class IMAP(object):
self.log.info(_("Folder has no corresponding user (2): %s") %(folder))
self.imap.dm("user/%s" %(folder))
- def list_user_folders(self):
+ def list_user_folders(self, primary_domain=None, secondary_domains=[]):
"""
List the INBOX folders in the IMAP backend. Returns a list of unique
base folder names.
"""
self._connect()
- _folders = self.imap.lm("user/*")
+ _folders = self.imap.lm("user/%")
+ # TODO: Replace the .* below with a regex representing acceptable DNS
+ # domain names.
+ domain_re = ".*\.?%s$"
+
+ acceptable_domain_name_res = []
+
+ if not primary_domain == None:
+ for domain in [ primary_domain ] + secondary_domains:
+ acceptable_domain_name_res.append(domain_re %(domain))
+
folders = []
for folder in _folders:
+ folder_name = None
if len(folder.split('@')) > 1:
- folder_name = "%s@%s" %(folder.split(self.imap.m.getsep())[1].split('@')[0],folder.split('@')[1])
+ #acceptable = False
+ #for domain_name_re in acceptable_domain_name_res:
+ #prog = re.compile(domain_name_re)
+ #if prog.match(folder.split('@')[1]):
+ #print "Acceptable indeed"
+ #acceptable = True
+ #if not acceptable:
+ #print "%s is not acceptable against %s yet using %s" %(folder.split('@')[1],folder,domain_name_re)
+
+ #if acceptable:
+ #folder_name = "%s@%s" %(folder.split(self.seperator)[1].split('@')[0],folder.split('@')[1])
+
+ folder_name = "%s@%s" %(folder.split(self.seperator)[1].split('@')[0],folder.split('@')[1])
else:
- folder_name = "%s" %(folder.split(self.imap.m.getsep())[1])
+ folder_name = "%s" %(folder.split(self.seperator)[1])
+
+ if not folder_name == None:
+ if not folder_name in folders:
+ folders.append(folder_name)
- if not folder_name in folders:
- folders.append(folder_name)
+ #print folders
return folders
- def synchronize(self, users=[]):
+ def synchronize(self, users=[], primary_domain=None, secondary_domains=[]):
self._connect()
- self.expunge_user_folders()
- self.create_user_folders()
- self.set_user_folder_quota()
+ self.users = users
+
+ folders = self.create_user_folders(users, primary_domain, secondary_domains)
+
+ self.set_user_folder_quota(users, primary_domain, secondary_domains, folders)
+
+ return folders