Projects
home:sicherha:branches:Kolab:16
pykolab-python3
Log In
Username
Password
Problem getting expanded diff: bad link: conflict in file debian.rules
×
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
Expand all
Collapse all
Changes of Revision 4
View file
pykolab.spec
Changed
@@ -10,6 +10,7 @@ %global py2or3_suffix 3 %global py3ornone_suffix 3 %global __python %{__python3} +%global python_sitelib %{python3_sitelib} %else %global py2or3_suffix 2 %{!?python_sitelib: %global python_sitelib %(python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")} @@ -44,21 +45,23 @@ %global pythonmysql python-mysql %else %if 0%{?use_python3} -%global pythonmysql python3-PyMySQL +%global pythonmysql python3-mysqlclient %else %global pythonmysql MySQL-python %endif %endif +%global upstream_version 0.9.0 + Summary: Kolab Groupware Solution Name: pykolab -Version: 0.9.0 +Version: 0.9.0.4 Release: 1%{?dist} License: GPLv3+ Group: Applications/System URL: http://kolab.org/ -Source0: pykolab-%{version}.tar.gz +Source0: pykolab-%{upstream_version}.tar.gz Source1: pykolab.logrotate BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root @@ -80,7 +83,9 @@ BuildRequires: glib2-devel BuildRequires: intltool BuildRequires: %{pythonmysql} + BuildRequires: python%{?py3ornone_suffix} +BuildRequires: python%{?py3ornone_suffix}-devel BuildRequires: python%{?py3ornone_suffix}-gnupg BuildRequires: python%{?py3ornone_suffix}-icalendar BuildRequires: python%{?py3ornone_suffix}-ldap @@ -89,7 +94,11 @@ BuildRequires: python%{?py3ornone_suffix}-kolabformat BuildRequires: python%{?py3ornone_suffix}-sqlalchemy BuildRequires: python%{?py3ornone_suffix}-tzlocal +%if 0%{?rhel} > 8 +BuildRequires: python%{?py2or3_suffix}-nose2 +%else BuildRequires: python%{?py2or3_suffix}-nose +%endif BuildRequires: python%{?py2or3_suffix}-pyasn1 BuildRequires: python%{?py2or3_suffix}-pyasn1-modules %if 0%{?rhel} < 8 && 0%{?fedora} < 1 @@ -241,19 +250,7 @@ This is the Kolab Content Filter, with plugins %prep -%setup -q - -%if 0%{?use_python3} -sed -i 's|#!/usr/bin/python|#!/usr/bin/python3|g' kolabd.py -sed -i 's|#!/usr/bin/python|#!/usr/bin/python3|g' saslauthd.py -sed -i 's|#!/usr/bin/python|#!/usr/bin/python3|g' conf.py -sed -i 's|#!/usr/bin/python|#!/usr/bin/python3|g' setup-kolab.py -sed -i 's|#!/usr/bin/python|#!/usr/bin/python3|g' wallace.py -sed -i 's|#!/usr/bin/python|#!/usr/bin/python3|g' kolab-cli.py -sed -i 's|#!/usr/bin/python|#!/usr/bin/python3|g' bin/kolab_parse_telemetry.py -sed -i 's|#!/usr/bin/python|#!/usr/bin/python3|g' bin/kolab_smtp_access_policy.py -%endif - +%setup -q -n %{name}-%{upstream_version} %build autoreconf -v || automake --add-missing && autoreconf -v @@ -425,7 +422,11 @@ fi %check +%if 0%{?rhel} > 8 +#nosetests -v tests/unit/ || : +%else nosetests -v tests/unit/ || : +%endif %clean rm -rf %{buildroot} @@ -478,7 +479,6 @@ %defattr(-,root,root,-) %doc AUTHORS COPYING %{_sbindir}/kolab_parse_telemetry -#%{python_sitelib}/pykolab/cli/commandgroups/telemetry.py %{python_sitelib}/pykolab/telemetry.* %{python_sitelib}/pykolab/cli/telemetry/
View file
cyrus-imapd.conf-cert-paths.patch
Changed
@@ -1,20 +1,24 @@ diff -ur pykolab-0.8.6.orig/share/templates/guam.sys.config.tpl pykolab-0.8.6/share/templates/guam.sys.config.tpl --- pykolab-0.8.6.orig/share/templates/guam.sys.config.tpl 2016-11-18 12:24:34.000000000 +0100 +++ pykolab-0.8.6/share/templates/guam.sys.config.tpl 2016-11-18 13:35:14.350503922 +0100 -@@ -26,7 +26,7 @@ +@@ -26,9 +26,7 @@ }, { tls_config, -- { certfile, "/etc/pki/cyrus-imapd/cyrus-imapd.pem" } +- { certfile, "/etc/pki/cyrus-imapd/cyrus-imapd.pem" }, +- { cacertfile, "/etc/pki/cyrus-imapd/cyrus-imapd-ca.pem" }, +- { keyfile, "/etc/pki/cyrus-imapd/cyrus-imapd-key.pem" } + { certfile, "/etc/ssl/private/cyrus-imapd.pem" } } -@@ -43,7 +43,7 @@ +@@ -43,9 +43,7 @@ }, { tls_config, -- { certfile, "/etc/pki/cyrus-imapd/cyrus-imapd.pem" } +- { certfile, "/etc/pki/cyrus-imapd/cyrus-imapd.pem" }, +- { cacertfile, "/etc/pki/cyrus-imapd/cyrus-imapd-ca.pem" }, +- { keyfile, "/etc/pki/cyrus-imapd/cyrus-imapd-key.pem" } + { certfile, "/etc/ssl/private/cyrus-imapd.pem" } }
View file
_link
Changed
@@ -1,4 +1,4 @@ -<link project="Kolab:16" baserev="f3bd0f82f881716bfb7da39b3542aa81"> +<link project="Kolab:16" baserev="252ad75c4927d4f6451007f368062ac6"> <patches> <branch/> </patches>
View file
buildtarball.sh
Added
@@ -0,0 +1,22 @@ +#!/bin/bash + +set -e + +VERSION=0.9.0 +GIT_REF=master +NAME=pykolab-$VERSION + +ROOT_DIR=$(pwd) + +rm -Rf /tmp/$NAME +mkdir /tmp/$NAME +cd /tmp/$NAME + +rm -f $NAME.tar.gz + -d "$NAME" && rm -rf "$NAME" + +git clone --branch master ssh://git@git.kolab.org/diffusion/P/pykolab.git $NAME +pushd $NAME +git archive --prefix=$NAME/ -o $ROOT_DIR/$NAME.tar.gz $GIT_REF + +cd "$PWD"
View file
debian.changelog
Changed
@@ -1,6 +1,6 @@ -pykolab (0.9.0-0~kolab1) unstable; urgency=low +pykolab (0.9.0.4-0~kolab4) unstable; urgency=low - * Release of version 0.8.0 + * Release of version 0.9.0 -- Christian Mollekopf <mollekopf@apheleia-it.ch> Tue, 16 Aug 2022 01:49:00 +0100
View file
debian.control
Changed
@@ -45,6 +45,7 @@ python3-pymysql, python3-six, python3-sqlalchemy, + ${python3:Depends}, ${misc:Depends}, ${shlibs:Depends}, ${ucs:Depends} @@ -57,6 +58,7 @@ python3, python3-augeas, python3-cheetah, + ${python3:Depends}, ${misc:Depends}, ${ucs:Depends} Description: Command-line utilities for Kolab @@ -64,7 +66,13 @@ Package: kolab-conf Architecture: all -Depends: pykolab (= ${binary:Version}), kolab-ldap, ${python3:Depends}, python3, ${misc:Depends}, python3-augeas, python3-cheetah +Depends: pykolab (= ${binary:Version}), + kolab-ldap, + python3, + ${python3:Depends}, + ${misc:Depends}, + python3-augeas, + python3-cheetah Description: Configuration management for Kolab This package includes configuration management utilities for Kolab Groupware @@ -74,6 +82,7 @@ Depends: lsb-base (>= 3.0-6), pykolab (= ${binary:Version}), python3, + ${python3:Depends}, sasl2-bin, ${misc:Depends} Description: SASL Authentication Daemon for Kolab @@ -81,14 +90,14 @@ Package: kolab-server Architecture: all -Depends: pykolab (= ${binary:Version}), python3, ${misc:Depends}, lsb-base (>= 3.0-6) +Depends: pykolab (= ${binary:Version}), python3, ${python3:Depends}, ${misc:Depends}, lsb-base (>= 3.0-6) Description: Kolab Groupware Server Server daemon synchronizing the mutations between various Kolab Groupware components. Package: kolab-telemetry Architecture: all -Depends: kolab-cli (= ${binary:Version}), python3, ${misc:Depends} +Depends: kolab-cli (= ${binary:Version}), python3, ${python3:Depends}, ${misc:Depends} Description: Kolab Telemetry Logging Capabilities Cyrus IMAP Telemetry logging handling capabilities for Kolab Groupware @@ -98,6 +107,7 @@ python3, python3-kolabformat, ${misc:Depends}, + ${python3:Depends}, python3-icalendar, python3-tzlocal Description: Kolab XML format wrapper for pykolab @@ -109,6 +119,7 @@ kolab-xml (= ${binary:Version}), python3-gnupg, python3, + ${python3:Depends}, ${misc:Depends}, lsb-base (>= 3.0-6), python3-dateutil,
View file
debian.rules
Changed
@@ -10,11 +10,14 @@ export DH_VERBOSE=1 %: - dh $@ --with python3 --with autotools-dev --with autoreconf + dh $@ --with python3 --without python2 --with autotools-dev --with autoreconf override_dh_auto_test: dh_auto_test || echo “ignoring test failure” +override_dh_python3: + dh_python3 --shebang=/usr/bin/python3 + override_dh_install: #dh_install --list-missing if -x "$$(which univention-install-config-registry 2>/dev/null)" ; then \
View file
pykolab-0.9.0.tar.gz/bin/kolab_parse_telemetry.py
Changed
@@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 # # Copyright 2010-2013 Kolab Systems AG (http://www.kolabsys.com) #
View file
pykolab-0.9.0.tar.gz/bin/kolab_smtp_access_policy.py
Changed
@@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 # # Copyright 2010-2013 Kolab Systems AG (http://www.kolabsys.com) #
View file
pykolab-0.9.0.tar.gz/conf.py
Changed
@@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 # -*- coding: utf-8 -*- # # Copyright 2010-2013 Kolab Systems AG (http://www.kolabsys.com)
View file
pykolab-0.9.0.tar.gz/conf/kolab.conf
Changed
@@ -240,8 +240,7 @@ ; The base DN, scope and filter to use when searching for additional domain ; name spaces in this environment. -domain_base_dn = ou=Domains,%(base_dn)s - +domain_base_dn = cn=kolab,cn=config domain_filter = (&(associatedDomain=*)) domain_name_attribute = associateddomain ; Attribute that holds the root dn for the domain name space. If this attribute @@ -411,7 +410,7 @@ ; The URI to use to connect to IMAP. Note that pykolab itself can detect whether ; or not Cyrus IMAP is deployed in a Murder topology, and should be able to ; connect to individual backends as well. -uri = imaps://localhost:993 +uri = imaps://localhost:9993 ; The login username to use for global administration. admin_login = cyrus-admin ; The corresponding password.
View file
pykolab-0.9.0.tar.gz/cyruslib.py
Changed
@@ -48,6 +48,8 @@ 'ID' : ('AUTH',), # Only one ID allowed in non auth mode 'GETANNOTATION': ('AUTH',), 'SETANNOTATION': ('AUTH',), + 'GETMETADATA': ('AUTH',), + 'SETMETADATA': ('AUTH',), 'XFER' : ('AUTH',) } @@ -87,6 +89,26 @@ elif not isinstance(s, (six.text_type, six.binary_type)): raise TypeError("not expecting type '%s'" % type(s)) return s +def ensure_binary(s, encoding='utf-8', errors='strict'): + """Coerce **s** to six.binary_type. + For Python 2: + - `unicode` -> encoded to `str` + - `str` -> `str` + For Python 3: + - `str` -> encoded to `bytes` + - `bytes` -> `bytes` + + Copied from six (not available < 1.12), and extended with list support. + """ + if isinstance(s, list): + + #FIXME pass encoding + return list(map(ensure_binary, s)) + if isinstance(s, six.binary_type): + return s + if isinstance(s, six.text_type): + return s.encode(encoding, errors) + raise TypeError("not expecting type '%s'" % type(s)) def ok(res): return res.upper().startswith('OK') @@ -104,6 +126,78 @@ if len(flag): flags.append(flag) return flags + +def parseToken(data, offset): + i = offset + while i < len(data): + c = datai:i+1 + if c == b' ': + return dataoffset:i, i + 1 + if c == b')': + return dataoffset:i, i + 1 + i += 1 + + +# TODO handle escape sequences? +def parseLiteral(data, offset): + i = offset + while i < len(data): + c = datai:i+1 + if c == b'"': + return dataoffset:i, i + 1 + i += 1 + + +def parseContinuation(data, offset): + i = offset + while i < len(data): + c = datai:i+1 + if c == b'}': + length = int(dataoffset:i) + return datai + 2:i + length + 1, i + length + 2 + i += 1 + + +def parse(data, offset): + result = + i = offset + while i < len(data): + c = datai:i + 1 + # print(c) + if c == b'(': + res, newOffset = parse(data, i + 1) + result.append(res) + i = newOffset + continue + if c == b')': + return result, i + 1 + if c == b'{': + res, newOffset = parseContinuation(data, i + 1) + # print("Found continuation", res, newOffset) + result.append(res) + i = newOffset + continue + if c == b'"': + res, newOffset = parseLiteral(data, i + 1) + # print("Found literal", res, newOffset) + result.append(res) + i = newOffset + continue + if c != b' ': + res, newOffset = parseToken(data, i) + # print("Found token", res, newOffset) + result.append(res) + i = newOffset + continue + i += 1 + return result, i + + +def tokenize(data): + result, _ = parse(data, 0) + return result + + ### A smart function to return an array of split strings ### and honours quoted strings def splitquote(text): @@ -172,7 +266,7 @@ return ok(res), dat0 def getannotation(self, mailbox, pattern='*', shared=None): - if shared == None: + if shared is None: typ, dat = self._simple_command('GETANNOTATION', mailbox, quote(pattern), quote('*')) elif shared: typ, dat = self._simple_command('GETANNOTATION', mailbox, quote(pattern), quote('value.shared')) @@ -193,6 +287,22 @@ return self._untagged_response(typ, dat, 'ANNOTATION') + + def setmetadata(self, mailbox, desc, value, shared=False): + if value: + value = value.join('"', '"') + else: + value = "NIL" + + if shared: + typ, dat = self._simple_command('SETMETADATA', mailbox, + "(/shared%s %s)" % (desc,value)) + else: + typ, dat = self._simple_command('SETMETADATA', mailbox, + "(/private%s %s)" % (desc,value)) + + return self._untagged_response(typ, dat, 'METADATA') + def setquota(self, mailbox, limit): """Set quota of a mailbox""" if limit == 0: @@ -260,7 +370,7 @@ return ok(res), dat0 def getannotation(self, mailbox, pattern='*', shared=None): - if shared == None: + if shared is None: typ, dat = self._simple_command('GETANNOTATION', mailbox, quote(pattern), quote('*')) elif shared: typ, dat = self._simple_command('GETANNOTATION', mailbox, quote(pattern), quote('value.shared')) @@ -281,6 +391,41 @@ return self._untagged_response(typ, dat, 'ANNOTATION') + def getmetadata(self, mailbox, pattern='*', shared=None): + # If pattern is '*' clean pattern and search all entries under /shared + # and/or /private (depens on the shared parameter value) to emulate the + # ANNOTATEMORE behaviour + if pattern == '*': + pattern = '' + options = '(DEPTH infinity)' + else: + options = '(DEPTH 0)' + if shared == None: + entries = '(/shared%s /private%s)' % (pattern, pattern) + elif shared: + entries = "/shared%s" % pattern + else: + entries = "/private%s" % pattern + + typ, dat = self._simple_command('GETMETADATA', mailbox, options, entries) + + return self._untagged_response(typ, dat, 'METADATA') + + def setmetadata(self, mailbox, desc, value, shared=False): + if value: + value = value.join('"', '"') + else: + value = "NIL" + + if shared: + typ, dat = self._simple_command('SETMETADATA', mailbox, + "(/shared%s %s)" % (desc,value)) + else: + typ, dat = self._simple_command('SETMETADATA', mailbox, + "(/private%s %s)" % (desc,value)) + + return self._untagged_response(typ, dat, 'METADATA') + def setquota(self, mailbox, limit): """Set quota of a mailbox""" if limit == 0: @@ -541,7 +686,7 @@ elif self.ENCODING in self.ENCODING_LIST: return self.__decode(text) - def lm(self, pattern="*"): + def lm(self, pattern=b"*"): """ List mailboxes, returns dict with list of mailboxes @@ -555,8 +700,8 @@ """ self.__prepare('LIST') - if pattern == '': pattern = "*" - if pattern == '%': + if pattern == b'': pattern = b"*" + if pattern == b'%': res, ml = self.__docommand('list', '', '%') else: res, ml = self.__docommand('list', '""', self.decode(pattern)) @@ -596,7 +741,8 @@ def dm(self, mailbox, recursive=True): """Delete mailbox""" self.__prepare('DELETE', mailbox) - mbxTmp = mailbox.split(self.SEP) + SEPARATOR = ensure_binary(self.SEP) + mbxTmp = mailbox.split(SEPARATOR) # Cyrus is not recursive for user subfolders and global folders if (recursive and mbxTmp0 != "user") or (len(mbxTmp) > 2): mbxList = self.lm("%s%s*" % (mailbox, self.SEP)) @@ -695,140 +841,77 @@ res, msg = self.__docommand("setquota", self.decode(mailbox), limit) self.__verbose( 'SETQUOTA %s %s %s: %s' % (mailbox, limit, res, msg0) ) - def getannotation(self, mailbox, pattern='*'): - """Get Annotation""" - self.__prepare('GETANNOTATION') - res, data = self.__docommand('getannotation', self.decode(mailbox), pattern) + def getmetadata(self, mailbox, pattern='*', shared=None): + """Get Metadata""" + # This test needs to be reviewed + #if not self.metadata: + # return {} + # Annotations vs. Metadata fix ... we set a pattern that we know is + # good enough for our purposes for now, but the fact is that the + # calling programs should be fixed instead. + + res, data = self.__docommand("getmetadata", self.decode(mailbox), pattern, shared) if (len(data) == 1) and data0 is None: - self.__verbose( 'GETANNOTATION %s No results' % (mailbox) ) + self.__verbose( 'GETMETADATA %s No results' % (mailbox) ) return {} ann = {} annotations = - empty_values = "NIL", '" "', None, '', ' ' + # Deal with partial metadata responses by making sure we have an even count of brackets concat_items = for item in data: if isinstance(item, tuple): - item = ' '.join(str(x) for x in item) + item = b' '.join(list(item)) if len(concat_items) > 0: concat_items.append(item) + joined = b''.join(concat_items) - if ''.join(concat_items).count('(') == ''.join(concat_items).count(')'): - annotations.append(''.join(concat_items)) + if joined.count(b'(') == joined.count(b')'): + annotations.append(joined) concat_items = - continue - else: - if item.count('(') == item.count(')'): - annotations.append(item) - continue - else: - concat_items.append(item) - continue + continue + + if item.count(b'(') == item.count(b')'): + annotations.append(item) + continue + + concat_items.append(item) for annotation in annotations: annotation = annotation.strip() - - if not annotation0 == '"': - folder = annotation.split('"')0.replace('"','').strip() - key = annotation.split('"')1.replace('"','').replace("'","").strip() - _annot = annotation.split('(')1.split(')')0.strip() - else: - folder = annotation.split('"')1.replace('"','').strip() - key = annotation.split('"')3.replace('"','').replace("'","").strip() - _annot = annotation.split('(')1.split(')')0.strip() + tokens = tokenize(annotation) + folder = tokens0 + + if mailbox != b'*' and folder != mailbox: + quoted_mailbox = "\"%s\"" % (mailbox) + if folder != quoted_mailbox: + # print("mismatch") + # print(quoted_mailbox) + self.__verbose( + 'GETMETADATA %s Mailbox \'%s\' is not the same as \'%s\'' + % (mailbox, quoted_mailbox, folder) + ) + return {} if folder not in ann: annfolder = {} - - try: - value_priv = _annot(_annot.index('"value.priv"')+len('"value.priv"')):_annot.index('"size.priv"').strip() - except ValueError: - value_priv = None - - try: - size_priv = _annot(_annot.index('"size.priv"')+len('"size.priv"')):.strip().split('"')1.strip() - try: - value_priv = value_privvalue_priv.index('{%s}' % (size_priv))+len('{%s}' % (size_priv)):.strip() - except Exception: - pass - except Exception: - pass - - if value_priv in empty_values: - value_priv = None - else: - try: - value_priv = value_priv:value_priv.index('"content-type.priv"').strip() - except: - pass - - try: - value_priv = value_priv:value_priv.index('"modifiedsince.priv"').strip() - except: - pass - - if value_priv.startswith('"'): - value_priv = value_priv1: - - if value_priv.endswith('"'): - value_priv = value_priv:-1 - - if value_priv in empty_values: - value_priv = None - - try: - value_shared = _annot(_annot.index('"value.shared"')+len('"value.shared"')):_annot.index('"size.shared"').strip() - except ValueError: - value_shared = None - - try: - size_shared = _annot(_annot.index('"size.shared"')+len('"size.shared"')):.strip().split('"')1.strip() - try: - value_shared = value_sharedvalue_shared.index('{%s}' % (size_shared))+len('{%s}' % (size_shared)):.strip() - except Exception: - pass - except Exception: - pass - - if value_shared in empty_values: - value_shared = None - else: - try: - value_shared = value_shared:value_shared.index('"content-type.shared"').strip() - except: - pass - - try: - value_shared = value_shared:value_shared.index('"modifiedsince.shared"').strip() - except: - pass - - if value_shared.startswith('"'): - value_shared = value_shared1: - - if value_shared.endswith('"'): - value_shared = value_shared:-1 - - if value_shared in empty_values: - value_shared = None - - if not value_priv == None: - annfolder'/private' + key = value_priv - - if not value_shared == None: - annfolder'/shared' + key = value_shared + # Iterate over list, two items at a time + for key, value in zip(*iter(tokens1) * 2): + # print(key) + # print(value) + if value != b'NIL': + annfolderkey = value return ann - def setannotation(self, mailbox, annotation, value, shared=False): - """Set Annotation""" - self.__prepare('SETANNOTATION') - res, msg = self.__docommand("setannotation", self.decode(mailbox), annotation, value, shared) - self.__verbose( 'SETANNOTATION %s %s: %s' % (mailbox, res, msg0) ) + def setmetadata(self, mailbox, desc, value, shared=False): + """Set METADADATA""" + res, msg = self.__docommand("setmetadata", self.decode(mailbox), desc, value, shared) + self.__verbose( 'SETMETADATA %s %s: %s' % (mailbox, res, msg0) ) def __reconstruct(self, mailbox): if not mailbox: @@ -853,7 +936,7 @@ self.__prepare('LSUB') if pattern == '': pattern = "*" res, ml = self.__docommand('lsub', '*', pattern) - + ml = ensure_str(ml) if not ok(res): self.__verbose( 'LIST %s: %s' % (res, ml) ) return
View file
pykolab-0.9.0.tar.gz/ext/python/Tools/freeze/freeze.py
Changed
@@ -1,4 +1,4 @@ -#! /usr/bin/env python +#! /usr/bin/env python3 """Freeze a Python script into a binary.
View file
pykolab-0.9.0.tar.gz/kolab-cli.py
Changed
@@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 # # Copyright 2010-2013 Kolab Systems AG (http://www.kolabsys.com) #
View file
pykolab-0.9.0.tar.gz/kolabd.py
Changed
@@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 # # Copyright 2010-2013 Kolab Systems AG (http://www.kolabsys.com) #
View file
pykolab-0.9.0.tar.gz/pykolab/auth/__init__.py
Changed
@@ -232,8 +232,8 @@ def find_user(self, attr, value, **kw): return self._auth.search_entry_by_attribute(attr, value, **kw) - def find_user_dn(self, login, kolabuser=False): - return self._auth._find_user_dn(login, kolabuser); + def find_user_dn(self, login, kolabuser=False, domain=None): + return self._auth._find_user_dn(login, kolabuser, domain); def list_recipient_addresses(self, user): return self._auth.list_recipient_addresses(user)
View file
pykolab-0.9.0.tar.gz/pykolab/auth/ldap/__init__.py
Changed
@@ -124,13 +124,7 @@ log.error(_l("Authentication cache failed: %r") % (errmsg)) if base_dn is None: - config_base_dn = self.config_get('base_dn') - ldap_base_dn = self._kolab_domain_root_dn(self.domain) - - if ldap_base_dn is not None and not ldap_base_dn == config_base_dn: - base_dn = ldap_base_dn - else: - base_dn = config_base_dn + base_dn = self._base_dn() try: auth_cache.set_entry(self.domain, base_dn) @@ -459,18 +453,11 @@ return entry_id'dn' unique_attribute = self.config_get('unique_attribute') - config_base_dn = self.config_get('base_dn') - ldap_base_dn = self._kolab_domain_root_dn(self.domain) - - if ldap_base_dn is not None and not ldap_base_dn == config_base_dn: - base_dn = ldap_base_dn - else: - base_dn = config_base_dn _filter = "(%s=%s)" % (unique_attribute, ldap.filter.escape_filter_chars(entry_id)) _search = self.ldap.search_ext( - base_dn, + self._base_dn(), ldap.SCOPE_SUBTREE, _filter, 'entrydn' @@ -714,19 +701,13 @@ _filter = "%s%s%s" % (__filter_prefix, _filter, __filter_suffix) - log.debug(_l("Finding recipient with filter %r") % (_filter), level=8) + base_dn = self._base_dn() + + log.debug(_l("Finding recipient with filter %r in %s") % (_filter, base_dn), level=8) if len(_filter) <= 6: return None - config_base_dn = self.config_get('base_dn') - ldap_base_dn = self._kolab_domain_root_dn(self.domain) - - if ldap_base_dn is not None and not ldap_base_dn == config_base_dn: - base_dn = ldap_base_dn - else: - base_dn = config_base_dn - _results = self.ldap.search_s( base_dn, scope=ldap.SCOPE_SUBTREE, @@ -790,13 +771,13 @@ _filter = "%s%s%s" % (__filter_prefix, _filter, __filter_suffix) - log.debug(_l("Finding resource with filter %r") % (_filter), level=8) - if len(_filter) <= 6: return None resource_base_dn = self._object_base_dn('resource') + log.debug(_l("Finding resource with filter %s in %s") % (_filter, resource_base_dn), level=8) + _results = self.ldap.search_s( resource_base_dn, scope=ldap.SCOPE_SUBTREE, @@ -1220,13 +1201,9 @@ _filter = "(%s=%s)" % (attr, ldap.filter.escape_filter_chars(value)) - config_base_dn = self.config_get('base_dn') - ldap_base_dn = self._kolab_domain_root_dn(self.domain) + base_dn = self._base_dn() - if ldap_base_dn is not None and not ldap_base_dn == config_base_dn: - base_dn = ldap_base_dn - else: - base_dn = config_base_dn + log.debug(_l("Finding entry %s in %s") % (_filter, base_dn), level=8) _results = self._search( base_dn, @@ -1321,22 +1298,14 @@ _filter = "(&%s(modifytimestamp>=%s))" % (_filter, modified_after) - log.debug(_l("Synchronization is using filter %r") % (_filter), level=8) - if mode != 0: override_search = mode else: - override_search = False + override_search = None - config_base_dn = self.config_get('base_dn') - ldap_base_dn = self._kolab_domain_root_dn(self.domain) + base_dn = self._base_dn() - if ldap_base_dn is not None and not ldap_base_dn == config_base_dn: - base_dn = ldap_base_dn - else: - base_dn = config_base_dn - - log.debug(_l("Synchronization is searching against base DN: %s") % (base_dn), level=8) + log.debug(_l("Synchronization is searching for %s in %s") % (_filter, base_dn), level=8) if callback is None: callback = self._synchronize_callback @@ -2429,14 +2398,7 @@ self._bind() entry_dn = self.entry_dn(entry_id) - - config_base_dn = self.config_get('base_dn') - ldap_base_dn = self._kolab_domain_root_dn(self.domain) - - if ldap_base_dn is not None and not ldap_base_dn == config_base_dn: - base_dn = ldap_base_dn - else: - base_dn = config_base_dn + base_dn = self._base_dn() for _type in 'user', 'group', 'sharedfolder': __filter = self.config_get('kolab_%s_filter' % (_type)) @@ -2462,14 +2424,14 @@ return None - def _find_user_dn(self, login, kolabuser=False): + def _find_user_dn(self, login, kolabuser=False, domain=None): """ Find the distinguished name (DN) for a (Kolab) user entry in LDAP. """ conf_prefix = 'kolab_' if kolabuser else '' - user_base_dn = self._object_base_dn('user', conf_prefix) + user_base_dn = self._object_base_dn('user', conf_prefix, domain) auth_attrs = self.config_get_list('auth_attributes') @@ -2682,18 +2644,12 @@ return domains - def _object_base_dn(self, objectType, prefix=''): + def _object_base_dn(self, objectType, prefix='', domain=None): """ Get configured base DN for specified Kolab object type """ - object_base_dn = self.config_get(prefix + objectType + '_base_dn') - config_base_dn = self.config_get('base_dn') - ldap_base_dn = self._kolab_domain_root_dn(self.domain) - - if ldap_base_dn is not None and not ldap_base_dn == config_base_dn: - base_dn = ldap_base_dn - else: - base_dn = config_base_dn + object_base_dn = self.config_get_raw(prefix + objectType + '_base_dn') + base_dn = self._base_dn(domain) if object_base_dn is None: object_base_dn = base_dn @@ -2702,6 +2658,15 @@ return object_base_dn + def _base_dn(self, domain=None): + config_base_dn = self.config_get('base_dn') + ldap_base_dn = self._kolab_domain_root_dn(domain if domain is not None else self.domain) + + if ldap_base_dn is not None and not ldap_base_dn == config_base_dn: + return ldap_base_dn + + return config_base_dn + def _synchronize_callback(self, *args, **kw): """ Determine the characteristics of the callback being placed, and @@ -2844,7 +2809,7 @@ attrlist=None, attrsonly=0, timeout=-1, - callback=False, + callback=None, primary_domain=None, secondary_domains= ): @@ -2860,6 +2825,8 @@ ) ) + log.debug(_l("Searching with filter %r in %s") % (filterstr, base_dn), level=8) + _search = self.ldap.search_ext( base_dn, scope=scope, @@ -2938,7 +2905,7 @@ attrlist=None, attrsonly=0, timeout=-1, - callback=False, + callback=None, primary_domain=None, secondary_domains= ): @@ -2948,6 +2915,8 @@ server_page_control = ldap.controls.libldap.SimplePagedResultsControl(size=page_size,cookie='') + log.debug(_l("Searching for %r in %s") % (filterstr, base_dn), level=8) + _search = self.ldap.search_ext( base_dn, scope=scope, @@ -3025,7 +2994,7 @@ attrlist=None, attrsonly=0, timeout=-1, - callback=False, + callback=None, primary_domain=None, secondary_domains= ): @@ -3039,7 +3008,7 @@ attrlist=None, attrsonly=0, timeout=-1, - callback=False, + callback=None, primary_domain=None, secondary_domains= ): @@ -3085,7 +3054,7 @@ attrlist=None, attrsonly=0, timeout=None, - callback=False, + callback=None, primary_domain=None, secondary_domains= ): @@ -3093,7 +3062,7 @@ if timeout is None: timeout = float(self.config_get('ldap', 'timeout', default=10)) - log.debug(_l("Searching with filter %r") % (filterstr), level=8) + log.debug(_l("Searching for %r in %s") % (filterstr, base_dn), level=8) _search = self.ldap.search( base_dn, @@ -3123,8 +3092,8 @@ attrlist=None, attrsonly=0, timeout=None, - override_search=False, - callback=False, + override_search=None, + callback=None, primary_domain=None, secondary_domains= ): @@ -3181,7 +3150,7 @@ _results = - if override_search is not False: + if override_search: _use_ldap_controls = override_search else: _use_ldap_controls = self.ldap.supported_controls
View file
pykolab-0.9.0.tar.gz/pykolab/auth/ldap/syncrepl.py
Changed
@@ -1,8 +1,8 @@ -#!/usr/bin/python +#!/usr/bin/python3 try: import anydbm -except: +except ImportError: import dbm.ndbm as anydbm import ldap import ldap.syncrepl @@ -11,11 +11,13 @@ import pykolab from pykolab import utils +from pykolab.translate import _ log = pykolab.getLogger('pykolab.syncrepl') conf = pykolab.getConf() -class DNSync(ldap.ldapobject.LDAPObject,ldap.syncrepl.SyncreplConsumer): + +class DNSync(ldap.ldapobject.LDAPObject, ldap.syncrepl.SyncreplConsumer): callback = None @@ -28,7 +30,7 @@ self.__db = anydbm.open(filename, 'c', 0o640) self.__presentUUIDs = {} - def syncrepl_set_cookie(self,cookie): + def syncrepl_set_cookie(self, cookie): self.__db'cookie' = cookie def syncrepl_get_cookie(self): @@ -36,12 +38,12 @@ return self.__db'cookie' def syncrepl_delete(self, uuids): - log.debug("syncrepl_delete uuids: %r" % (uuids), level=8) + log.debug("syncrepl_delete uuids: %r" % uuids, level=8) # Get the unique_attribute name to issue along with our # callback (if any) unique_attr = conf.get('ldap', 'unique_attribute') - if unique_attr == None: + if unique_attr is None: unique_attr = 'entryuuid' if unique_attr == 'nsuniqueid': @@ -50,14 +52,13 @@ "is very probably not compatible with the use of " + \ "syncrepl.") ) - for uuid in uuids: dn = self.__dbuuid - log.debug("syncrepl_delete dn: %r" % (dn), level=8) + log.debug("syncrepl_delete dn: %r" % dn, level=8) - if not self.callback == None: + if self.callback is not None: self.callback( change_type='delete', previous_dn=None, @@ -90,7 +91,7 @@ if uuid in self.__db: odn = self.__dbuuid if odn != dn: - if not self.callback == None: + if self.callback is not None: self.callback( change_type='moddn', previous_dn=odn, @@ -100,7 +101,7 @@ ) else: - if not self.callback == None: + if self.callback is not None: self.callback( change_type='modify', previous_dn=None, @@ -110,7 +111,7 @@ ) else: - if not self.callback == None: + if self.callback is not None: self.callback( change_type='add', previous_dn=None,
View file
pykolab-0.9.0.tar.gz/pykolab/cli/cmd_delete_mailbox.py
Changed
@@ -37,6 +37,17 @@ def description(): return """Delete a mailbox or sub-folder. Note that the mailbox or folder is removed recursively.""" +def cli_options(): + my_option_group = conf.add_cli_parser_option_group(_("CLI Options")) + my_option_group.add_option( + '--server', + dest="connect_server", + action="store", + default=None, + metavar="SERVER", + help=_("Delete mailboxes on server SERVER only.") + ) + def execute(*args, **kw): """ Delete mailbox @@ -48,7 +59,10 @@ imap = IMAP() - imap.connect() + if not conf.connect_server == None: + imap.connect(server=conf.connect_server) + else: + imap.connect() delete_folders = while len(conf.cli_args) > 0:
View file
pykolab-0.9.0.tar.gz/pykolab/cli/cmd_list_deleted_mailboxes.py
Changed
@@ -104,7 +104,7 @@ print("Deleted folders:") for folder in folders: - utf8_folder = imap_utf7.decode(folder).encode('utf-8') + utf8_folder = imap_utf7.decode(folder) mbox_parts = imap.parse_mailfolder(utf8_folder) ts = datetime.datetime.fromtimestamp(int(mbox_parts'hex_timestamp', 16))
View file
pykolab-0.9.0.tar.gz/pykolab/cli/cmd_list_mailbox_metadata.py
Changed
@@ -92,6 +92,6 @@ if folder in metadata: for annotation in metadatafolder: print(" %-49s %s" % ( - annotation, - metadatafolderannotation + annotation.decode('utf-8', 'replace'), + metadatafolderannotation.decode('utf-8', 'replace') ))
View file
pykolab-0.9.0.tar.gz/pykolab/cli/cmd_list_mailboxes.py
Changed
@@ -16,6 +16,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # +import datetime from . import commands @@ -97,7 +98,13 @@ folders.extend(imap.lm(imap_utf7.encode(search))) for folder in folders: - if not conf.raw: - print(imap_utf7.decode(folder)) - else: + if conf.raw: print(folder) + else: + utf8_folder = imap_utf7.decode(folder) + if 'DELETED' in folder: + mbox_parts = imap.parse_mailfolder(utf8_folder) + ts = datetime.datetime.fromtimestamp(int(mbox_parts'hex_timestamp', 16)) + print("%s (Deleted at %s)" % (folder, ts)) + else: + print(utf8_folder)
View file
pykolab-0.9.0.tar.gz/pykolab/cli/cmd_sync.py
Changed
@@ -74,20 +74,20 @@ auth = Auth() if conf.domain == "all": - log.debug(_("Listing domains..."), level=5) - start_time = time.time() - domains = auth.list_domains() - end_time = time.time() - log.debug( + log.debug(_("Listing domains..."), level=5) + start_time = time.time() + domains = auth.list_domains() + end_time = time.time() + log.debug( _("Found %d domains in %d seconds") % ( - len(domains), - (end_time-start_time) - ), + len(domains), + (end_time-start_time) + ), level=8 ) else: - domains = {} - domainsconf.domain = conf.domain + domains = {} + domainsconf.domain = conf.domain if version.StrictVersion(sys.version:3) >= version.StrictVersion("2.7"): pool = multiprocessing.Pool(conf.threads, worker_process, (), 1) @@ -125,14 +125,13 @@ entry = utils.normalize(kw) mailbox_attribute = conf.get('cyrus-sasl', 'result_attribute') - if mailbox_attribute == None: + if mailbox_attribute is None: mailbox_attribute = 'mail' - if mailbox_attribute not in entry: return - if not 'kolabinetorgperson' in entry'objectclass': + if 'kolabinetorgperson' not in entry'objectclass': return imap = IMAP()
View file
pykolab-0.9.0.tar.gz/pykolab/imap/__init__.py
Changed
@@ -271,6 +271,7 @@ log.error( _("Could not create folder %r on server %r: %r") % (folder_path, server, excpt) ) + return self.has_folder(folder_path) else: try: @@ -278,7 +279,7 @@ return True except Exception as excpt: log.error(_("Could not create folder %r: %r") % (folder_path, excpt)) - return False + return self.has_folder(folder_path) def __getattr__(self, name): if hasattr(self.imap, name): @@ -304,13 +305,13 @@ def folder_quote(self, folder): return u'"' + str(folder).strip('"') + '"' - def get_metadata(self, folder): + def get_metadata(self, folder, pattern='*'): """ Obtain all metadata entries on a folder """ metadata = {} - _metadata = self.imap.getannotation(self.folder_utf7(folder), '*') + _metadata = self.imap.getmetadata(self.folder_utf7(folder), pattern) for (k, v) in _metadata.items(): metadataself.folder_utf8(k) = v @@ -467,7 +468,7 @@ shared = False metadata_path = metadata_path.replace('/private/', '/') - self.imap._setannotation(self.folder_utf7(folder), metadata_path, metadata_value, shared) + self.imap._setmetadata(self.folder_utf7(folder), metadata_path, metadata_value, shared) def shared_folder_create(self, folder_path, server=None): """
View file
pykolab-0.9.0.tar.gz/pykolab/imap/cyrus.py
Changed
@@ -30,6 +30,7 @@ import pykolab +from pykolab import utils from pykolab import constants from pykolab.imap import IMAP from pykolab.translate import _ @@ -200,7 +201,7 @@ ) # TODO: Workaround for undelete - if len(self.lm(mailfolder)) < 1 and 'hex_timestamp' in _mailfolder: + if 'hex_timestamp' in _mailfolder: mailfolder = self.folder_utf7("DELETED/%s%s%s@%s" % ( self.separator.join(_mailfolder'path_parts'), self.separator, @@ -208,7 +209,6 @@ _mailfolder'domain') ) - # TODO: Murder capabilities may have been suppressed using Cyrus IMAP # configuration. if not self.murder: @@ -241,18 +241,15 @@ max_tries = 20 num_try = 0 - ann_path = "/vendor/cmu/cyrus-imapd/server" - s_ann_path = "/shared%s" % (ann_path) + ann_path = b"/vendor/cmu/cyrus-imapd/server" + s_ann_path = b"/shared%s" % (ann_path) while 1: num_try += 1 - annotations = self._getannotation( - '"%s"' % (mailfolder), - ann_path - ) + annotations = self._getmetadata(mailfolder, ann_path) if mailfolder in annotations: - if s_ann_path in annotationsmailfolder: + if s_ann_path.encode('utf-8') in annotationsmailfolder: break if max_tries <= num_try: @@ -279,7 +276,7 @@ time.sleep(1) - server = annotationsmailfolders_ann_path + server = annotationsmailfolders_ann_path.encode('utf-8') self.mboxmailfolder = server log.debug( @@ -363,12 +360,12 @@ partition ) - def _getannotation(self, *args, **kw): - return self.getannotation(*args, **kw) + def _getmetadata(self, *args, **kw): + return self.getmetadata(*args, **kw) - def _setannotation(self, mailfolder, annotation, value, shared=False): + def _setmetadata(self, mailfolder, metadata, value, shared=False): """ - Login to the actual backend server, then set annotation. + Login to the actual backend server, then set metadata. """ try: server = self.find_mailfolder_server(mailfolder) @@ -376,24 +373,32 @@ server = self.server log.debug( - _("Setting annotation %s on folder %s") % ( - annotation, + _("Setting metadata %s on folder %s") % ( + metadata, mailfolder ), level=8 ) try: - self.setannotation(mailfolder, annotation, value, shared) + self.setmetadata(mailfolder, metadata, value, shared) except cyruslib.CYRUSError as errmsg: log.error( - _("Could not set annotation %r on mail folder %r: %r") % ( - annotation, + _("Could not set metadata %r on mail folder %r: %r") % ( + metadata, mailfolder, errmsg ) ) + # Use metadata instead of annotations + def _getannotation(self, *args, **kw): + return self._getmetadata(*args, **kw) + + # Use metadata instead of annotations + def _setannotation(self, *args, **kw): + return self._setmetadata(*args, **kw) + def _xfer(self, mailfolder, current_server, new_server): self.connect(self.uri.replace(self.server, current_server)) log.debug( @@ -446,6 +451,11 @@ for undelete_folder in undelete_folders: undelete_mbox = self.parse_mailfolder(undelete_folder) + if undelete_mbox is None: + print(_("The folder to undelete does not exist") % ( + undelete_mbox + ), file=sys.stdout) + return prefix = undelete_mbox'path_parts'.pop(0) mbox = undelete_mbox'path_parts'.pop(0) @@ -491,8 +501,12 @@ ) ) - target_server = self.find_mailfolder_server(target_folder) source_server = self.find_mailfolder_server(undelete_folder) + try: + target_server = self.find_mailfolder_server(target_folder) + except cyruslib.CYRUSError as errmsg: + # This is normal for a toplevel folder, the target does not exist + target_server = source_server if hasattr(conf, 'dry_run') and not conf.dry_run: undelete_folder = self.folder_utf7(undelete_folder) @@ -567,13 +581,7 @@ mbox'domain' ) - if ' ' in verify_folder_search: - folders = self.lm( - '"%s"' % self.folder_utf7(verify_folder_search) - ) - - else: - folders = self.lm(self.folder_utf7(verify_folder_search)) + folders = self.lm(utils.ensure_str(self.folder_utf7(verify_folder_search))) # NOTE: Case also covered is valid hexadecimal folders; won't be # the actual check as intended, but doesn't give you anyone else's
View file
pykolab-0.9.0.tar.gz/pykolab/imap/dovecot.py
Changed
@@ -57,128 +57,6 @@ log = pykolab.getLogger('pykolab.imap') conf = pykolab.getConf() -# BEG: Add GETMETADATA and SETMETADATA support to the cyruslib IMAP objects - -Commands = { - 'GETMETADATA': ('AUTH',), - 'SETMETADATA': ('AUTH',), -} - -imaplib.Commands.update(Commands) - -def imap_getmetadata(self, mailbox, pattern='*', shared=None): - # If pattern is '*' clean pattern and search all entries under /shared - # and/or /private (depens on the shared parameter value) to emulate the - # ANNOTATEMORE behaviour - if pattern == '*': - pattern = '' - options = '(DEPTH infinity)' - else: - options = '(DEPTH 0)' - if shared == None: - entries = '( /shared%s /private%s )' % (pattern, pattern) - elif shared: - entries = "/shared%s" % pattern - else: - entries = " /private%s" % pattern - - typ, dat = self._simple_command('GETMETADATA', options, mailbox, entries) - - return self._untagged_response(typ, dat, 'METADATA') - -def imap_setmetadata(self, mailbox, desc, value, shared=False): - if value: - value = value.join('"', '"') - else: - value = "NIL" - - if shared: - typ, dat = self._simple_command('SETMETADATA', mailbox, - "(/shared%s %s)" % (desc,value)) - else: - typ, dat = self._simple_command('SETMETADATA', mailbox, - "(/private%s %s)" % (desc,value)) - - return self._untagged_response(typ, dat, 'METADATA') - -# Bind the new methods to the cyruslib IMAP4 and IMAP4_SSL objects -from types import MethodType -cyruslib.IMAP4.getmetadata = MethodType(imap_getmetadata, None, cyruslib.IMAP4) -cyruslib.IMAP4.setmetadata = MethodType(imap_setmetadata, None, cyruslib.IMAP4) -cyruslib.IMAP4_SSL.getmetadata = MethodType(imap_getmetadata, None, cyruslib.IMAP4_SSL) -cyruslib.IMAP4_SSL.setmetadata = MethodType(imap_setmetadata, None, cyruslib.IMAP4_SSL) - -# END: Add GETMETADATA and SETMETADATA support to the cyruslib IMAP objects - -# Auxiliary functions -def _get_line_entries(lines): - """Function to get metadata entries """ - entries = {} - name = None - value = "" - vlen = 0 - for line in lines: - line_len = len(line) - i = 0 - while i < line_len: - if name == None: - if linei == '/': - j = i - while j < line_len: - if linej == ' ': - break - j += 1 - name = linei:j - i = j - elif vlen != 0: - j = i + vlen - if j > line_len: - value += linei:line_len - vlen -= line_len - i - else: - value += linei:i+vlen - if value in ('', 'NIL'): - entriesname = "" - else: - entriesname = value - name = None - value = "" - vlen = 0 - elif linei == '{': - j = i - while j < line_len: - if linej == '}': - vlen = int(linei+1:j) - break - j += 1 - i = j - elif linei != ' ': - j = i - if linei == '"': - while j < line_len: - # Skip quoted text - if linej == '\\': - j += 2 - continue - elif linej == '"': - break - j += 1 - else: - while j < line_len: - if linej == ' ' or linej == ')': - break - j += 1 - value = linei:j - if value in ('', 'NIL'): - entriesname = "" - else: - entriesname = value - name = None - value = "" - i = j - i += 1 - return entries - class Dovecot(cyruslib.CYRUS): """ Abstraction class for some common actions to do exclusively in @@ -330,126 +208,15 @@ self.m.rename(self.folder_utf7(from_mailfolder), self.folder_utf7(to_mailfolder), '"%s"' % (partition)) -# BEG: METADATA support functions ... quite similar to annotations, really - - def _getmetadata(self, mailbox, pattern='*', shared=None): - """Get Metadata""" - # This test needs to be reviewed - #if not self.metadata: - # return {} - - # Annotations vs. Metadata fix ... we set a pattern that we know is - # good enough for our purposes for now, but the fact is that the - # calling programs should be fixed instead. - - res, data = self.m.getmetadata(self.decode(mailbox), pattern, shared) - - if (len(data) == 1) and data0 is None: - self.__verbose( 'GETMETADATA %s No results' % (mailbox) ) - return {} - - # Get the first response line (it can be a string or a tuple) - if isinstance(data0, tuple): - fline = data00 - else: - fline = data0 - - # Find the folder name - fbeg = 0 - fend = -1 - if fline0 == '"': - # Quoted name - fbeg = 1 - i = 1 - while i < len(fline): - if flinei == '"': - # folder name ended unless the previous char is \ (we - # should test more, this test would fail if we had a \ - # at the end of the folder name, but we leave it at that - # right now - if flinei-1 != '\\': - fend = i - break - i += 1 - else: - # For unquoted names the first word is the folder name - fend = fline.find(' ') - - # No mailbox found - if fend < 0: - self.__verbose( 'GETMETADATA %s Mailbox not found in results' % (mailbox) ) - return {} - - # Folder name - folder = flinefbeg:fend - - # Check mailbox name against the folder name - if folder != mailbox: - quoted_mailbox = "\"%s\"" % (mailbox) - if folder != quoted_mailbox: - self.__verbose( - 'GETMETADATA %s Mailbox \'%s\' is not the same as \'%s\'' \ - % (mailbox, quoted_mailbox, folder) - ) - return {} - - # Process the rest of the first line, the first value will be - # available after the first '(' found - i=fend - ebeg = -1 - while i < len(fline): - if flinei == '(': - ebeg = i+1 - break - i += 1 - - if ebeg < 0: - self.__verbose( - 'GETMETADATA %s Mailbox has no values, skipping' % (mailbox) - ) - return {} - - # This variable will start with an entry name and will continue with - # the value lenght or the value - nfline = flineebeg: - if isinstance(data0, tuple): - entries = _get_line_entries((nfline,) + data01:) - else: - entries = _get_line_entries((nfline,)) - - for line in data1:: - if isinstance(line, tuple): - lentries = _get_line_entries(line) - else: - lentries = _get_line_entries(line,) - - if lentries != None and lentries != {}: - entries.update(lentries) - - mdat = { mailbox: entries }; - return mdat - - def _setmetadata(self, mailbox, desc, value, shared=False): - """Set METADADATA""" - res, msg = self.m.setmetadata(self.decode(mailbox), desc, value, shared) - self.__verbose( 'SETMETADATA %s %s: %s' % (mailbox, res, msg0) ) # Use metadata instead of annotations def _getannotation(self, *args, **kw): return self._getmetadata(*args, **kw) - def getannotation(self, *args, **kw): - return self._getmetadata(*args, **kw) - # Use metadata instead of annotations def _setannotation(self, *args, **kw): return self._setmetadata(*args, **kw) - def setannotation(self, *args, **kw): - return self._setmetadata(*args, **kw) - -# END: METADATA / Annotations - # The functions that follow are the same ones used with Cyrus, probably a # review is needed
View file
pykolab-0.9.0.tar.gz/pykolab/imap_utf7.py
Changed
@@ -112,8 +112,10 @@ elif b64_buffer: b64_buffer.append(c) # No buffer initialized yet, should be an ASCII printable char - else: + elif isinstance(c, int): res.append(chr(c)) + else: + res.append(c) # Decode the remaining buffer if any if b64_buffer:
View file
pykolab-0.9.0.tar.gz/pykolab/logger.py
Changed
@@ -73,8 +73,8 @@ # Required for python3 compat because logger adapter now has a native debug function. - def debug(self, msg, level=1, *args, **kw): - return self.logger.debug(msg, level, args, kw) + def debug(self, msg, *args, **kw): + return self.logger.debug(msg, args, kw) class Logger(logging.Logger): @@ -264,14 +264,13 @@ self.console_stdout.close() self.removeHandler(self.console_stdout) - # pylint: disable=arguments-differ - # pylint: disable=keyword-arg-before-vararg - def debug(self, msg, level=1, *args, **kw): + def debug(self, msg, *args, **kw): self.setLevel(self.loglevel) # Work around other applications not using various levels of debugging if not self.name.startswith('pykolab') and self.debuglevel != 9: return + level = kw.get('level', 1) if level <= self.debuglevel: self.log(logging.DEBUG, msg)
View file
pykolab-0.9.0.tar.gz/pykolab/setup/setup_imap.py
Changed
@@ -61,7 +61,7 @@ partition_default = "/var/spool/cyrus/mail/" imapd_settings = { - "ldap_servers": conf.get('ldap', 'ldap_uri'), + "ldap_uri": conf.get('ldap', 'ldap_uri'), "ldap_base": conf.get('ldap', 'base_dn'), "ldap_bind_dn": conf.get('ldap', 'service_bind_dn'), "ldap_password": conf.get('ldap', 'service_bind_pw'),
View file
pykolab-0.9.0.tar.gz/pykolab/setup/setup_ldap.py
Changed
@@ -56,6 +56,14 @@ ) ldap_group.add_option( + "--domain", + dest = "domain", + action = "store", + default = None, + help = _("Specify the domain (defaults to one level up from fqdn).") + ) + + ldap_group.add_option( "--allow-anonymous", dest = "anonymous", action = "store_true", @@ -248,19 +256,13 @@ # TODO: Verify the user and group exist. - # TODO: This takes the system fqdn, domainname and hostname, rather then - # the desired fqdn, domainname and hostname. - # - # TODO^2: This should be confirmed. - - if conf.fqdn: - _input'fqdn' = conf.fqdn - _input'hostname' = conf.fqdn.split('.')0 - _input'domain' = '.'.join(conf.fqdn.split('.')1:) + _input'fqdn' = conf.fqdn + _input'hostname' = conf.fqdn.split('.')0 + if conf.domain: + _input'domain' = conf.domain else: - _input'fqdn' = fqdn - _input'hostname' = hostname.split('.')0 - _input'domain' = domainname + _input'domain' = '.'.join(conf.fqdn.split('.')1:) + _input'nodotdomain' = _input'domain'.replace('.','_') _input'rootdn' = utils.standard_root_dn(_input'domain') @@ -447,11 +449,11 @@ ), file=sys.stderr) fp = open('/var/log/kolab/setup.error.log', 'w') - fp.write(stderrdata) + fp.write(utils.ensure_str(stderrdata, 'latin-1')) fp.close() fp = open('/var/log/kolab/setup.out.log', 'w') - fp.write(stdoutdata) + fp.write(utils.ensure_str(stdoutdata, 'latin-1')) fp.close() log.debug(_("Setup DS stdout:"), level=8) @@ -543,11 +545,11 @@ ), file=sys.stderr) fp = open('/var/log/kolab/setup.error.log', 'w') - fp.write(stderrdata) + fp.write(utils.ensure_str(stderrdata, 'latin-1')) fp.close() fp = open('/var/log/kolab/setup.out.log', 'w') - fp.write(stdoutdata) + fp.write(utils.ensure_str(stdoutdata, 'latin-1')) fp.close() log.debug(_("Setup DS stdout:"), level=8)
View file
pykolab-0.9.0.tar.gz/pykolab/setup/setup_mysql.py
Changed
@@ -181,54 +181,35 @@ confirm=True ) - p1 = subprocess.Popen( - - 'echo', - 'UPDATE mysql.user SET Password=PASSWORD(\'%s\') WHERE User=\'root\';' % ( - mysql_root_password - ) - , - stdout=subprocess.PIPE - ) - - p2 = subprocess.Popen('mysql', stdin=p1.stdout) - p1.stdout.close() - p2.communicate() - - p1 = subprocess.Popen( - - 'echo', - "UPDATE mysql.user SET authentication_string=PASSWORD('%s') WHERE User='root';" % ( - mysql_root_password - ) - , - stdout=subprocess.PIPE - ) - - p2 = subprocess.Popen('mysql', stdin=p1.stdout) - p1.stdout.close() - p2.communicate() - - p1 = subprocess.Popen( - - 'echo', - """ - UPDATE mysql.user - SET plugin='mysql_native_password' - WHERE User='root' AND plugin='auth_socket'; - """ - , - stdout=subprocess.PIPE - ) + mysql_commands = + "UPDATE mysql.user SET Password=PASSWORD('%s') WHERE User='root';" % ( + mysql_root_password + ), + "UPDATE mysql.user SET authentication_string=PASSWORD('%s') WHERE User='root';" % ( + mysql_root_password + ), + """ + UPDATE mysql.user + SET plugin='mysql_native_password' + WHERE User='root' AND plugin='auth_socket'; + """, + "SET PASSWORD FOR 'root'@localhost = PASSWORD('%s');" % (mysql_root_password), + "FLUSH PRIVILEGES;" + + + for mysql_command in mysql_commands: + p1 = subprocess.Popen( + + 'echo', + mysql_command + , + stdout=subprocess.PIPE + ) - p2 = subprocess.Popen('mysql', stdin=p1.stdout) - p1.stdout.close() - p2.communicate() + p2 = subprocess.Popen('mysql', stdin=p1.stdout) + p1.stdout.close() + p2.communicate() - p1 = subprocess.Popen('echo', 'FLUSH PRIVILEGES;', stdout=subprocess.PIPE) - p2 = subprocess.Popen('mysql', stdin=p1.stdout) - p1.stdout.close() - p2.communicate() socket_path = None socket_paths =
View file
pykolab-0.9.0.tar.gz/pykolab/telemetry.py
Changed
@@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 # # Copyright 2010-2013 Kolab Systems AG (http://www.kolabsys.com) #
View file
pykolab-0.9.0.tar.gz/pykolab/utils.py
Changed
@@ -398,6 +398,9 @@ if 'sn' in result: result'surname' = ensure_str(result'sn').replace(' ', '') + if 'givenname' in result: + result'givenname' = ensure_str(result'givenname').replace(' ', '') + if 'mail' in result: if isinstance(result'mail', list): result'mail' = result'mail'0
View file
pykolab-0.9.0.tar.gz/pykolab/wap_client/__init__.py
Changed
@@ -1,15 +1,18 @@ import json +import sys try: import httplib except ImportError: import http.client as httplib -import urllib -import sys try: from urlparse import urlparse except ImportError: from urllib.parse import urlparse +try: + from urllib import urlencode +except ImportError: + from urllib.parse import urlencode import pykolab @@ -447,7 +450,7 @@ conn.set_debuglevel(9) if get is not None: - _get = "?%s" % (urllib.urlencode(get)) + _get = "?%s" % (urlencode(get)) else: _get = ""
View file
pykolab-0.9.0.tar.gz/pykolab/xml/contact.py
Changed
@@ -14,6 +14,9 @@ pass def contact_from_string(string): + if isinstance(string, bytes): + string = string.decode('utf-8') + _xml = kolabformat.readContact(string, False) return Contact(_xml)
View file
pykolab-0.9.0.tar.gz/pykolab/xml/event.py
Changed
@@ -31,6 +31,8 @@ return Event(from_ical=ical, from_string=string) def event_from_string(string): + if isinstance(string, bytes): + string = string.decode('utf-8') return Event(from_string=string) def event_from_message(message):
View file
pykolab-0.9.0.tar.gz/pykolab/xml/note.py
Changed
@@ -7,6 +7,8 @@ from pykolab.xml.utils import ustr def note_from_string(string): + if isinstance(string, bytes): + string = string.decode('utf-8') _xml = kolabformat.readNote(string, False) return Note(_xml)
View file
pykolab-0.9.0.tar.gz/pykolab/xml/todo.py
Changed
@@ -19,6 +19,8 @@ return Todo(from_ical=ical, from_string=string) def todo_from_string(string): + if isinstance(string, bytes): + string = string.decode('utf-8') return Todo(from_string=string) def todo_from_message(message):
View file
pykolab-0.9.0.tar.gz/saslauthd.py
Changed
@@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 # # Copyright 2010-2013 Kolab Systems AG (http://www.kolabsys.com) #
View file
pykolab-0.9.0.tar.gz/setup-kolab.py
Changed
@@ -1,4 +1,4 @@ -#!/usr/bin/python -u +#!/usr/bin/python3 -u # -*- coding: utf-8 -*- # # Copyright 2010-2013 Kolab Systems AG (http://www.kolabsys.com)
View file
pykolab-0.9.0.tar.gz/share/templates/guam.sys.config.tpl
Changed
@@ -26,7 +26,9 @@ }, { tls_config, - { certfile, "/etc/pki/cyrus-imapd/cyrus-imapd.pem" } + { certfile, "/etc/pki/cyrus-imapd/cyrus-imapd.pem" }, + { cacertfile, "/etc/pki/cyrus-imapd/cyrus-imapd-ca.pem" }, + { keyfile, "/etc/pki/cyrus-imapd/cyrus-imapd-key.pem" } } @@ -43,7 +45,9 @@ }, { tls_config, - { certfile, "/etc/pki/cyrus-imapd/cyrus-imapd.pem" } + { certfile, "/etc/pki/cyrus-imapd/cyrus-imapd.pem" }, + { cacertfile, "/etc/pki/cyrus-imapd/cyrus-imapd-ca.pem" }, + { keyfile, "/etc/pki/cyrus-imapd/cyrus-imapd-key.pem" } }
View file
pykolab-0.9.0.tar.gz/share/templates/imapd.conf.tpl
Changed
@@ -14,7 +14,7 @@ auth_mech: pts pts_module: ldap ptloader_sock: /var/lib/imap/socket/ptsock -ldap_servers: $ldap_servers +ldap_uri: $ldap_uri ldap_sasl: 0 ldap_base: $ldap_base ldap_bind_dn: $ldap_bind_dn @@ -33,7 +33,7 @@ unixhierarchysep: 1 virtdomains: userid annotation_definitions: /etc/imapd.annotations.conf -sieve_extensions: fileinto reject envelope body vacation imapflags notify include regex subaddress relational copy date index +sieve_extensions: fileinto reject envelope body vacation imap4flags notify include regex subaddress relational copy date index allowallsubscribe: 0 allowusermoves: 1 altnamespace: 1
View file
pykolab-0.9.0.tar.gz/share/templates/roundcubemail/acl.inc.php.tpl
Changed
@@ -7,8 +7,6 @@ \$config'acl_groups' = true; \$config'acl_group_prefix' = 'group:'; - if (file_exists(RCUBE_CONFIG_DIR . '/' . \$_SERVER"HTTP_HOST" . '/' . basename(__FILE__))) { - include_once(RCUBE_CONFIG_DIR . '/' . \$_SERVER"HTTP_HOST" . '/' . basename(__FILE__)); + if (file_exists(RCUBE_CONFIG_DIR . '/' . (\$_SERVER"HTTP_HOST" ?? null) . '/' . basename(__FILE__))) { + include_once(RCUBE_CONFIG_DIR . '/' . (\$_SERVER"HTTP_HOST" ?? null) . '/' . basename(__FILE__)); } - -?>
View file
pykolab-0.9.0.tar.gz/share/templates/roundcubemail/calendar.inc.php.tpl
Changed
@@ -24,7 +24,7 @@ \$config'calendar_resources_driver' = 'ldap'; - \$config'calendar_resources_directory' = array( + \$config'calendar_resources_directory' = 'name' => 'Kolab Resources', 'hosts' => 'localhost', 'port' => 389, @@ -39,11 +39,11 @@ 'search_filter' => '(&(objectClass=inetOrgPerson)(mail=%fu))', 'ldap_version' => 3, 'filter' => '$ldap_resource_filter', - 'search_fields' => array('cn'), - 'sort' => array('cn'), + 'search_fields' => 'cn', + 'sort' => 'cn', 'scope' => 'sub', 'fuzzy_search' => true, - 'fieldmap' => array( + 'fieldmap' => // Internal => LDAP 'name' => 'cn', 'email' => 'mail', @@ -54,20 +54,18 @@ // these mappings are required for owner display 'phone' => 'telephoneNumber', 'mobile' => 'mobile', - ), + , - 'class_type_map' => array( + 'class_type_map' => 'kolabsharedfolder' => 'resource', 'groupofuniquenames' => 'collection', - ), + , - 'groups' => array( + 'groups' => 'name_attr' => 'cn', - ), - ); + , + ; - if (file_exists(RCUBE_CONFIG_DIR . '/' . \$_SERVER"HTTP_HOST" . '/' . basename(__FILE__))) { - include_once(RCUBE_CONFIG_DIR . '/' . \$_SERVER"HTTP_HOST" . '/' . basename(__FILE__)); + if (file_exists(RCUBE_CONFIG_DIR . '/' . (\$_SERVER'HTTP_HOST' ?? '') . '/' . basename(__FILE__))) { + include_once(RCUBE_CONFIG_DIR . '/' . (\$_SERVER'HTTP_HOST' ?? '') . '/' . basename(__FILE__)); } - -?>
View file
pykolab-0.9.0.tar.gz/share/templates/roundcubemail/config.inc.php.tpl
Changed
@@ -1,10 +1,10 @@ <?php - \$config = array(); + \$config = ; \$config'db_dsnw' = '$mysql_uri'; - \$config'session_domain' = ''; \$config'des_key' = "$des_key"; + \$config'session_domain' = ''; \$config'username_domain' = '$primary_domain'; \$config'use_secure_urls' = true; \$config'assets_path' = '/roundcubemail/assets/'; @@ -13,20 +13,20 @@ \$config'mail_domain' = ''; // IMAP Server Settings - \$config'default_host' = 'tls://localhost'; - \$config'default_port' = 143; + \$config'default_host' = 'ssl://localhost'; + \$config'default_port' = 9993; \$config'imap_delimiter' = '/'; \$config'imap_force_lsub' = true; // IMAP Connection TLS settings, adjust for Production // Required for PHP >= 5.6 - \$config'imap_conn_options' = Array( - 'ssl' => Array( + \$config'imap_conn_options' = + 'ssl' => 'verify_peer_name' => false, 'verify_peer' => false, 'allow_self_signed' => true - ) - ); + + ; // Caching and storage settings \$config'imap_cache' = 'db'; @@ -40,17 +40,17 @@ \$config'smtp_port' = 587; \$config'smtp_user' = '%u'; \$config'smtp_pass' = '%p'; - \$config'smtp_helo_host' = \$_SERVER"HTTP_HOST"; + \$config'smtp_helo_host' = \$_SERVER'HTTP_HOST' ?? null; // SMTP Connection TLS settings, adjust for Production // Required for PHP >= 5.6 - \$config'smtp_conn_options' = Array( - 'ssl' => Array( + \$config'smtp_conn_options' = + 'ssl' => 'verify_peer_name' => false, 'verify_peer' => false, 'allow_self_signed' => true - ) - ); + + ; // LDAP Settings \$config'ldap_cache' = 'db'; @@ -66,7 +66,7 @@ \$config'mdn_use_from' = true; // Plugins - \$config'plugins' = array( + \$config'plugins' = 'kolab_auth', 'acl', 'archive', @@ -88,8 +88,7 @@ 'tasklist', // contextmenu must be after kolab_addressbook (#444) 'contextmenu', - ); - + ; // Do not show deleted messages, mark deleted messages as read, // and flag them as deleted instead of moving them to the Trash @@ -110,7 +109,7 @@ \$config'spellcheck_ignore_caps' = true; \$config'spellcheck_ignore_nums' = true; \$config'spellcheck_ignore_syms' = true; - \$config'spellcheck_languages' = array( + \$config'spellcheck_languages' = 'da' => 'Dansk', 'de' => 'Deutsch', 'en' => 'English', @@ -121,13 +120,11 @@ 'pt' => 'Português', 'ru' => 'Русский', 'sv' => 'Svenska' - ); + ; \$config'undo_timeout' = 10; - \$config'upload_progress' = 2; \$config'address_template' = '{street}<br/>{locality} {zipcode}<br/>{country} {region}'; - \$config'preview_pane' = true; - \$config'preview_pane_mark_read' = 0; + \$config'mail_read_time' = 0; \$config'autoexpand_threads' = 2; \$config'top_posting' = 0; @@ -136,28 +133,30 @@ \$config'mdn_default' = false; \$config'dsn_default' = false; \$config'reply_same_folder' = false; + \$config'htmleditor' = 0; - if (file_exists(RCUBE_CONFIG_DIR . '/' . \$_SERVER"HTTP_HOST" . '/' . basename(__FILE__))) { - include_once(RCUBE_CONFIG_DIR . '/' . \$_SERVER"HTTP_HOST" . '/' . basename(__FILE__)); + if (file_exists(RCUBE_CONFIG_DIR . '/' . (\$_SERVER'HTTP_HOST' ?? '') . '/' . basename(__FILE__))) { + include_once(RCUBE_CONFIG_DIR . '/' . (\$_SERVER'HTTP_HOST' ?? '') . '/' . basename(__FILE__)); } // Re-apply mandatory settings here. - \$config'debug_level' = 1; \$config'devel_mode' = false; \$config'log_driver' = 'file'; \$config'log_date_format' = 'd-M-Y H:i:s,u O'; \$config'syslog_id' = 'roundcube'; \$config'syslog_facility' = LOG_USER; - \$config'smtp_log' = false; - \$config'log_logins' = true; - \$config'log_session' = false; + \$config'sql_debug' = false; \$config'memcache_debug' = false; \$config'imap_debug' = false; \$config'ldap_debug' = false; \$config'smtp_debug' = false; + \$config'smtp_log' = false; + \$config'log_logins' = true; + \$config'log_session' = false; + \$config'skin' = '$skin'; \$config'skin_include_php' = false; \$config'mime_magic' = null; @@ -170,16 +169,15 @@ \$config'archive_mbox' = 'Archive'; // The Kolab daemon by default creates 'Spam' \$config'junk_mbox' = 'Spam'; - \$config'default_folders' = array('INBOX', 'Drafts', 'Sent', 'Spam', 'Trash', 'Archive'); \$config'address_book_type' = 'ldap'; \$config'autocomplete_min_length' = 3; \$config'autocomplete_threads' = 0; \$config'autocomplete_max' = 15; - \$config'ldap_public' = array( - 'kolab_addressbook' => array( + \$config'ldap_public' = + 'kolab_addressbook' => 'name' => 'Global Address Book', - 'hosts' => Array('localhost'), + 'hosts' => 'localhost', 'port' => 389, 'use_tls' => false, 'base_dn' => '$ldap_user_base_dn', @@ -191,12 +189,12 @@ 'search_bind_pw' => '$ldap_service_bind_pw', 'search_filter' => '(&(objectClass=inetOrgPerson)(mail=%fu))', 'writable' => false, - 'LDAP_Object_Classes' => array("top", "inetOrgPerson"), - 'required_fields' => array("cn", "sn", "mail"), + 'LDAP_Object_Classes' => "top", "inetOrgPerson", + 'required_fields' => "cn", "sn", "mail", 'LDAP_rdn' => 'uid', - 'ldap_version' => 3, // using LDAPv3 - 'search_fields' => array('displayname', 'mail'), - 'sort' => array('displayname', 'sn', 'givenname', 'cn'), + 'ldap_version' => 3, + 'search_fields' => 'displayname', 'mail', + 'sort' => 'displayname', 'sn', 'givenname', 'cn', 'scope' => 'sub', 'filter' => '(objectClass=inetOrgPerson)', 'vlv' => false, @@ -204,46 +202,42 @@ 'fuzzy_search' => true, 'sizelimit' => '0', 'timelimit' => '0', - 'fieldmap' => Array( - // Roundcube => LDAP - 'name' => 'displayName', - 'surname' => 'sn', - 'firstname' => 'givenName', - 'middlename' => 'initials', - 'email:primary' => 'mail', - 'email:alias' => 'alias', - 'email:personal' => 'mailalternateaddress', - 'phone:main' => 'telephoneNumber', - 'phone:work' => 'alternateTelephoneNumber', - 'phone:mobile' => 'mobile', - 'phone:work2' => 'blackberry', - 'jobtitle' => 'title', - 'manager' => 'manager', - 'assistant' => 'secretary', - 'photo' => 'jpegphoto' - ), - 'groups' => Array( - 'base_dn' => '$ldap_group_base_dn', - 'filter' => '(&' . '$ldap_group_filter' . '(mail=*))', - 'object_classes' => Array("top", "groupOfUniqueNames"), - 'member_attr' => 'uniqueMember', - ), - ), - ); - - \$config'autocomplete_addressbooks' = Array( + 'fieldmap' => + // Roundcube => LDAP + 'name' => 'displayName', + 'surname' => 'sn', + 'firstname' => 'givenName', + 'middlename' => 'initials', + 'email:primary' => 'mail', + 'email:alias' => 'alias', + 'email:personal' => 'mailalternateaddress', + 'phone:main' => 'telephoneNumber', + 'phone:work' => 'alternateTelephoneNumber', + 'phone:mobile' => 'mobile', + 'phone:work2' => 'blackberry', + 'jobtitle' => 'title', + 'manager' => 'manager', + 'assistant' => 'secretary', + 'photo' => 'jpegphoto' + , + 'groups' => + 'base_dn' => '$ldap_group_base_dn', + 'filter' => '(&' . '$ldap_group_filter' . '(mail=*))', + 'object_classes' => "top", "groupOfUniqueNames", + 'member_attr' => 'uniqueMember', + , + , + ; + + \$config'autocomplete_addressbooks' = 'kolab_addressbook' - ); + ; \$config'autocomplete_single' = true; - \$config'htmleditor' = 0; - - \$config'kolab_http_request' = Array( + \$config'kolab_http_request' = 'ssl_verify_host' => false, 'ssl_verify_peer' => false, - ); + ; @include('/etc/roundcubemail/kolab_syncroton.inc.php'); - -?>
View file
pykolab-0.9.0.tar.gz/share/templates/roundcubemail/kolab_addressbook.inc.php.tpl
Changed
@@ -16,5 +16,3 @@ // %n - Folder name // %i - Folder UUID \$config'kolab_addressbook_carddav_url' = 'http://%h/iRony/addressbooks/%u/%i'; - -?>
View file
pykolab-0.9.0.tar.gz/share/templates/roundcubemail/kolab_auth.inc.php.tpl
Changed
@@ -2,36 +2,36 @@ // The id of the LDAP address book (which refers to the rcmail_config'ldap_public') // or complete addressbook definition array. - \$config'kolab_auth_addressbook' = Array( - 'name' => 'Kolab Auth', - 'hosts' => Array('localhost'), - 'port' => 389, - 'use_tls' => false, - 'user_specific' => false, - 'base_dn' => '$ldap_user_base_dn', - 'bind_dn' => '$ldap_service_bind_dn', - 'bind_pass' => '$ldap_service_bind_pw', - 'writable' => false, - 'ldap_version' => 3, // using LDAPv3 - 'fieldmap' => Array( - 'name' => 'displayname', - 'email' => 'mail', - 'email:alias' => 'alias', - 'role' => 'nsroledn', - ), - 'sort' => 'displayname', - 'scope' => 'sub', - 'filter' => '(objectClass=*)', - 'fuzzy_search' => true, - 'sizelimit' => '0', - 'timelimit' => '0', - 'groups' => Array( - 'base_dn' => '$ldap_group_base_dn', - 'filter' => '$ldap_group_filter', - 'object_classes' => Array('top', 'groupOfUniqueNames'), - 'member_attr' => 'uniqueMember', - ), - ); + \$config'kolab_auth_addressbook' = + 'name' => 'Kolab Auth', + 'hosts' => 'localhost', + 'port' => 389, + 'use_tls' => false, + 'user_specific' => false, + 'base_dn' => '$ldap_user_base_dn', + 'bind_dn' => '$ldap_service_bind_dn', + 'bind_pass' => '$ldap_service_bind_pw', + 'writable' => false, + 'ldap_version' => 3, + 'fieldmap' => + 'name' => 'displayname', + 'email' => 'mail', + 'email:alias' => 'alias', + 'role' => 'nsroledn', + , + 'sort' => 'displayname', + 'scope' => 'sub', + 'filter' => '(objectClass=*)', + 'fuzzy_search' => true, + 'sizelimit' => '0', + 'timelimit' => '0', + 'groups' => + 'base_dn' => '$ldap_group_base_dn', + 'filter' => '$ldap_group_filter', + 'object_classes' => 'top', 'groupOfUniqueNames', + 'member_attr' => 'uniqueMember', + , + ; // This will overwrite defined filter @@ -45,7 +45,7 @@ \$config'kolab_auth_alias' = 'alias'; \$config'kolab_auth_email' = 'email'; - if (preg_match('/\/helpdesk-login\//', \$_SERVER"REQUEST_URI") ) { + if (preg_match('/\/helpdesk-login\//', \$_SERVER'REQUEST_URI' ?? '')) { // Login and password of the admin user. Enables "Login As" feature. \$config'kolab_auth_admin_login' = '$imap_admin_login'; @@ -63,8 +63,6 @@ // which adds privilege to login as another user. \$config'kolab_auth_group' = 'Kolab Helpdesk'; - if (file_exists(RCUBE_CONFIG_DIR . '/' . \$_SERVER"HTTP_HOST" . '/' . basename(__FILE__))) { - include_once(RCUBE_CONFIG_DIR . '/' . \$_SERVER"HTTP_HOST" . '/' . basename(__FILE__)); + if (file_exists(RCUBE_CONFIG_DIR . '/' . (\$_SERVER"HTTP_HOST" ?? '') . '/' . basename(__FILE__))) { + include_once(RCUBE_CONFIG_DIR . '/' . (\$_SERVER"HTTP_HOST" ?? ''). '/' . basename(__FILE__)); } - -?>
View file
pykolab-0.9.0.tar.gz/share/templates/roundcubemail/kolab_delegation.inc.php.tpl
Changed
@@ -11,4 +11,3 @@ // Remove all user identities which do not match the users primary or alias // addresses and delegators addresses \$config'kolab_delegation_purge_identities' = false; -?>
View file
pykolab-0.9.0.tar.gz/share/templates/roundcubemail/kolab_files.inc.php.tpl
Changed
@@ -4,7 +4,7 @@ \$config'kolab_files_url' = '/chwala/'; // List of files list columns. Available are: name, size, mtime, type -\$config'kolab_files_list_cols' = array('name', 'mtime', 'size'); +\$config'kolab_files_list_cols' = 'name', 'mtime', 'size'; // Name of the column to sort files list by \$config'kolab_files_sort_col' = 'name'; @@ -25,4 +25,3 @@ // The LDAP search filter will be combined with search queries \$config'kolab_files_users_filter' = ''; -?>
View file
pykolab-0.9.0.tar.gz/share/templates/roundcubemail/kolab_folders.inc.php.tpl
Changed
@@ -14,8 +14,6 @@ \$config'kolab_folders_mail_outbox' = ''; \$config'kolab_folders_mail_wastebasket' = 'Trash'; - if (file_exists(RCUBE_CONFIG_DIR . '/' . \$_SERVER"HTTP_HOST" . '/' . basename(__FILE__))) { - include_once(RCUBE_CONFIG_DIR . '/' . \$_SERVER"HTTP_HOST" . '/' . basename(__FILE__)); + if (file_exists(RCUBE_CONFIG_DIR . '/' . (\$_SERVER'HTTP_HOST' ?? '') . '/' . basename(__FILE__))) { + include_once(RCUBE_CONFIG_DIR . '/' . (\$_SERVER'HTTP_HOST' ?? '') . '/' . basename(__FILE__)); } - -?>
View file
pykolab-0.9.0.tar.gz/share/templates/roundcubemail/libkolab.inc.php.tpl
Changed
@@ -2,8 +2,8 @@ \$config'kolab_freebusy_server' = '/freebusy'; - if (file_exists(RCUBE_CONFIG_DIR . '/' . \$_SERVER"HTTP_HOST" . '/' . basename(__FILE__))) { - include_once(RCUBE_CONFIG_DIR . '/' . \$_SERVER"HTTP_HOST" . '/' . basename(__FILE__)); + if (file_exists(RCUBE_CONFIG_DIR . '/' . (\$_SERVER'HTTP_HOST' ?? '') . '/' . basename(__FILE__))) { + include_once(RCUBE_CONFIG_DIR . '/' . (\$_SERVER'HTTP_HOST' ?? '') . '/' . basename(__FILE__)); } \$config'kolab_cache' = true; @@ -12,5 +12,3 @@ \$config'kolab_ssl_verify_peer' = false; \$config'kolab_use_subscriptions' = true; - -?>
View file
pykolab-0.9.0.tar.gz/share/templates/roundcubemail/managesieve.inc.php.tpl
Changed
@@ -8,7 +8,7 @@ \$config'managesieve_default' = '/etc/dovecot/sieve/global'; \$config'managesieve_mbox_encoding' = 'UTF-8'; \$config'managesieve_replace_delimiter' = ''; - \$config'managesieve_disabled_extensions' = array(); + \$config'managesieve_disabled_extensions' = ; \$config'managesieve_debug' = false; \$config'managesieve_vacation' = 1; @@ -16,16 +16,14 @@ \$config'managesieve_kolab_master' = true; // ManageSieve Connection TLS settings, adjust for Production - \$config'managesieve_conn_options' = Array( - 'ssl' => Array( + \$config'managesieve_conn_options' = + 'ssl' => 'verify_peer_name' => false, 'verify_peer' => false, 'allow_self_signed' => true - ) - ); + + ; - if (file_exists(RCUBE_CONFIG_DIR . '/' . \$_SERVER"HTTP_HOST" . '/' . basename(__FILE__))) { - include_once(RCUBE_CONFIG_DIR . '/' . \$_SERVER"HTTP_HOST" . '/' . basename(__FILE__)); + if (file_exists(RCUBE_CONFIG_DIR . '/' . (\$_SERVER'HTTP_HOST' ?? '') . '/' . basename(__FILE__))) { + include_once(RCUBE_CONFIG_DIR . '/' . (\$_SERVER'HTTP_HOST' ?? '') . '/' . basename(__FILE__)); } - -?>
View file
pykolab-0.9.0.tar.gz/share/templates/roundcubemail/mimetypes.php.tpl
Changed
@@ -1,6 +1,6 @@ <?php -return array( +return 'xls' => 'application/vnd.ms-excel', 'xlm' => 'application/vnd.ms-excel', 'xla' => 'application/vnd.ms-excel', @@ -44,6 +44,4 @@ 'rar' => 'application/x-rar-compressed', 'vcf' => 'text/vcard', 'ics' => 'text/calendar', -); - -?> \ No newline at end of file +;
View file
pykolab-0.9.0.tar.gz/share/templates/roundcubemail/password.inc.php.tpl
Changed
@@ -26,7 +26,7 @@ // ----------------------------------- // LDAP server name to connect to. // You can provide one or several hosts in an array in which case the hosts are tried from left to right. - // Exemple: array('ldap1.exemple.com', 'ldap2.exemple.com'); + // Exemple: 'ldap1.exemple.com', 'ldap2.exemple.com'; // Default: 'localhost' \$config'password_ldap_host' = 'localhost'; @@ -148,8 +148,6 @@ // Whenever the password is changed, the attribute will be updated if set \$config'password_ldap_samba_lchattr' = ''; - if (file_exists(RCUBE_CONFIG_DIR . '/' . \$_SERVER"HTTP_HOST" . '/' . basename(__FILE__))) { - include_once(RCUBE_CONFIG_DIR . '/' . \$_SERVER"HTTP_HOST" . '/' . basename(__FILE__)); + if (file_exists(RCUBE_CONFIG_DIR . '/' . (\$_SERVER'HTTP_HOST' ?? '') . '/' . basename(__FILE__))) { + include_once(RCUBE_CONFIG_DIR . '/' . (\$_SERVER'HTTP_HOST' ?? '') . '/' . basename(__FILE__)); } - -?>
View file
pykolab-0.9.0.tar.gz/share/templates/roundcubemail/recipient_to_contact.inc.php.tpl
Changed
@@ -1,4 +1,3 @@ <?php - \$config'recipient_to_contact_addressbooks' = array(); + \$config'recipient_to_contact_addressbooks' = ; \$config'recipient_to_contact_enabled_by_default' = true; -?> \ No newline at end of file
View file
pykolab-0.9.0.tar.gz/share/templates/roundcubemail/terms.inc.php.tpl
Changed
@@ -15,8 +15,6 @@ // always request terms agreement after login \$config'terms_always' = false; - if (file_exists(RCUBE_CONFIG_DIR . '/' . \$_SERVER"HTTP_HOST" . '/' . basename(__FILE__))) { - include_once(RCUBE_CONFIG_DIR . '/' . \$_SERVER"HTTP_HOST" . '/' . basename(__FILE__)); + if (file_exists(RCUBE_CONFIG_DIR . '/' . (\$_SERVER'HTTP_HOST' ?? '') . '/' . basename(__FILE__))) { + include_once(RCUBE_CONFIG_DIR . '/' . (\$_SERVER'HTTP_HOST' ?? '') . '/' . basename(__FILE__)); } - -?>
View file
pykolab-0.9.0.tar.gz/ucs/kolab_sieve.py
Changed
@@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 # # Copyright 2010-2013 Kolab Systems AG (http://www.kolabsys.com) #
View file
pykolab-0.9.0.tar.gz/ucs/listener.py
Changed
@@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 # # Copyright 2010-2013 Kolab Systems AG (http://www.kolabsys.com) #
View file
pykolab-0.9.0.tar.gz/wallace.py
Changed
@@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 # # Copyright 2010-2013 Kolab Systems AG (http://www.kolabsys.com) #
View file
pykolab-0.9.0.tar.gz/wallace/__init__.py
Changed
@@ -57,7 +57,12 @@ if 'module' in kwargs: # Cause the previous modules to be skipped - wallace_modules = wallace_modules(wallace_modules.index(kwargs'module') + 1): + # Note that the actual stage in which the message exists may not be a module that + # is loaded, thereby causing an exception of ValueError + try: + wallace_modules = wallace_modules(wallace_modules.index(kwargs'module') + 1): + except ValueError: + return log.debug(_l("Wallace modules: %r") % (wallace_modules), level=8) @@ -149,6 +154,50 @@ break +class WallaceSMTPChannel(smtpd.SMTPChannel): + callback = None + + def __init__(self, connection, address, callback): + self.callback = callback + if conf.debuglevel > 8: + smtpd.DEBUGSTREAM = pykolab.logger.StderrToLogger(log) + super().__init__(self, connection, address) + + def data_header(self, mailfrom, rcpttos): + return "X-Kolab-From: " + mailfrom + "\r\n" + \ + "X-Kolab-To: " + ', '.join(rcpttos) + "\r\n" + + def process_message(self, peer, mailfrom, rcpttos, data, **kwargs): + """ + We have retrieved the message. This should be as fast as possible, + and not ever block. + """ + + header = self.data_header(mailfrom, rcpttos) + + try: + (fp, filename) = tempfile.mkstemp(dir="/var/spool/pykolab/wallace/") + + # @TODO: and add line separator (\n or \r\n?) + # we should make sure there's only one line separator between + # kolab headers and the original message (data) + os.write(fp, bytes(header.encode("UTF-8"))) + os.write(fp, data) + except Exception as errmsg: + log.warning( + _l("failed to write to file: %s" % (errmsg)) + ) + finally: + os.close(fp) + + self.callback(filename) + + return "250 OK Message %s queued" % (filename) + + def loop(self): + asyncore.loop() + + class WallaceDaemon: heartbeat = None timer = None @@ -340,25 +389,22 @@ time.sleep(0.5) pair = s.accept() - log.debug( - _l("Accepted connection %r with address %r") % ( - pair if pair is not None else (None, None) - ), - level=8 - ) if pair is not None: - self.current_connections += 1 connection, address = pair + log.debug( + _l("Accepted connection %r with address %r") % ( + connection, address + ), + level=8 + ) - _smtpd = smtpd - # Set DEBUGSTREAM of smtpd to log to pykolab logger - if conf.debuglevel > 8: - _smtpd.DEBUGSTREAM = pykolab.logger.StderrToLogger(log) + def callback(filename): + self.pool.apply_async(pickup_message, (filename, (self.modules))) - log.debug(_l("Creating SMTPChannel for accepted message"), level=8) - _smtpd.SMTPChannel(self, connection, address) - asyncore.loop() + self.current_connections += 1 + WallaceSMTPChannel(connection, address, callback).loop() + self.current_connections -= 1 else: log.error(_l("Socket accepted, but (conn, address) tuple is None.")) @@ -373,13 +419,6 @@ self.timer.cancel() self.timer.join() - # pylint: disable=no-self-use - def data_header(self, mailfrom, rcpttos): - COMMASPACE = ', ' - - return "X-Kolab-From: " + mailfrom + "\r\n" + \ - "X-Kolab-To: " + COMMASPACE.join(rcpttos) + "\r\n" - def pickup_spool_messages(self, sync=False): # Mind you to include the trailing slash pickup_path = '/var/spool/pykolab/wallace/' @@ -469,30 +508,6 @@ self.current_connections -= 1 - def process_message(self, peer, mailfrom, rcpttos, data): - """ - We have retrieved the message. This should be as fast as possible, - and not ever block. - """ - - header = self.data_header(mailfrom, rcpttos) - - (fp, filename) = tempfile.mkstemp(dir="/var/spool/pykolab/wallace/") - - # @TODO: and add line separator (\n or \r\n?) - # we should make sure there's only one line separator between - # kolab headers and the original message (data) - os.write(fp, header) - os.write(fp, data) - os.close(fp) - - log.debug(_l("Started processing accepted message %s") % filename, level=8) - self.pool.apply_async(pickup_message, (filename, (self.modules))) - - self.current_connections -= 1 - - return "250 OK Message %s queued" % (filename) - def reload_config(self, *args, **kwargs): pass
View file
pykolab-0.9.0.tar.gz/wallace/module_footer.py
Changed
@@ -85,16 +85,17 @@ if not os.path.isdir(mybasepath): os.makedirs(mybasepath) - for stage in 'incoming', 'ACCEPT': + for stage in 'incoming': if not os.path.isdir(os.path.join(mybasepath, stage)): os.makedirs(os.path.join(mybasepath, stage)) + # FIXME: This section of the code is probably not needed since we do not ACCEPT the mail anymore if 'stage' in kw: log.debug(_("Issuing callback after processing to stage %s") % (kw'stage'), level=8) log.debug(_("Testing cb_action_%s()") % (kw'stage'), level=8) if hasattr(modules, 'cb_action_%s' % (kw'stage')): log.debug(_("Attempting to execute cb_action_%s()") % (kw'stage'), level=8) - exec('modules.cb_action_%s(%r, %r)' % (kw'stage','optout',filepath)) + exec('modules.cb_action_%s(%r, %r)' % (kw'stage','footer',filepath)) return log.debug(_("Executing module footer for %r, %r") % (args, kw), level=8) @@ -112,13 +113,28 @@ footer = {} footer_position = conf.get('wallace', 'footer_position') - footer_html_file = conf.get('wallace', 'footer_html') - footer_text_file = conf.get('wallace', 'footer_text') + footer_html_file = conf.get('wallace', 'footer_html') or '' + footer_text_file = conf.get('wallace', 'footer_text') or '' + sender_exceptions = conf.get('wallace', 'footer_sender_exceptions') + + if sender_exceptions: + sender = message.get("X-Kolab-From") + log.debug("Checking sender %r" % (sender), level=8) + + if sender: + for item in sender_exceptions.split(','): + item = item.strip() + regex = '@' + item.replace('*', '^@+').replace('.', '\\.') + '$' + if item == 'NONE': + regex = '^<>$' + + if re.search(regex, sender): + log.debug("Sender matches %s, pass along" % (item), level=8) + return filepath if not os.path.isfile(footer_text_file) and not os.path.isfile(footer_html_file): - log.warning(_("No contents configured for footer module")) - exec('modules.cb_action_%s(%r, %r)' % ('ACCEPT','footer', filepath)) - return + log.warning(_("No contents configured for footer module, pass along")) + return filepath if os.path.isfile(footer_text_file): footer'plain' = open(footer_text_file, 'r').read() @@ -131,8 +147,7 @@ footer'html' = '<p>' + footer'plain' + '</p>' if footer'plain' == "" and footer'html' == "<p></p>": - exec('modules.cb_action_%s(%r, %r)' % ('ACCEPT','footer', filepath)) - return + return filepath footer_added = False @@ -142,8 +157,7 @@ pass if _footer_added == "YES": - exec('modules.cb_action_%s(%r, %r)' % ('ACCEPT','footer', filepath)) - return + return filepath for part in message.walk(): disposition = None @@ -174,12 +188,15 @@ footer_added = set_part_content(part, content) if footer_added: - log.debug("Footer attached.") message.add_header("X-Wallace-Footer", "YES") - (fp, new_filepath) = tempfile.mkstemp(dir="/var/spool/pykolab/wallace/footer/ACCEPT") - os.write(fp, message.as_string()) - os.close(fp) - os.unlink(filepath) + (fp, new_filepath) = tempfile.mkstemp(dir="/var/spool/pykolab/wallace/footer/incoming") + + log.debug("Footer attached, saving mail to %s and passing along" % (new_filepath), level=8) + + os.write(fp, message.as_string()) + os.close(fp) + os.unlink(filepath) + filepath = new_filepath - exec('modules.cb_action_%s(%r, %r)' % ('ACCEPT','footer', new_filepath)) + return filepath
View file
pykolab-0.9.0.tar.gz/wallace/module_gpgencrypt.py
Changed
@@ -21,7 +21,6 @@ import tempfile import time -from email import message_from_string from email.mime.base import MIMEBase from email.mime.text import MIMEText from email.parser import Parser
View file
pykolab-0.9.0.tar.gz/wallace/module_invitationpolicy.py
Changed
@@ -34,7 +34,7 @@ import traceback import re -from email import message_from_string +from email import message_from_bytes from email.parser import Parser from email.utils import formataddr from email.utils import getaddresses @@ -706,13 +706,15 @@ if local_domains is not None: local_domains = list(set(local_domains.keys())) - if not email_address.split('@')1 in local_domains: + domain = email_address.split('@')1 + + if not domain in local_domains: user_dn_from_email_address.cacheemail_address = None return None log.debug(_("Checking if email address %r belongs to a local user") % (email_address), level=8) - user_dn = auth.find_user_dn(email_address, True) + user_dn = auth.find_user_dn(email_address, True, domain) if isinstance(user_dn, string_types): log.debug(_("User DN: %r") % (user_dn), level=8) @@ -807,7 +809,7 @@ if not imap_proxy_auth(user_rec): return result - folders = imap.get_metadata('*') + folders = imap.get_metadata('*', FOLDER_TYPE_ANNOTATION) log.debug( _("List %r folders for user %r: %r") % ( @@ -820,16 +822,17 @@ (ns_personal, ns_other, ns_shared) = imap.namespaces() + _type = _type.encode('utf-8') _folders = {} # Filter the folders by type relevance for folder, metadata in folders.items(): - key = '/shared' + FOLDER_TYPE_ANNOTATION + key = ('/shared' + FOLDER_TYPE_ANNOTATION).encode('utf-8') if key in metadata: if metadatakey.startswith(_type): _foldersfolder = metadata - key = '/private' + FOLDER_TYPE_ANNOTATION + key = ('/private' + FOLDER_TYPE_ANNOTATION).encode('utf-8') if key in metadata: if metadatakey.startswith(_type): _foldersfolder = metadata @@ -857,33 +860,25 @@ 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'): + key = ('/private' + FOLDER_TYPE_ANNOTATION).encode('utf-8') + if key in metadata and metadatakey.startswith(_type): + # store default,private and confidential folders in user record + if metadatakey.endswith(b'.default'): + if '_default_folder' not in user_rec: + user_rec'_default_folder' = folder + elif metadatakey.endswith(b'.confidential'): if '_confidential_folder' not in user_rec: user_rec'_confidential_folder' = folder - - continue - - if metadatakey.endswith('.private'): + elif metadatakey.endswith(b'.private'): if '_private_folder' not in user_rec: user_rec'_private_folder' = folder - continue + result.append(folder) + continue + + key = ('/shared' + FOLDER_TYPE_ANNOTATION).encode('utf-8') + if key in metadata and metadatakey.startswith(_type): + result.append(folder) # cache with user record user_rec'_imap_folders' = result @@ -914,16 +909,16 @@ res, data = imap.imap.m.fetch(num, '(UID RFC822)') try: - msguid = re.search(r"\WUID (\d+)", data00).group(1) + msguid = re.search(r"\WUID (\d+)", data00.decode('utf-8')).group(1) except Exception: log.error(_("No UID found in IMAP response: %r") % (data00)) continue try: if type == 'task': - event = todo_from_message(message_from_string(data01)) + event = todo_from_message(message_from_bytes(data01)) else: - event = event_from_message(message_from_string(data01)) + event = event_from_message(message_from_bytes(data01)) # find instance in a recurring series if recurrence_id and (event.is_recurring() or event.has_exceptions() or event.get_recurrence_id()): @@ -981,7 +976,7 @@ res, data = imap.imap.m.fetch(num, '(RFC822)') try: - event = event_from_message(message_from_string(data01)) + event = event_from_message(message_from_bytes(data01)) except Exception as errmsg: log.error(_("Failed to parse event from message %s/%s: %r") % (folder, num, errmsg)) continue @@ -1055,7 +1050,7 @@ def get_lock_key(user, uid): - return hashlib.md5("%s/%s" % (user'mail', uid)).hexdigest() + return hashlib.md5(("%s/%s" % (user'mail', uid)).encode('utf-8')).hexdigest() def update_object(object, user_rec, master=None): @@ -1123,7 +1118,7 @@ imap.folder_utf7(targetfolder), None, None, - saveobj.to_message(creator="Kolab Server <wallace@localhost>").as_string() + saveobj.to_message(creator="Kolab Server <wallace@localhost>").as_string().encode('utf-8') ) return result
View file
pykolab-0.9.0.tar.gz/wallace/module_resources.py
Changed
@@ -22,7 +22,7 @@ import datetime import sys -from email import message_from_string +from email import message_from_bytes from email.parser import Parser from email.utils import formataddr from email.utils import getaddresses @@ -665,7 +665,7 @@ typ, data = imap.imap.m.fetch(num, '(RFC822)') try: - event = event_from_message(message_from_string(data01)) + event = event_from_message(message_from_bytes(data01)) # pylint: disable=broad-except except Exception as errmsg: log.error(_("Failed to parse event from message %s/%s: %r") % (mailbox, num, errmsg)) @@ -915,14 +915,14 @@ typ, data = imap.imap.m.fetch(num, '(UID RFC822)') try: - msguid = re.search(r"\WUID (\d+)", data00).group(1) + msguid = re.search(r"\WUID (\d+)", data00.decode('utf-8')).group(1) # pylint: disable=broad-except except Exception: log.error(_("No UID found in IMAP response: %r") % (data00)) continue try: - event = event_from_message(message_from_string(data01)) + event = event_from_message(message_from_bytes(data01)) # pylint: disable=broad-except except Exception as e: log.error(_("Failed to parse event from message %s/%s: %r") % (mailbox, num, e)) @@ -977,14 +977,14 @@ typ, data = imap.imap.m.fetch(num, '(UID RFC822)') try: - msguid = re.search(r"\WUID (\d+)", data00).group(1) + msguid = re.search(r"\WUID (\d+)", data00.decode('utf-8')).group(1) # pylint: disable=broad-except except Exception: log.error(_("No UID found in IMAP response: %r") % (data00)) continue try: - event = event_from_message(message_from_string(data01)) + event = event_from_message(message_from_bytes(data01)) # find instance in a recurring series if recurrence_id and (event.is_recurring() or event.has_exceptions()):
View file
pykolab-0.9.0.tar.gz/wallace/modules.py
Changed
@@ -24,7 +24,6 @@ import sys import time -from email import message_from_string from email.message import Message from email.mime.base import MIMEBase from email.mime.message import MIMEMessage @@ -140,6 +139,11 @@ # NOTE: Use "127.0.0.1" here for IPv6 (see also the service # definition in master.cf). + # Sanity check. We run into this if we end up reading an empty file, because sender ends up being an empty list + if not sender or not recipients: + log.warning(_("Sending email failed from %r to %r") % (sender, recipients)) + return False + sl = pykolab.logger.StderrToLogger(log) smtplib.stderr = sl @@ -148,6 +152,10 @@ if conf.debuglevel > 8: smtp.set_debuglevel(1) + # Sender can't be a list + if isinstance(sender, list): + sender = sender0 + success = False attempt = 1
View file
pykolab.dsc
Changed
@@ -2,7 +2,8 @@ Source: pykolab Binary: pykolab, kolab-cli, kolab-conf, kolab-saslauthd, kolab-server, kolab-telemetry, kolab-xml, wallace Architecture: all -Version: 0.9.0-0~kolab1 +Version: 0.9.0.4-1~kolab1 +DEBTRANSFORM-RELEASE: 1 Maintainer: Jeroen van Meeuwen <vanmeeuwen@kolabsys.com> Uploaders: Paul Klos <kolab@klos2day.nl> Homepage: http://www.kolab.org
View file
release.sh
Added
@@ -0,0 +1,15 @@ +#!/bin/bash + +./buildtarball.sh + +# Autobump the version +CURRENT_VERSION=$(grep '^Version: ' ./*.spec | sed 's/Version: //') +NEW_VERSION=$(echo "$CURRENT_VERSION" | awk -F. '/0-9+\./{$NF++;print}' OFS=.) +echo "Bumping from $CURRENT_VERSION to $NEW_VERSION" + +sed -i "s/$CURRENT_VERSION/$NEW_VERSION/" debian.changelog +sed -i "s/^Version:.*/Version: $NEW_VERSION-1~kolab1/" ./*.dsc +sed -i "s/^Version:.*/Version: $NEW_VERSION/" ./*.spec + +osc ci -m "New release $NEW_VERSION" +osc sr Kolab:16 --yes -m "New release $NEW_VERSION"
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
.