Projects
Kolab:16:Enterprise
pykolab
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 21
View file
pykolab.spec
Changed
@@ -29,7 +29,7 @@ Summary: Kolab Groupware Solution Name: pykolab -Version: 0.8.7 +Version: 0.8.8 Release: 1%{?dist} License: GPLv3+ Group: Applications/System @@ -71,7 +71,11 @@ BuildRequires: python-kolab BuildRequires: python-kolabformat BuildRequires: python-ldap +%if 0%{?fedora} > 24 +BuildRequires: python2-nose +%else BuildRequires: python-nose +%endif BuildRequires: python-pep8 BuildRequires: python-pyasn1 BuildRequires: python-pyasn1-modules @@ -580,6 +584,9 @@ %attr(0700,%{kolab_user},%{kolab_group}) %dir %{_var}/spool/pykolab/wallace %changelog +* Thu Mar 8 2018 Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com> - 0.8.8-1 +- Release of version 0.8.8 + * Tue Dec 13 2016 Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com> - 0.8.7-1 - Release of version 0.8.7
View file
debian.changelog
Changed
@@ -1,8 +1,14 @@ +pykolab (0.8.8-0~kolab1) unstable; urgency=low + + * Upstream release of version 0.8.8 + + -- Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com> Thu, 8 Mar 2018 01:49:00 +0100 + pykolab (0.8.7-0~kolab2) unstable; urgency=low - * Ubuntu Xenial: pykolab requires now python-pymysql because /usr/lib/postfix/kolab_smtp_access_policy needs module pymysql + * pykolab requires now python-pymysql because /usr/lib/postfix/kolab_smtp_access_policy needs module pymysql on Ubuntu Xenial - -- Timotheus Pokorra <tp@tbits.net> Tue, 30 May 2017 01:49:00 +0100 + -- Timotheus Pokorra <tp@tbits.net> Thu, 25 May 2017 01:49:00 +0100 pykolab (0.8.7-0~kolab1) unstable; urgency=low
View file
pykolab-0.8.7.tar.gz/configure.ac -> pykolab-0.8.8.tar.gz/configure.ac
Changed
@@ -1,4 +1,4 @@ -AC_INIT(pykolab, 0.8.7) +AC_INIT(pykolab, 0.8.8) AC_SUBST(RELEASE, 1) AC_CONFIG_SRCDIR(pykolab/constants.py.in)
View file
pykolab-0.8.7.tar.gz/pykolab/auth/ldap/__init__.py -> pykolab-0.8.8.tar.gz/pykolab/auth/ldap/__init__.py
Changed
@@ -232,6 +232,24 @@ return False + except ldap.NO_SUCH_OBJECT: + log.error( + _("Invalid DN, username and/or password for '%s'.") % ( + bind_dn + ) + ) + + return False + + except ldap.INVALID_CREDENTIALS: + log.error( + _("Invalid DN, username and/or password for '%s'.") % ( + bind_dn + ) + ) + + return False + except Exception, errmsg: log.error(_("Exception occurred: %r") % (errmsg)) log.error(_("%s") % (traceback.format_exc())) @@ -246,6 +264,9 @@ level=8 ) + # Remove referrals + _result_data = _e for _e in _result_data if _e0 is not None + if len(_result_data) == 1: (entry_dn, entry_attrs) = _result_data0 @@ -1432,8 +1453,13 @@ bind_pw = self.config_get('service_bind_pw') if bind_dn is not None: - log.debug(_("Binding with bind_dn: %s and password: %s") - % (bind_dn, '*' * len(bind_pw))) + log.debug( + _("Binding with bind_dn: %s and password: %s") % ( + bind_dn, + '*' * len(bind_pw) + ), + level=8 + ) # TODO: Binding errors control try: @@ -1449,8 +1475,21 @@ return False + except ldap.NO_SUCH_OBJECT: + log.error( + _("Invalid DN, username and/or password for '%s'.") % ( + bind_dn + ) + ) + + return False + except ldap.INVALID_CREDENTIALS: - log.error(_("Invalid DN, username and/or password.")) + log.error( + _("Invalid DN, username and/or password for '%s'.") % ( + bind_dn + ) + ) return False @@ -1474,7 +1513,12 @@ log.error(_("%s") % (traceback.format_exc())) return False except ldap.INVALID_CREDENTIALS: - log.error(_("Invalid DN, username and/or password.")) + log.error( + _("Invalid DN, username and/or password for '%s'.") % ( + bind_dn + ) + ) + return False else: log.debug(_("bind_priv() called but already bound"), level=8) @@ -2036,7 +2080,7 @@ ) if not self.imap.has_folder(imap_mailbox): - self.imap_user_mailbox_create( + self.imap.user_mailbox_create( entryresult_attribute )
View file
pykolab-0.8.7.tar.gz/pykolab/imap/__init__.py -> pykolab-0.8.8.tar.gz/pykolab/imap/__init__.py
Changed
@@ -33,6 +33,7 @@ log = pykolab.getLogger('pykolab.imap') conf = pykolab.getConf() + class IMAP(object): def __init__(self): # Pool of named IMAP connections, by hostname @@ -44,12 +45,15 @@ def cleanup_acls(self, aci_subject): lm_suffix = "" - log.info(_("Cleaning up ACL entries for %s across all folders") % (aci_subject)) + log.info( + _("Cleaning up ACL entries for %s across all folders") % ( + aci_subject + ) + ) if len(aci_subject.split('@')) > 1: lm_suffix = "@%s" % (aci_subject.split('@')1) - shared_folders = self.imap.lm( "shared/*%s" % (lm_suffix) ) @@ -72,17 +76,38 @@ # ... loop through them and ... for folder in folders: - # ... list the ACL entries - acls = self.imap.lam(folder) - - # For each ACL entry, see if we think it is a current, valid entry - for acl_entry in acls.keys(): - # If the key 'acl_entry' does not exist in the dictionary of valid - # ACL entries, this ACL entry has got to go. - if acl_entry == aci_subject: - # Set the ACL to '' (effectively deleting the ACL entry) - log.debug(_("Removing acl %r for subject %r from folder %r") % (aclsacl_entry,acl_entry,folder), level=8) - self.set_acl(folder, acl_entry, '') + # ... list the ACL entries -- but only if the folder still exists + if self.imap.has_folder(folder): + acls = self.imap.lam(folder) + + # For each ACL entry, see if we think it is a current, valid + # entry + for acl_entry in acls.keys(): + # If the key 'acl_entry' does not exist in the dictionary + # of valid ACL entries, this ACL entry has got to go. + if acl_entry == aci_subject: + # Set the ACL to '' (effectively deleting the ACL + # entry) + log.debug( + _( + "Removing acl %r for subject %r from folder %r" + ) % ( + aclsacl_entry, + acl_entry, + folder + ), + level=8 + ) + + self.set_acl(folder, acl_entry, '') + else: + log.debug( + _("Folder %r disappeared (ACL cleanup for %r") % ( + folder, + aci_subject + ), + level=8 + ) def connect(self, uri=None, server=None, domain=None, login=True): """ @@ -508,36 +533,12 @@ folder_name = "user%s%s" % (self.get_separator(), mailbox_base_name) log.info(_("Creating new mailbox for user %s") %(mailbox_base_name)) - max_tries = 10 - success = False - while not success and max_tries > 0: - success = self.create_folder(folder_name, server) - if not success: - self.disconnect() - max_tries -= 1 - time.sleep(1) - self.connect() + success = self._create_folder_waiting(folder_name, server) if not success: log.error(_("Could not create the mailbox for user %s, aborting." % (mailbox_base_name))) return False - # In a Cyrus IMAP Murder topology, wait for the murder to have settled - if self.imap_murder(): - self.disconnect() - self.connect() - - created = False - last_log = time.time() - while not created: - created = self.has_folder(folder_name) - if not created: - if time.time() - last_log > 5: - log.info(_("Waiting for the Cyrus IMAP Murder to settle...")) - last_log = time.time() - - time.sleep(0.5) - _additional_folders = None if not hasattr(self, 'domain'): @@ -628,7 +629,6 @@ last_log = time.time() while not success: try: - self.disconnect() self.connect(login=False, server=server) self.login_plain(admin_login, admin_password, user) @@ -654,28 +654,11 @@ log.error(_("Correcting additional folder name from %r to %r") % (folder_name, "%s%s" % (personal, folder_name))) folder_name = "%s%s" % (personal, folder_name) - try: - self.create_folder(folder_name) - created = False - last_log = time.time() - while not created: - created = self.has_folder(folder_name) - if not created: - if time.time() - last_log > 5: - log.info(_("Waiting for the Cyrus IMAP Murder to settle...")) - if time.time() - last_log > 30: - log.warning(_("Waited for 30 seconds, going to reconnect")) - self.disconnect() - self.connec() - last_log = time.time() + success = self._create_folder_waiting(folder_name) - time.sleep(0.5) - except: - log.warning(_("Mailbox already exists: %s") % (folder_name)) - if conf.debuglevel > 8: - import traceback - traceback.print_exc() + if not success: + log.warning(_("Failed to create folder: %s") % (folder_name)) continue if additional_foldersadditional_folder.has_key("annotations"): @@ -782,6 +765,50 @@ except: log.error(_("Could not rename %s to reside on partition %s") % (folder_name, partition)) + def _create_folder_waiting(self, folder_name, server=None): + """ + Create a folder and wait to make sure it exists + """ + + created = False + + try: + max_tries = 10 + while not created and max_tries > 0: + created = self.create_folder(folder_name, server) + if not created: + self.disconnect() + max_tries -= 1 + time.sleep(1) + self.connect() + + # In a Cyrus IMAP Murder topology, wait for the murder to have settled + if created and self.imap_murder(): + success = False + last_log = time.time() + reconnect_counter = 0 + while not success: + success = self.has_folder(folder_name) + if not success: + if time.time() - last_log > 5: + reconnect_counter += 1 + log.info(_("Waiting for the Cyrus IMAP Murder to settle...")) + if reconnect_counter == 6: + log.warning(_("Waited for 15 seconds, going to reconnect")) + reconnect_counter = 0 + self.disconnect() + self.connect() + + last_log = time.time() + + time.sleep(0.5) + except: + if conf.debuglevel > 8: + import traceback + traceback.print_exc() + + return created + def user_mailbox_delete(self, mailbox_base_name): """ Delete a user mailbox.
View file
pykolab-0.8.7.tar.gz/pykolab/imap/cyrus.py -> pykolab-0.8.8.tar.gz/pykolab/imap/cyrus.py
Changed
@@ -173,8 +173,8 @@ _mailfolder = self.parse_mailfolder(mailfolder) - prefix = _mailfolder'path_parts'.pop(0) - mbox = _mailfolder'path_parts'.pop(0) + prefix = _mailfolder'path_parts'0 + mbox = _mailfolder'path_parts'1 if _mailfolder'domain' is not None: mailfolder = "%s%s%s@%s" % ( prefix, @@ -184,8 +184,14 @@ ) # TODO: Workaround for undelete - if len(self.lm(mailfolder)) < 1: - return self.server + if len(self.lm(mailfolder)) < 1 and _mailfolder'hex_timestamp': + mailfolder = self.folder_utf7("DELETED/%s%s%s@%s" % ( + self.separator.join(_mailfolder'path_parts'), + self.separator, + _mailfolder'hex_timestamp', + _mailfolder'domain') + ) + # TODO: Murder capabilities may have been suppressed using Cyrus IMAP # configuration. @@ -219,17 +225,19 @@ max_tries = 20 num_try = 0 - annotation_path = "/shared/vendor/cmu/cyrus-imapd/server" + ann_path = "/vendor/cmu/cyrus-imapd/server" + s_ann_path = "/shared%s" % (ann_path) while 1: num_try += 1 annotations = self._getannotation( - mailfolder, - annotation_path + '"%s"' % (mailfolder), + ann_path ) if annotations.has_key(mailfolder): - break + if annotationsmailfolder.has_key(s_ann_path): + break if max_tries <= num_try: log.error( @@ -240,7 +248,7 @@ annotations = { mailfolder: { - annotation_path: self.server + s_ann_path: self.server } } @@ -255,7 +263,7 @@ time.sleep(1) - server = annotationsmailfolderannotation_path + server = annotationsmailfolders_ann_path self.mboxmailfolder = server log.debug(
View file
pykolab-0.8.7.tar.gz/pykolab/xml/event.py -> pykolab-0.8.8.tar.gz/pykolab/xml/event.py
Changed
@@ -880,7 +880,8 @@ if attr == "categories": self.add_category(value) elif attr == "class": - self.set_classification(value) + if (value and value:2 not in 'X-', 'x-'): + self.set_classification(value) elif attr == "recurrenceid": self.set_ical_recurrenceid(value, params) elif hasattr(self, ical_setter): @@ -1035,7 +1036,7 @@ self.event.setSequence(int(sequence)) def set_url(self, url): - self.event.setUrl(str(url)) + self.event.setUrl(ustr(url)) def set_recurrence(self, recurrence): self.event.setRecurrenceRule(recurrence)
View file
pykolab-0.8.7.tar.gz/share/templates/header_checks.submission -> pykolab-0.8.8.tar.gz/share/templates/header_checks.submission
Changed
@@ -2,3 +2,5 @@ /^Received:.*127\.0\.0\.1/ IGNORE /^User-Agent:/ IGNORE /^X-Mailer:/ IGNORE +/^Sender:/ IGNORE +/^X-Sender:/ IGNORE
View file
pykolab-0.8.7.tar.gz/share/templates/master.cf.tpl -> pykolab-0.8.8.tar.gz/share/templates/master.cf.tpl
Changed
@@ -85,6 +85,7 @@ # Filter email through Wallace smtp-wallace unix - - n - 3 smtp + -o default_destination_recipient_limit=1 -o smtp_data_done_timeout=1800 -o disable_dns_lookups=yes -o smtp_send_xforward_command=yes
View file
pykolab-0.8.7.tar.gz/wallace/module_invitationpolicy.py -> pykolab-0.8.8.tar.gz/wallace/module_invitationpolicy.py
Changed
@@ -419,8 +419,8 @@ # compare sequence number to determine a (re-)scheduling request if existing is not None: - log.debug(_("Existing %s: %r") % (existing.type, existing), level=9) scheduling_required = itip_event'sequence' > 0 and itip_event'sequence' > existing.get_sequence() + log.debug(_("Scheduling required: %r, for existing %s: %s") % (scheduling_required, existing.type, existing.get_uid()), level=8) save_object = True # if scheduling: check availability (skip that for tasks) @@ -774,14 +774,14 @@ return True -def list_user_folders(user_rec, type): +def list_user_folders(user_rec, _type): """ Get a list of the given user's private calendar/tasks folders """ global imap # return cached list - if user_rec.has_key('_imap_folders'): + if '_imap_folders' in user_rec: return user_rec'_imap_folders' result = @@ -789,39 +789,84 @@ if not imap_proxy_auth(user_rec): return result - folders = imap.list_folders('*') - log.debug(_("List %r folders for user %r: %r") % (type, user_rec'mail', folders), level=8) + folders = imap.get_metadata('*') + + log.debug( + _("List %r folders for user %r: %r") % ( + _type, + user_rec'mail', + folders + ), + level=8 + ) (ns_personal, ns_other, ns_shared) = imap.namespaces() - for folder in folders: - # exclude shared and other user's namespace - if ns_other is not None and folder.startswith(ns_other) and '_delegated_mailboxes' in user_rec: - # allow shared folders from delegators - if len(_mailbox for _mailbox in user_rec'_delegated_mailboxes' if folder.startswith(ns_other + _mailbox + '/')) == 0: + _folders = {} + + # Filter the folders by type relevance + for folder, metadata in folders.items(): + key = '/shared' + FOLDER_TYPE_ANNOTATION + if key in metadata: + if metadatakey.startswith(_type): + _foldersfolder = metadata + + key = '/private' + FOLDER_TYPE_ANNOTATION + if key in metadata: + if metadatakey.startswith(_type): + _foldersfolder = metadata + + for folder, metadata in _folders.items(): + folder_delegated = False + + # Exclude shared and other user's namespace + # + # First, test if this is another users folder + if ns_other is not None and folder.startswith(ns_other): + # If we have no delegated mailboxes, we can skip this entirely + if '_delegated_mailboxes' not in user_rec: + continue + + for _m in user_rec'_delegated_mailboxes': + if folder.startswith(ns_other + _m + '/'): + folder_delegated = True + + if not folder_delegated: continue + # TODO: list shared folders the user has write privileges ? - if ns_shared is not None and len(_ns for _ns in ns_shared if folder.startswith(_ns)) > 0: - continue - - metadata = imap.get_metadata(folder) - log.debug(_("IMAP metadata for %r: %r") % (folder, metadata), level=9) - if metadata.has_key(folder) and ( \ - metadatafolder.has_key('/shared' + FOLDER_TYPE_ANNOTATION) and metadatafolder'/shared' + FOLDER_TYPE_ANNOTATION.startswith(type) \ - or metadatafolder.has_key('/private' + FOLDER_TYPE_ANNOTATION) and metadatafolder'/private' + FOLDER_TYPE_ANNOTATION.startswith(type)): - result.append(folder) - - if metadatafolder.has_key('/private' + FOLDER_TYPE_ANNOTATION): - # store default folder in user record - if metadatafolder'/private' + FOLDER_TYPE_ANNOTATION.endswith('.default'): - user_rec'_default_folder' = folder - - # store private and confidential folders in user record - if metadatafolder'/private' + FOLDER_TYPE_ANNOTATION.endswith('.confidential') and not user_rec.has_key('_confidential_folder'): + if ns_shared is not None: + if len(_ns for _ns in ns_shared if folder.startswith(_ns)) > 0: + continue + + key = '/shared' + FOLDER_TYPE_ANNOTATION + if key in metadata: + if metadatakey.startswith(_type): + result.append(folder) + + key = '/private' + FOLDER_TYPE_ANNOTATION + if key in metadata: + if metadatakey.startswith(_type): + result.append(folder) + + # store default folder in user record + if metadatakey.endswith('.default'): + user_rec'_default_folder' = folder + continue + + # store private and confidential folders in user record + if metadatakey.endswith('.confidential'): + if '_confidential_folder' not in user_rec: user_rec'_confidential_folder' = folder - if metadatafolder'/private' + FOLDER_TYPE_ANNOTATION.endswith('.private') and not user_rec.has_key('_private_folder'): + + continue + + if metadatakey.endswith('.private'): + if '_private_folder' not in user_rec: user_rec'_private_folder' = folder + continue + # cache with user record user_rec'_imap_folders' = result
View file
pykolab-0.8.7.tar.gz/wallace/module_resources.py -> pykolab-0.8.8.tar.gz/wallace/module_resources.py
Changed
@@ -432,6 +432,9 @@ resource_dns = auth.find_resource('*') + # Remove referrals + resource_dns = dn for dn in resource_dns if dn is not None + # filter by resource_base_dn resource_base_dn = conf.get('ldap', 'resource_base_dn', None) if resource_base_dn is not None:
View file
pykolab.dsc
Changed
@@ -2,7 +2,7 @@ Source: pykolab Binary: pykolab, kolab-cli, kolab-conf, kolab-saslauthd, kolab-server, kolab-telemetry, kolab-xml, wallace Architecture: all -Version: 0.8.7-0~kolab2 +Version: 0.8.8-0~kolab1 Maintainer: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com> Uploaders: Paul Klos <kolab@klos2day.nl> Homepage: http://www.kolab.org @@ -40,5 +40,5 @@ pykolab deb python optional wallace deb python optional Files: - 00000000000000000000000000000000 0 pykolab-0.8.7.tar.gz + 00000000000000000000000000000000 0 pykolab-0.8.8.tar.gz 00000000000000000000000000000000 0 debian.tar.gz
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.