Clean up the code after refactor
- Clean up PGP/MIME flow by using API instead of explicit/manual generation of headers. - Fix E2E test configuration for PGP/MIME case. - Add first lacre.core unit tests. - Add another Contract Test.
This commit is contained in:
parent
27b07e672d
commit
56101b86c0
|
@ -321,42 +321,38 @@ def _encrypt_all_payloads_mime(message: email.message.Message, gpg_to_cmdline):
|
|||
|
||||
encrypted_part.set_payload(copy_encrypted.get_payload())
|
||||
|
||||
_set_content_type(message, boundary)
|
||||
_set_type_and_boundary_2(message, boundary)
|
||||
|
||||
return [pgp_ver_part, encrypted_part]
|
||||
else:
|
||||
processed_payloads = _generate_message_from_payloads(message)
|
||||
encrypted_part.set_payload(processed_payloads.as_string())
|
||||
|
||||
_set_content_type(message, boundary)
|
||||
_set_type_and_boundary_2(message, boundary)
|
||||
|
||||
return [pgp_ver_part, _encrypt_payload(encrypted_part, gpg_to_cmdline, False)]
|
||||
|
||||
|
||||
def _make_boundary():
|
||||
junk_msg = MIMEMultipart()
|
||||
_ = junk_msg.as_string() # WTF! Without this, get_boundary() will return 'None'!
|
||||
# XXX See EmailTest.test_boundary_generated_after_as_string_call.
|
||||
_ = junk_msg.as_string()
|
||||
return junk_msg.get_boundary()
|
||||
|
||||
|
||||
def _set_content_type(message: email.message.Message, boundary: str):
|
||||
if 'Content-Type' in message:
|
||||
message.replace_header('Content-Type', _multipart_encrypted_with_boundary(boundary)+text.EOL)
|
||||
else:
|
||||
message['Content-Type'] = _multipart_encrypted_with_boundary(boundary)+text.EOL
|
||||
|
||||
|
||||
def _multipart_encrypted_with_boundary(boundary):
|
||||
return f"multipart/encrypted; protocol=\"application/pgp-encrypted\"; boundary=\"{boundary}\""
|
||||
def _set_type_and_boundary_2(message: email.message.Message, boundary):
|
||||
message.set_type('multipart/encrypted')
|
||||
message.set_param('protocol', 'application/pgp-encrypted')
|
||||
message.set_param('boundary', boundary)
|
||||
|
||||
|
||||
def _encrypt_payload(payload: email.message.Message, recipients, check_nested=True, **kwargs):
|
||||
raw_payload = raw_data_manager.get_content(payload)
|
||||
LOG.debug('Got raw_payload (%s; %s): %s. Message: %s',
|
||||
LOG.debug('About to encrypt raw payload (%s; %s): %s',
|
||||
type(raw_payload),
|
||||
payload.get_content_type(),
|
||||
raw_payload,
|
||||
payload)
|
||||
raw_payload)
|
||||
LOG.debug('Encrypting message: %s', payload)
|
||||
if check_nested and text.is_payload_pgp_inline(raw_payload):
|
||||
LOG.debug("Message is already pgp encrypted. No nested encryption needed.")
|
||||
return payload
|
||||
|
@ -364,8 +360,7 @@ def _encrypt_payload(payload: email.message.Message, recipients, check_nested=Tr
|
|||
gpg = _make_encryptor(raw_payload, recipients)
|
||||
|
||||
gpg.update(raw_payload)
|
||||
encrypted_data, returncode = gpg.encrypt()
|
||||
LOG.debug("Return code from encryption=%d (0 indicates success)." % returncode)
|
||||
encrypted_data, exit_code = gpg.encrypt()
|
||||
|
||||
payload.set_payload(encrypted_data)
|
||||
isAttachment = payload.get_param('attachment', None, 'Content-Disposition') is not None
|
||||
|
|
14
test/e2e.ini
14
test/e2e.ini
|
@ -37,6 +37,14 @@ e2e_log_datefmt: %Y-%m-%d %H:%M:%S
|
|||
lacre_log: test/logs/gpg-mailgate.log
|
||||
log_config: test/gpg-lacre-log.ini
|
||||
|
||||
# TEST IDENTITIES AND SETTINGS:
|
||||
#
|
||||
# Email Key Style
|
||||
# alice@disposlab RSA 3072 PGP/Inline
|
||||
# bob@disposlab ED25519 PGP/Inline
|
||||
# carlos@disposlab none PGP/Inline
|
||||
# evan@disposlab ED25519 PGP/MIME
|
||||
|
||||
[case-1]
|
||||
descr: Clear text message to a user without a key
|
||||
to: carlos@disposlab
|
||||
|
@ -119,10 +127,10 @@ out: -----BEGIN PGP MESSAGE-----
|
|||
descr: Clear text with UTF-8, PGP/MIME
|
||||
to: evan@disposlab
|
||||
in: test/msgin/utf8-plain.msg
|
||||
out: -----BEGIN PGP MESSAGE-----
|
||||
out: Content-Type: application/pgp-encrypted
|
||||
|
||||
[case-15]
|
||||
descr: Clear text with UTF-8, PGP/Inline
|
||||
to: carlos@disposlab
|
||||
to: bob@disposlab
|
||||
in: test/msgin/utf8-plain.msg
|
||||
out-not: -----BEGIN PGP MESSAGE-----
|
||||
out: -----BEGIN PGP MESSAGE-----
|
||||
|
|
|
@ -28,9 +28,10 @@ log_headers = yes
|
|||
send_email = no
|
||||
|
||||
[pgp_style]
|
||||
# this recipient has PGP/MIME enabled, because the default approach is to use
|
||||
# PGP/Inline
|
||||
evan@disposlab = mime
|
||||
|
||||
[enc_keymap]
|
||||
alice@disposlab = 1CD245308F0963D038E88357973CF4D9387C44D7
|
||||
bob@disposlab = 19CF4B47ECC9C47AFA84D4BD96F39FDA0E31BB67
|
||||
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
#
|
||||
# gpg-mailgate
|
||||
# gpg-mailgate
|
||||
#
|
||||
# This file is part of the gpg-mailgate source code.
|
||||
# This file is part of the gpg-mailgate source code.
|
||||
#
|
||||
# gpg-mailgate 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.
|
||||
# gpg-mailgate 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.
|
||||
#
|
||||
# gpg-mailgate source code 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.
|
||||
# gpg-mailgate source code 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 gpg-mailgate source code. If not, see <http://www.gnu.org/licenses/>.
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with gpg-mailgate source code. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
"""Unit-tests as contracts for external dependencies.
|
||||
|
@ -25,68 +25,80 @@ documentation.
|
|||
"""
|
||||
|
||||
import email
|
||||
import email.mime.multipart
|
||||
import unittest
|
||||
from configparser import RawConfigParser
|
||||
|
||||
|
||||
class EmailParsingTest(unittest.TestCase):
|
||||
"""This test serves as a package contract and documentation of its behaviour."""
|
||||
"""This test serves as a package contract and documentation of its behaviour."""
|
||||
|
||||
def test_message_from_bytes_produces_message_with_str_headers(self):
|
||||
rawmsg = b"From: alice@lacre.io\r\n" \
|
||||
+ b"To: bob@lacre.io\r\n" \
|
||||
+ b"Subject: Test message\r\n" \
|
||||
+ b"\r\n" \
|
||||
+ b"Test message from Alice to Bob.\r\n"
|
||||
def test_message_from_bytes_produces_message_with_str_headers(self):
|
||||
rawmsg = b"From: alice@lacre.io\r\n" \
|
||||
+ b"To: bob@lacre.io\r\n" \
|
||||
+ b"Subject: Test message\r\n" \
|
||||
+ b"\r\n" \
|
||||
+ b"Test message from Alice to Bob.\r\n"
|
||||
|
||||
parsed = email.message_from_bytes(rawmsg)
|
||||
parsed = email.message_from_bytes(rawmsg)
|
||||
|
||||
self.assertEqual(parsed["From"], "alice@lacre.io")
|
||||
self.assertEqual(parsed["To"], "bob@lacre.io")
|
||||
self.assertEqual(parsed["Subject"], "Test message")
|
||||
self.assertEqual(parsed["From"], "alice@lacre.io")
|
||||
self.assertEqual(parsed["To"], "bob@lacre.io")
|
||||
self.assertEqual(parsed["Subject"], "Test message")
|
||||
|
||||
def test_bytes_message_payload_decoded_produces_bytes(self):
|
||||
rawmsg = b"From: alice@lacre.io\r\n" \
|
||||
+ b"To: bob@lacre.io\r\n" \
|
||||
+ b"Subject: Test message\r\n" \
|
||||
+ b"\r\n" \
|
||||
+ b"Test message from Alice to Bob.\r\n"
|
||||
def test_bytes_message_payload_decoded_produces_bytes(self):
|
||||
rawmsg = b"From: alice@lacre.io\r\n" \
|
||||
+ b"To: bob@lacre.io\r\n" \
|
||||
+ b"Subject: Test message\r\n" \
|
||||
+ b"\r\n" \
|
||||
+ b"Test message from Alice to Bob.\r\n"
|
||||
|
||||
parsed = email.message_from_bytes(rawmsg)
|
||||
parsed = email.message_from_bytes(rawmsg)
|
||||
|
||||
self.assertEqual(parsed.get_payload(), "Test message from Alice to Bob.\r\n")
|
||||
self.assertEqual(parsed.get_payload(decode=True), b"Test message from Alice to Bob.\r\n")
|
||||
self.assertEqual(parsed.get_payload(), "Test message from Alice to Bob.\r\n")
|
||||
self.assertEqual(parsed.get_payload(decode=True), b"Test message from Alice to Bob.\r\n")
|
||||
|
||||
def test_message_from_string_produces_message_with_str_headers(self):
|
||||
rawmsg = "From: alice@lacre.io\r\n" \
|
||||
+ "To: bob@lacre.io\r\n" \
|
||||
+ "Subject: Test message\r\n" \
|
||||
+ "\r\n" \
|
||||
+ "Test message from Alice to Bob.\r\n"
|
||||
def test_message_from_string_produces_message_with_str_headers(self):
|
||||
rawmsg = "From: alice@lacre.io\r\n" \
|
||||
+ "To: bob@lacre.io\r\n" \
|
||||
+ "Subject: Test message\r\n" \
|
||||
+ "\r\n" \
|
||||
+ "Test message from Alice to Bob.\r\n"
|
||||
|
||||
parsed = email.message_from_string(rawmsg)
|
||||
parsed = email.message_from_string(rawmsg)
|
||||
|
||||
self.assertEqual(parsed["From"], "alice@lacre.io")
|
||||
self.assertEqual(parsed["To"], "bob@lacre.io")
|
||||
self.assertEqual(parsed["Subject"], "Test message")
|
||||
self.assertEqual(parsed["From"], "alice@lacre.io")
|
||||
self.assertEqual(parsed["To"], "bob@lacre.io")
|
||||
self.assertEqual(parsed["Subject"], "Test message")
|
||||
|
||||
def test_str_message_payload_decoded_produces_bytes(self):
|
||||
rawmsg = "From: alice@lacre.io\r\n" \
|
||||
+ "To: bob@lacre.io\r\n" \
|
||||
+ "Subject: Test message\r\n" \
|
||||
+ "\r\n" \
|
||||
+ "Test message from Alice to Bob.\r\n"
|
||||
def test_str_message_payload_decoded_produces_bytes(self):
|
||||
rawmsg = "From: alice@lacre.io\r\n" \
|
||||
+ "To: bob@lacre.io\r\n" \
|
||||
+ "Subject: Test message\r\n" \
|
||||
+ "\r\n" \
|
||||
+ "Test message from Alice to Bob.\r\n"
|
||||
|
||||
parsed = email.message_from_string(rawmsg)
|
||||
parsed = email.message_from_string(rawmsg)
|
||||
|
||||
self.assertEqual(parsed.get_payload(), "Test message from Alice to Bob.\r\n")
|
||||
self.assertEqual(parsed.get_payload(decode=True), b"Test message from Alice to Bob.\r\n")
|
||||
|
||||
|
||||
class EmailTest(unittest.TestCase):
|
||||
def test_boundary_generated_after_as_string_call(self):
|
||||
mp = email.mime.multipart.MIMEMultipart()
|
||||
self.assertTrue(mp.get_boundary() is None)
|
||||
_ = mp.as_string()
|
||||
self.assertFalse(mp.get_boundary() is None)
|
||||
|
||||
self.assertEqual(parsed.get_payload(), "Test message from Alice to Bob.\r\n")
|
||||
self.assertEqual(parsed.get_payload(decode=True), b"Test message from Alice to Bob.\r\n")
|
||||
|
||||
class RawConfigParserTest(unittest.TestCase):
|
||||
def test_config_parser_returns_str(self):
|
||||
cp = RawConfigParser()
|
||||
cp.read("test/sample.ini")
|
||||
self.assertEqual(cp.get("foo", "bar"), "quux")
|
||||
self.assertEqual(cp.get("foo", "baz"), "14")
|
||||
def test_config_parser_returns_str(self):
|
||||
cp = RawConfigParser()
|
||||
cp.read("test/sample.ini")
|
||||
self.assertEqual(cp.get("foo", "bar"), "quux")
|
||||
self.assertEqual(cp.get("foo", "baz"), "14")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
unittest.main()
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
import lacre.core
|
||||
from email.message import Message
|
||||
|
||||
import unittest
|
||||
|
||||
|
||||
class LacreCoreTest(unittest.TestCase):
|
||||
def test_attachment_handling(self):
|
||||
m = Message()
|
||||
m.set_payload('This is a payload')
|
||||
m.set_param('attachment', '', 'Content-Disposition')
|
||||
m.set_param('filename', 'foo', 'Content-Disposition')
|
||||
|
||||
lacre.core._append_gpg_extension(m)
|
||||
|
||||
self.assertEqual(m.get_filename(), 'foo.pgp')
|
||||
|
||||
def test_attachment_handling_2(self):
|
||||
m = Message()
|
||||
m.set_payload('This is a payload')
|
||||
m.set_param('attachment', '', 'Content-Disposition')
|
||||
m.set_param('name', 'quux', 'Content-Type')
|
||||
|
||||
lacre.core._append_gpg_extension(m)
|
||||
|
||||
self.assertEqual(m.get_filename(), 'quux.pgp')
|
Loading…
Reference in New Issue