diff --git a/pykolab/auth/__init__.py b/pykolab/auth/__init__.py --- a/pykolab/auth/__init__.py +++ b/pykolab/auth/__init__.py @@ -179,6 +179,20 @@ 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 --- a/pykolab/auth/ldap/__init__.py +++ b/pykolab/auth/ldap/__init__.py @@ -461,6 +461,78 @@ 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 --- a/pykolab/cli/cmd_sync_mailhost_attrs.py +++ b/pykolab/cli/cmd_sync_mailhost_attrs.py @@ -95,14 +95,18 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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