Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F117822140
D167.1775295850.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
8 KB
Referenced Files
None
Subscribers
None
D167.1775295850.diff
View Options
diff --git a/conf/kolab.conf b/conf/kolab.conf
--- a/conf/kolab.conf
+++ b/conf/kolab.conf
@@ -427,9 +427,42 @@
result_attribute = mail
[wallace]
-modules = resources, invitationpolicy, footer
-footer_text = /etc/kolab/footer.text
-footer_html = /etc/kolab/footer.html
+; List the modules to load and apply, in order.
+;
+; Available modules include;
+;
+; * resources
+; * invitationpolicy
+; * footer
+; * signature
+;
+modules = resources, invitationpolicy
+
+; Footer module settings
+;footer_text = /etc/kolab/footer.text
+;footer_html = /etc/kolab/footer.html
+
+; Signature module settings
+;
+; A list of dicts, with each dict holding an attribute name ("o", "cn",
+; "entrydn"), and a regular expression to be matched against the attribute
+; value.
+;
+; The module takes the first match, and uses the "html" and "text" files as
+; templates.
+;
+;signature_rules = [
+; {
+; "entrydn": "uid=.*,ou=IT,ou=People,dc=example,dc=org",
+; "html": "/etc/kolab/signature_IT.html",
+; "text": "/etc/kolab/signature_IT.txt"
+; },
+; {
+; "entrydn": "uid=.*,ou=Finance,ou=People,dc=example,dc=org",
+; "html": "/etc/kolab/signature_Finance.html",
+; "text": "/etc/kolab/signature_Finance.txt"
+; }
+; ]
; default settings for kolabInvitationPolicy LDAP attribute on user records
kolab_invitation_policy = ACT_ACCEPT_IF_NO_CONFLICT:example.org, ACT_MANUAL
diff --git a/conf/signature_IT.html b/conf/signature_IT.html
new file mode 100644
--- /dev/null
+++ b/conf/signature_IT.html
@@ -0,0 +1,13 @@
+<br clear="all"/>
+<hr>
+This is an example HTML signature.
+
+<p style="font-size: small; color: gray;">
+%(o)s
+
+%(manager:cn)s
+
+M: %(mobile)s
+T: %(telephonenumber)s
+W: https://it.services.inc
+</p>
diff --git a/conf/signature_IT.txt b/conf/signature_IT.txt
new file mode 100644
--- /dev/null
+++ b/conf/signature_IT.txt
@@ -0,0 +1,9 @@
+This is an example TEXT signature.
+
+%(o)s
+
+%(manager:cn)s
+
+M: %(mobile)s
+T: %(telephonenumber)s
+W: https://it.services.inc
diff --git a/wallace/module_signature.py b/wallace/module_signature.py
new file mode 100644
--- /dev/null
+++ b/wallace/module_signature.py
@@ -0,0 +1,199 @@
+# -*- coding: utf-8 -*-
+# Copyright 2010-2013 Kolab Systems AG (http://www.kolabsys.com)
+#
+# Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen a kolabsys.com>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# 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 json
+import os
+import re
+import tempfile
+import time
+
+from email import message_from_file
+from email.encoders import encode_quopri
+from email.parser import Parser
+from email.utils import getaddresses
+
+import modules
+import pykolab
+
+from pykolab.auth import Auth
+from pykolab.translate import _
+
+log = pykolab.getLogger('pykolab.wallace')
+conf = pykolab.getConf()
+
+mybasepath = '/var/spool/pykolab/wallace/signature/'
+
+def __init__():
+ modules.register('signature', execute, description=description())
+
+def description():
+ return """Append a signature to messages."""
+
+def set_part_content(part, content):
+ # Reset old encoding and use quoted-printable (#5414)
+ del part['Content-Transfer-Encoding']
+ part.set_payload(content)
+ encode_quopri(part)
+
+ return True
+
+def attr_resolve(sender_info, attr):
+ try:
+ attr, attr_val = attr.split(':')
+ except ValueError, errmsg:
+ return None
+
+ auth = Auth()
+ auth.connect()
+
+ values = []
+
+ if not isinstance(sender_info[attr], list):
+ sender_info[attr] = [ sender_info[attr] ]
+
+ for sender_attr_val in sender_info[attr]:
+ values.append(auth.get_entry_attribute(None, sender_attr_val, attr_val))
+
+ return ", ".join(values)
+
+def execute(*args, **kw):
+ if not os.path.isdir(mybasepath):
+ os.makedirs(mybasepath)
+
+ for stage in ['incoming', 'ACCEPT']:
+ if not os.path.isdir(os.path.join(mybasepath, stage)):
+ os.makedirs(os.path.join(mybasepath, stage))
+
+ # TODO: Test for correct call.
+ filepath = args[0]
+
+ 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))
+ return
+
+ log.debug(_("Executing module signature for %r, %r") % (args, kw), level=8)
+
+ new_filepath = os.path.join('/var/spool/pykolab/wallace/signature/incoming', os.path.basename(filepath))
+ os.rename(filepath, new_filepath)
+ filepath = new_filepath
+
+ # parse message
+ message = Parser().parse(open(filepath, 'r'))
+
+ # Possible signature answers are limited to ACCEPT only
+ answers = [ 'ACCEPT' ]
+
+ sender_address = [address for displayname,address in getaddresses(message.get_all('X-Kolab-From'))][0]
+
+ auth = Auth()
+ auth.connect()
+
+ sender_dn = auth.find_recipient(sender_address)
+ sender_info = auth.get_entry_attributes(None, sender_dn, ['*', 'entrydn', 'manager'])
+
+ log.debug("Sender info: %r" % (sender_info), level=7)
+
+ signature_rules = json.loads(conf.get_raw('wallace', 'signature_rules'))
+
+ log.debug("Signature rules: %r" % (signature_rules), level=7)
+
+ signature_html = None
+ signature_text = None
+
+ for signature_rule in signature_rules:
+ for attr, regex in signature_rule.iteritems():
+ if attr is "html":
+ continue
+ if attr is "text":
+ continue
+
+ if attr in sender_info.keys() and re.match(regex, sender_info[attr], flags=re.IGNORECASE):
+ success = False
+
+ while not success:
+ try:
+ signature_html = open(signature_rule['html'], 'r').read() % sender_info
+ signature_text = open(signature_rule['text'], 'r').read() % sender_info
+
+ success = True
+
+ except KeyError, errmsg:
+ sender_info[errmsg[0]] = attr_resolve(sender_info, errmsg[0])
+
+ if signature_html is None and signature_text is None:
+ exec('modules.cb_action_%s(%r, %r)' % ('ACCEPT','signature', filepath))
+ return
+
+ signature_added = False
+
+ try:
+ _signature_added = message.get("X-Wallace-Signature")
+ except:
+ pass
+
+ if _signature_added == "YES":
+ exec('modules.cb_action_%s(%r, %r)' % ('ACCEPT','signature', filepath))
+ return
+
+ for part in message.walk():
+ disposition = None
+
+ try:
+ content_type = part.get_content_type()
+ except:
+ continue
+
+ try:
+ disposition = part.get("Content-Disposition")
+ except:
+ pass
+
+ log.debug("Walking message part: %s; disposition = %r" % (content_type, disposition), level=8)
+
+ if disposition is not None:
+ continue
+
+ if content_type == "text/plain":
+ content = part.get_payload(decode=True)
+ content += "\n\n-- \n%s" % (signature_text)
+ signature_added = set_part_content(part, content)
+
+ elif content_type == "text/html":
+ content = part.get_payload(decode=True)
+ append = "\n<!-- signature appended by Wallace -->\n" + signature_html
+ if "</body>" in content:
+ content = content.replace("</body>", append + "</body>")
+ else:
+ content = "<html><body>" + content + append + "</body></html>"
+ signature_added = set_part_content(part, content)
+
+ if signature_added:
+ log.debug("Signature attached.", level=8)
+ message.add_header("X-Wallace-Signature", "YES")
+
+ (fp, new_filepath) = tempfile.mkstemp(dir="/var/spool/pykolab/wallace/signature/ACCEPT")
+ os.write(fp, message.as_string())
+ os.close(fp)
+ os.unlink(filepath)
+
+ exec('modules.cb_action_%s(%r, %r)' % ('ACCEPT','signature', new_filepath))
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Apr 4, 9:44 AM (2 d, 12 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18828861
Default Alt Text
D167.1775295850.diff (8 KB)
Attached To
Mode
D167: Append signatures from templates using LDAP information and conditionals.
Attached
Detach File
Event Timeline