summaryrefslogtreecommitdiffstats
path: root/pykolab
diff options
context:
space:
mode:
authorAleksander Machniak <machniak@kolabsys.com>2016-05-18 09:40:17 +0200
committerJeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com>2016-05-18 09:40:17 +0200
commit67e65cd5271658bd106a42f427904cf0374c8cd2 (patch)
treec1fc2bdfbfebc5c6ba2b3401d130a2c7af525140 /pykolab
parente7bbf664076622b2a4dc51d492298cd5d984f8fb (diff)
downloadpykolab-67e65cd5271658bd106a42f427904cf0374c8cd2.tar.gz
Determine shared folder resource using kolabTargetFolder attribute (#5337)
Summary: It's supposed to fix #5337. WARNING: Untested!!!!!!!! Reviewers: #pykolab_developers, vanmeeuwen Reviewed By: #pykolab_developers, vanmeeuwen Subscribers: vanmeeuwen Differential Revision: https://git.kolab.org/D130
Diffstat (limited to 'pykolab')
-rw-r--r--pykolab/auth/__init__.py14
-rw-r--r--pykolab/auth/ldap/__init__.py72
-rw-r--r--pykolab/cli/cmd_sync_mailhost_attrs.py37
3 files changed, 112 insertions, 11 deletions
diff --git a/pykolab/auth/__init__.py b/pykolab/auth/__init__.py
index ed5865f..2ffd8d3 100644
--- a/pykolab/auth/__init__.py
+++ b/pykolab/auth/__init__.py
@@ -179,6 +179,20 @@ class Auth(pykolab.base.Base):
del self._auth
self._auth = None
+ def find_folder_resource(self, folder):
+ """
+ Find one or more resources corresponding to the shared folder name.
+ """
+ if not self._auth or self._auth == None:
+ self.connect()
+
+ result = self._auth.find_folder_resource(folder)
+
+ if isinstance(result, list) and len(result) == 1:
+ return result[0]
+ else:
+ return result
+
def find_recipient(self, address, domain=None):
"""
Find one or more entries corresponding to the recipient address.
diff --git a/pykolab/auth/ldap/__init__.py b/pykolab/auth/ldap/__init__.py
index d40a118..c2f6df7 100644
--- a/pykolab/auth/ldap/__init__.py
+++ b/pykolab/auth/ldap/__init__.py
@@ -461,6 +461,78 @@ class LDAP(pykolab.base.Base):
return delegators
+ def find_folder_resource(self, folder="*", exclude_entry_id=None):
+ """
+ Given a shared folder name or list of folder names, find one or more valid
+ resources.
+
+ Specify an additional entry_id to exclude to exclude matches.
+ """
+
+ self._bind()
+
+ if not exclude_entry_id == None:
+ __filter_prefix = "(&"
+ __filter_suffix = "(!(%s=%s)))" % (
+ self.config_get('unique_attribute'),
+ exclude_entry_id
+ )
+ else:
+ __filter_prefix = ""
+ __filter_suffix = ""
+
+ resource_filter = self.config_get('resource_filter')
+ if not resource_filter == None:
+ __filter_prefix = "(&%s" % resource_filter
+ __filter_suffix = ")"
+
+ recipient_address_attrs = self.config_get_list("mail_attributes")
+
+ result_attributes = recipient_address_attrs
+ result_attributes.append(self.config_get('unique_attribute'))
+ result_attributes.append('kolabTargetFolder')
+
+ _filter = "(|"
+
+ if isinstance(folder, basestring):
+ _filter += "(kolabTargetFolder=%s)" % (folder)
+ else:
+ for _folder in folder:
+ _filter += "(kolabTargetFolder=%s)" % (_folder)
+
+ _filter += ")"
+
+ _filter = "%s%s%s" % (__filter_prefix,_filter,__filter_suffix)
+
+ log.debug(_("Finding resource with filter %r") % (_filter), level=8)
+
+ if len(_filter) <= 6:
+ return None
+
+ config_base_dn = self.config_get('resource_base_dn')
+ ldap_base_dn = self._kolab_domain_root_dn(self.domain)
+
+ if not ldap_base_dn == None and not ldap_base_dn == config_base_dn:
+ resource_base_dn = ldap_base_dn
+ else:
+ resource_base_dn = config_base_dn
+
+ _results = self.ldap.search_s(
+ resource_base_dn,
+ scope=ldap.SCOPE_SUBTREE,
+ filterstr=_filter,
+ attrlist=result_attributes,
+ attrsonly=True
+ )
+
+ _entry_dns = []
+
+ for _result in _results:
+ (_entry_id, _entry_attrs) = _result
+ _entry_dns.append(_entry_id)
+
+ return _entry_dns
+
def find_recipient(self, address="*", exclude_entry_id=None):
"""
Given an address string or list of addresses, find one or more valid
diff --git a/pykolab/cli/cmd_sync_mailhost_attrs.py b/pykolab/cli/cmd_sync_mailhost_attrs.py
index 131157e..fe7f6b2 100644
--- a/pykolab/cli/cmd_sync_mailhost_attrs.py
+++ b/pykolab/cli/cmd_sync_mailhost_attrs.py
@@ -95,14 +95,18 @@ def execute(*args, **kw):
folders.extend(imap.lm('user/%%@%s' % (domain)))
for folder in folders:
+ r_folder = folder
+ if not folder.startswith('shared/'):
+ r_folder = '/'.join(folder.split('/')[1:])
+
if conf.delete:
if conf.dry_run:
- if not folder.split('/')[0] == 'shared':
- log.warning(_("No recipients for '%s' (would have deleted the mailbox if not for --dry-run)!") % ('/'.join(folder.split('/')[1:])))
+ if not folder.startswith('shared/'):
+ log.warning(_("No recipients for '%s' (would have deleted the mailbox if not for --dry-run)!") % (r_folder))
else:
continue
else:
- if not '/'.join(folder.split('/')[0]) == 'shared':
+ if not folder.startswith('shared/'):
log.info(_("Deleting mailbox '%s' because it has no recipients") % (folder))
try:
imap.dm(folder)
@@ -111,7 +115,7 @@ def execute(*args, **kw):
else:
log.info(_("Not automatically deleting shared folder '%s'") % (folder))
else:
- log.warning(_("No recipients for '%s' (use --delete to delete)!") % ('/'.join(folder.split('/')[1:])))
+ log.warning(_("No recipients for '%s' (use --delete to delete)!") % (r_folder))
for primary in list(set(domains.values())):
secondaries = [x for x in domains.keys() if domains[x] == primary]
@@ -130,20 +134,27 @@ def execute(*args, **kw):
for folder in folders:
server = imap.user_mailbox_server(folder)
- recipient = auth.find_recipient('/'.join(folder.split('/')[1:]))
+ r_folder = folder
+
+ if folder.startswith('shared/'):
+ recipient = auth.find_folder_resource(folder)
+ else:
+ r_folder = '/'.join(folder.split('/')[1:])
+ recipient = auth.find_recipient(r_folder)
+
if (isinstance(recipient, list)):
if len(recipient) > 1:
- log.warning(_("Multiple recipients for '%s'!") % ('/'.join(folder.split('/')[1:])))
+ log.warning(_("Multiple recipients for '%s'!") % (r_folder))
continue
elif len(recipient) == 0:
if conf.delete:
if conf.dry_run:
- if not folder.split('/')[0] == 'shared':
- log.warning(_("No recipients for '%s' (would have deleted the mailbox if not for --dry-run)!") % ('/'.join(folder.split('/')[1:])))
+ if not folder.startswith('shared/'):
+ log.warning(_("No recipients for '%s' (would have deleted the mailbox if not for --dry-run)!") % (r_folder))
else:
continue
else:
- if not '/'.join(folder.split('/')[0]) == 'shared':
+ if not folder.startswith('shared/'):
log.info(_("Deleting mailbox '%s' because it has no recipients") % (folder))
try:
imap.dm(folder)
@@ -152,7 +163,7 @@ def execute(*args, **kw):
else:
log.info(_("Not automatically deleting shared folder '%s'") % (folder))
else:
- log.warning(_("No recipients for '%s' (use --delete to delete)!") % ('/'.join(folder.split('/')[1:])))
+ log.warning(_("No recipients for '%s' (use --delete to delete)!") % (r_folder))
continue
else:
@@ -173,6 +184,10 @@ def execute(*args, **kw):
for folder in folders:
server = imap.user_mailbox_server(folder)
- recipient = auth.find_recipient('/'.join(folder.split('/')[1:]))
+
+ if folder.startswith('shared/'):
+ recipient = auth.find_folder_resource(folder)
+ else:
+ recipient = auth.find_recipient('/'.join(folder.split('/')[1:]))
print folder, server, recipient