1.1 --- a/actions/PostMessage.py Fri Jul 20 21:58:47 2012 +0200
1.2 +++ b/actions/PostMessage.py Sat Jul 21 02:01:16 2012 +0200
1.3 @@ -9,6 +9,7 @@
1.4 from MoinMoin.PageEditor import PageEditor
1.5 from MoinSupport import *
1.6 from email.parser import Parser
1.7 +import os
1.8
1.9 try:
1.10 from cStringIO import StringIO
1.11 @@ -41,6 +42,71 @@
1.12 # Get the message.
1.13
1.14 message_text = StringIO(request.read(content_length))
1.15 + self.handle_message(message_text)
1.16 +
1.17 + def handle_message(self, message_text):
1.18 +
1.19 + "Handle the given 'message_text'."
1.20 +
1.21 + request = self.request
1.22 + message = Parser().parse(message_text)
1.23 + mimetype = message.get_content_type()
1.24 + encoding = message.get_content_charset()
1.25 +
1.26 + # Detect PGP/GPG-encoded payloads.
1.27 + # See: http://tools.ietf.org/html/rfc3156
1.28 +
1.29 + if mimetype == "multipart/encrypted" and \
1.30 + message.get_param("protocol") == "application/pgp-encrypted":
1.31 +
1.32 + try:
1.33 + declaration, part = message.get_payload()
1.34 + except ValueError:
1.35 + writeHeaders(request, "text/plain", getMetadata(self.page), "415 Unsupported Media Type")
1.36 + request.write("There must be a declaration and a content part for signed uploads.")
1.37 + return
1.38 +
1.39 + # Verify the message format.
1.40 +
1.41 + if part.get_content_type() != "application/octet-stream":
1.42 + writeHeaders(request, "text/plain", getMetadata(self.page), "415 Unsupported Media Type")
1.43 + request.write("Encrypted data must be provided as application/octet-stream.")
1.44 + return
1.45 +
1.46 + # Locate the keyring.
1.47 +
1.48 + homedir = getattr(request.cfg, "postmessage_gpg_homedir")
1.49 + if not homedir:
1.50 + writeHeaders(request, "text/plain", getMetadata(self.page), "415 Unsupported Media Type")
1.51 + request.write("Encrypted data cannot currently be understood. Please notify the site administrator.")
1.52 + return
1.53 +
1.54 + # Decrypt the message text.
1.55 +
1.56 + to_child, from_child, error_child = os.popen3(["gpg", "--no-default-keyring", "--homedir", homedir, "--decrypt"])
1.57 + to_child.write(part.get_payload())
1.58 + to_child.close()
1.59 + #print >>open("/tmp/log.txt", "a"), error_child.read()
1.60 +
1.61 + # Handle the embedded message.
1.62 +
1.63 + try:
1.64 + self.handle_plaintext_message(from_child)
1.65 + finally:
1.66 + from_child.close()
1.67 + error_child.close()
1.68 +
1.69 + # Reject unsigned payloads.
1.70 +
1.71 + else:
1.72 + writeHeaders(request, "text/plain", getMetadata(self.page), "415 Unsupported Media Type")
1.73 + request.write("Only PGP/GPG-signed payloads are supported.")
1.74 +
1.75 + def handle_plaintext_message(self, message_text):
1.76 +
1.77 + "Handle the given 'message_text'."
1.78 +
1.79 + request = self.request
1.80 message = Parser().parse(message_text)
1.81
1.82 # Handle a single part.
1.83 @@ -83,7 +149,8 @@
1.84 body = []
1.85
1.86 for part in parts:
1.87 - mimetype, encoding = getContentTypeAndEncoding(part.get("Content-Type"))
1.88 + mimetype = part.get_content_type()
1.89 + encoding = part.get_content_charset()
1.90 if mimetype == "text/moin":
1.91 body.append(part.get_payload())
1.92 if replace:
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/tests/test_message.py Sat Jul 21 02:01:16 2012 +0200
2.3 @@ -0,0 +1,19 @@
2.4 +#!/usr/bin/env python
2.5 +
2.6 +from email.mime.multipart import MIMEMultipart
2.7 +from email.mime.text import MIMEText
2.8 +
2.9 +if __name__ == "__main__":
2.10 + message = MIMEMultipart()
2.11 +
2.12 + text1 = MIMEText("An update to the Wiki.", "moin")
2.13 +
2.14 + text2 = MIMEText("Another update to the Wiki.", "moin")
2.15 +
2.16 + message.attach(text1)
2.17 + message.attach(text2)
2.18 +
2.19 + text = message.as_string()
2.20 + print text
2.21 +
2.22 +# vim: tabstop=4 expandtab shiftwidth=4
3.1 --- a/tests/test_post.py Fri Jul 20 21:58:47 2012 +0200
3.2 +++ b/tests/test_post.py Sat Jul 21 02:01:16 2012 +0200
3.3 @@ -1,24 +1,28 @@
3.4 #!/usr/bin/env python
3.5
3.6 from email.mime.multipart import MIMEMultipart
3.7 -from email.mime.text import MIMEText
3.8 +from email.mime.application import MIMEApplication
3.9 +from email.mime.base import MIMEBase
3.10 +from email.encoders import encode_noop
3.11 import httplib
3.12 import sys
3.13
3.14 if __name__ == "__main__":
3.15 host = sys.argv[1]
3.16 path = sys.argv[2] + "?action=PostMessage"
3.17 + text = sys.stdin.read()
3.18
3.19 - message = MIMEMultipart()
3.20 -
3.21 - text1 = MIMEText("An update to the Wiki.", "moin")
3.22 + message = MIMEMultipart("encrypted", protocol="application/pgp-encrypted")
3.23
3.24 - text2 = MIMEText("Another update to the Wiki.", "moin")
3.25 + declaration = MIMEBase("application", "pgp-encrypted")
3.26 + declaration.set_payload("Version: 1")
3.27 + message.attach(declaration)
3.28
3.29 - message.attach(text1)
3.30 - message.attach(text2)
3.31 + content = MIMEApplication(text, "octet-stream", encode_noop)
3.32 + message.attach(content)
3.33
3.34 text = message.as_string()
3.35 +
3.36 print text
3.37 print
3.38