1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/MoinMessage.py Sun Jul 22 01:58:24 2012 +0200
1.3 @@ -0,0 +1,131 @@
1.4 +# -*- coding: iso-8859-1 -*-
1.5 +"""
1.6 + MoinMoin - MoinMessage library
1.7 +
1.8 + @copyright: 2012 by Paul Boddie <paul@boddie.org.uk>
1.9 + @license: GNU GPL (v2 or later), see COPYING.txt for details.
1.10 +"""
1.11 +
1.12 +from MoinMoin.log import getLogger
1.13 +from email import message_from_string
1.14 +from email.encoders import encode_noop
1.15 +from email.mime.multipart import MIMEMultipart
1.16 +from email.mime.application import MIMEApplication
1.17 +from email.mime.base import MIMEBase
1.18 +from email.mime.text import MIMEText
1.19 +from subprocess import Popen, PIPE
1.20 +import httplib
1.21 +
1.22 +class Message:
1.23 +
1.24 + "An update message."
1.25 +
1.26 + def __init__(self):
1.27 + self.updates = []
1.28 +
1.29 + def add_update(self, alternatives):
1.30 + if len(alternatives) > 1:
1.31 + part = MIMEMultipart()
1.32 + for alternative in alternatives:
1.33 + part.attach(alternative)
1.34 + self.updates.append(part)
1.35 + else:
1.36 + self.updates.append(alternatives[0])
1.37 +
1.38 + def get_payload(self):
1.39 + if len(self.updates) == 1:
1.40 + message = self.updates[0]
1.41 + else:
1.42 + message = MIMEMultipart()
1.43 + message.add_header("Update-Type", "collection")
1.44 + for update in self.updates:
1.45 + message.attach(update)
1.46 +
1.47 + return message
1.48 +
1.49 +class MoinMessageError(Exception):
1.50 + pass
1.51 +
1.52 +def gpg(args, text):
1.53 +
1.54 + "Invoke gpg with the given 'args', supplying the given 'text'."
1.55 +
1.56 + cmd = Popen(args, stdin=PIPE, stdout=PIPE, stderr=PIPE)
1.57 +
1.58 + cmd.stdin.write(text)
1.59 + cmd.stdin.close()
1.60 +
1.61 + errors = cmd.stderr.read()
1.62 + if errors:
1.63 + getLogger(__name__).warning(errors)
1.64 +
1.65 + try:
1.66 + text = cmd.stdout.read()
1.67 +
1.68 + # Test for a zero result.
1.69 +
1.70 + if not cmd.wait():
1.71 + return text
1.72 + else:
1.73 + raise MoinMessageError, errors
1.74 +
1.75 + finally:
1.76 + cmd.stdout.close()
1.77 + cmd.stderr.close()
1.78 +
1.79 +def signMessage(message, keyid):
1.80 +
1.81 + """
1.82 + Return a signed 'message' using the given 'keyid'.
1.83 + """
1.84 +
1.85 + text = message.as_string()
1.86 + signature = gpg(["gpg", "--armor", "-u", keyid, "--detach-sig"], text)
1.87 +
1.88 + # Make the container for the message.
1.89 +
1.90 + signed_message = MIMEMultipart("signed", protocol="application/pgp-signature")
1.91 + signed_message.attach(message)
1.92 +
1.93 + signature_part = MIMEBase("application", "pgp-signature")
1.94 + signature_part.set_payload(signature)
1.95 + signed_message.attach(signature_part)
1.96 +
1.97 + return signed_message
1.98 +
1.99 +def encryptMessage(message, keyid):
1.100 +
1.101 + """
1.102 + Return an encrypted 'message' using the given 'keyid'.
1.103 + """
1.104 +
1.105 + text = message.as_string()
1.106 + encrypted = gpg(["gpg", "--armor", "-r", keyid, "--encrypt", "--trust-model", "always"], text)
1.107 +
1.108 + # Make the container for the message.
1.109 +
1.110 + encrypted_message = MIMEMultipart("encrypted", protocol="application/pgp-encrypted")
1.111 +
1.112 + # For encrypted content, add the declaration and content.
1.113 +
1.114 + declaration = MIMEBase("application", "pgp-encrypted")
1.115 + declaration.set_payload("Version: 1")
1.116 + encrypted_message.attach(declaration)
1.117 +
1.118 + content = MIMEApplication(encrypted, "octet-stream", encode_noop)
1.119 + encrypted_message.attach(content)
1.120 +
1.121 + return encrypted_message
1.122 +
1.123 +def sendMessage(message, host, path):
1.124 +
1.125 + "Send 'message' to the given 'host' using the specified URL 'path'."
1.126 +
1.127 + text = message.as_string()
1.128 +
1.129 + req = httplib.HTTPConnection(host)
1.130 + req.request("PUT", path, text) # {"Content-Length" : len(text)}
1.131 + resp = req.getresponse()
1.132 + return resp.read()
1.133 +
1.134 +# vim: tabstop=4 expandtab shiftwidth=4
2.1 --- a/tests/test_encrypt.py Sat Jul 21 23:52:59 2012 +0200
2.2 +++ b/tests/test_encrypt.py Sun Jul 22 01:58:24 2012 +0200
2.3 @@ -8,7 +8,6 @@
2.4
2.5 if __name__ == "__main__":
2.6 text = sys.stdin.read()
2.7 - signature = None
2.8 protocol = "application/pgp-encrypted"
2.9 subtype = "encrypted"
2.10
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/tests/test_send.py Sun Jul 22 01:58:24 2012 +0200
3.3 @@ -0,0 +1,25 @@
3.4 +#!/usr/bin/env python
3.5 +
3.6 +from MoinMessage import *
3.7 +from email.mime.text import MIMEText
3.8 +import sys
3.9 +
3.10 +if __name__ == "__main__":
3.11 + signer = sys.argv[1]
3.12 + recipient = sys.argv[2]
3.13 + host = sys.argv[3]
3.14 + path = sys.argv[4] + "?action=PostMessage"
3.15 +
3.16 + message = Message()
3.17 + message.add_update([MIMEText("An update to the Wiki.", "moin")])
3.18 + message.add_update([MIMEText("Another update to the Wiki.", "moin")])
3.19 + email_message = message.get_payload()
3.20 +
3.21 + try:
3.22 + signed_message = signMessage(email_message, signer)
3.23 + encrypted_message = encryptMessage(signed_message, recipient)
3.24 + sendMessage(encrypted_message, host, path)
3.25 + except MoinMessageError, exc:
3.26 + print exc
3.27 +
3.28 +# vim: tabstop=4 expandtab shiftwidth=4