MoinMessage

Change of parsers/pgp.py

48:24690b5d2c3f
parsers/pgp.py
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/parsers/pgp.py	Wed Jul 10 16:11:18 2013 +0200
     1.3 @@ -0,0 +1,127 @@
     1.4 +# -*- coding: iso-8859-1 -*-
     1.5 +"""
     1.6 +    MoinMoin - pgp (MoinMessage)
     1.7 +
     1.8 +    @copyright: 2012, 2013 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 MoinSupport import parseAttributes
    1.13 +from MoinMessage import GPG, is_signed, is_encrypted, \
    1.14 +                        MoinMessageDecodingError, MoinMessageError
    1.15 +from MoinMessageSupport import get_homedir
    1.16 +import email.parser
    1.17 +
    1.18 +try:
    1.19 +    from cStringIO import StringIO
    1.20 +except ImportError:
    1.21 +    from StringIO import StringIO
    1.22 +
    1.23 +Dependencies = ["pages"]
    1.24 +
    1.25 +# Parser support.
    1.26 +
    1.27 +class Parser:
    1.28 +
    1.29 +    """
    1.30 +    Extract information from PGP-encrypted content, subject to key availability.
    1.31 +    """
    1.32 +
    1.33 +    Dependencies = Dependencies
    1.34 +    extensions = []
    1.35 +
    1.36 +    # Input content types understood by this parser.
    1.37 +
    1.38 +    input_mimetypes = ["multipart/encrypted"]
    1.39 +
    1.40 +    # Output content types preferred by this parser.
    1.41 +
    1.42 +    output_mimetypes = []
    1.43 +
    1.44 +    def __init__(self, raw, request, **kw):
    1.45 +
    1.46 +        """
    1.47 +        Initialise the parser with the given 'raw' data, 'request' and any
    1.48 +        keyword arguments that may have been supplied.
    1.49 +        """
    1.50 +
    1.51 +        self.raw = raw
    1.52 +        self.request = request
    1.53 +        attrs = parseAttributes(kw.get("format_args", ""), False)
    1.54 +
    1.55 +        self.fragment = attrs.get("fragment")
    1.56 +
    1.57 +    def _decrypt(self, text):
    1.58 +
    1.59 +        "Decrypt the content."
    1.60 +
    1.61 +        homedir = get_homedir(self.request)
    1.62 +        gpg = GPG(homedir)
    1.63 +
    1.64 +        # Obtain a message from the text.
    1.65 +
    1.66 +        message = email.parser.Parser().parse(StringIO(text))
    1.67 +
    1.68 +        # Decrypt the message.
    1.69 +
    1.70 +        if is_encrypted(message):
    1.71 +            message_text = gpg.decryptMessage(message)
    1.72 +            message = email.parser.Parser().parse(StringIO(message_text))
    1.73 +
    1.74 +        # Extract any signature details.
    1.75 +
    1.76 +        if is_signed(message):
    1.77 +            result = gpg.verifyMessage(message)
    1.78 +            if result:
    1.79 +                return result
    1.80 +        else:
    1.81 +            return None, None, message
    1.82 +
    1.83 +    def _decode(self, part):
    1.84 +
    1.85 +        "Decode the given 'part'."
    1.86 +
    1.87 +        charset = part.get_content_charset()
    1.88 +        payload = part.get_payload(decode=True)
    1.89 +        return charset and unicode(payload, charset) or payload
    1.90 +
    1.91 +    def format(self, fmt, write=None):
    1.92 +
    1.93 +        """
    1.94 +        Format content using the given formatter 'fmt'. If the 'write'
    1.95 +        parameter is specified, use it to write output; otherwise, write output
    1.96 +        using the request.
    1.97 +        """
    1.98 +
    1.99 +        write = write or self.request.write
   1.100 +
   1.101 +        try:
   1.102 +            fingerprint, identity, content = self._decrypt(self.raw)
   1.103 +            write(fmt.text(self._decode(content)))
   1.104 +
   1.105 +        except MoinMessageDecodingError:
   1.106 +            write(fmt.text(_("Encrypted content was improperly encoded.")))
   1.107 +
   1.108 +        except MoinMessageError:
   1.109 +            write(fmt.text(_("Encrypted content could not be decrypted/verified.")))
   1.110 +
   1.111 +    # Extra API methods.
   1.112 +
   1.113 +    def formatForOutputType(self, mimetype, write=None):
   1.114 +
   1.115 +        """
   1.116 +        Format content for the given 'mimetype'. If the 'write' parameter is
   1.117 +        specified, use it to write output; otherwise, write output using the
   1.118 +        request.
   1.119 +        """
   1.120 +
   1.121 +        self.format(self.request.html_formatter, write)
   1.122 +
   1.123 +    # Class methods.
   1.124 +
   1.125 +    def getOutputTypes(self):
   1.126 +        return self.output_mimetypes
   1.127 +
   1.128 +    getOutputTypes = classmethod(getOutputTypes)
   1.129 +
   1.130 +# vim: tabstop=4 expandtab shiftwidth=4