Skip to content

Commit

Permalink
Merge pull request #75 from Waghabond/master
Browse files Browse the repository at this point in the history
Alter Email Message Default Policy to Comply With RFC 5322
  • Loading branch information
Miksus committed Feb 21, 2023
2 parents 0a6f0a6 + a9f77b2 commit 8511afc
Show file tree
Hide file tree
Showing 6 changed files with 24 additions and 19 deletions.
1 change: 1 addition & 0 deletions docs/versions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Version history

- ``0.6.0``

- Fix: Line breaks according to RFC 5322 (credit Waghabond)
- Add: Support for Pandas styler (thanks ejbills!)

- ``0.5.0``
Expand Down
6 changes: 5 additions & 1 deletion redmail/email/sender.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@

from copy import copy
import email.policy
from email.message import EmailMessage
from email.utils import make_msgid, formatdate
from typing import TYPE_CHECKING, Any, Callable, Dict, List, Optional, Union
Expand Down Expand Up @@ -429,7 +430,10 @@ def create_message_id(self) -> str:
return make_msgid(domain=self.domain)

def _create_body(self, subject, sender, receivers=None, cc=None, bcc=None, headers=None) -> EmailMessage:
msg = EmailMessage()
# Python's default email policy follows the Internet mail standards (RFC 5322) EXCEPT for line endings.
# For line endings the default policy uses python's default LF instead of CRLF as mandated by RFC 5322.
# So we can manually edit this to to comply with the internet standards.
msg = EmailMessage(email.policy.default.clone(linesep="\r\n"))

email_headers = {
"From": sender,
Expand Down
10 changes: 5 additions & 5 deletions redmail/test/email/test_body.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def test_text_message():
MIME-Version: 1.0
Hi, nice to meet you.
""")[1:]
""")[1:].replace('\n', '\r\n')


def test_html_message():
Expand Down Expand Up @@ -80,7 +80,7 @@ def test_html_message():
--===============<ID>==--
--===============<ID>==--
""")[1:]
""")[1:].replace('\n', '\r\n')


def test_text_and_html_message():
Expand Down Expand Up @@ -129,7 +129,7 @@ def test_text_and_html_message():
--===============<ID>==--
--===============<ID>==--
""")[1:]
""")[1:].replace('\n', '\r\n')


@pytest.mark.parametrize(
Expand Down Expand Up @@ -246,9 +246,9 @@ def test_without_jinja(use_jinja_obj, use_jinja):
--===============<ID>==--
--===============<ID>==--
""")[1:]
""")[1:].replace('\n', '\r\n')
if IS_PY37:
expected = expected.replace('sender.full_n=\n', 'sender.full_n')
expected = expected.replace('sender.full_n=\r\n', 'sender.full_n')
msg = prune_generated_headers(str(msg))
assert remove_email_content_id(msg) == expected

Expand Down
2 changes: 1 addition & 1 deletion redmail/test/email/test_cookbook.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,4 @@ def get_bcc(self, receiver_list):
Message-ID: <<message_id>>
Date: <date>
""")[1:]
""")[1:].replace('\n', '\r\n')
22 changes: 11 additions & 11 deletions redmail/test/email/test_headers.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ def test_date():
before = datetime.datetime.now(datetime.timezone.utc)
msg = email.get_message(sender="[email protected]", subject="Some email")
after = datetime.datetime.now(datetime.timezone.utc)
date_strings = re.findall(r'(?<=Date: ).+', str(msg))
date_strings = re.findall(r'(?<=Date: )[^\r\n]+', str(msg))
assert len(date_strings) == 1
for dt_string in date_strings:

# Validate the Date fits to the format
datetime.datetime.strptime(dt_string, format)

Expand All @@ -45,15 +45,15 @@ def test_message_id():
msg = email.get_message(sender="[email protected]", subject="Some email")
msg2 = email.get_message(sender="[email protected]", subject="Some email")

message_ids = re.findall(r'(?<=Message-ID: ).+', str(msg))
message_ids = re.findall(r'(?<=Message-ID: )[^\r\n]+', str(msg))
assert len(message_ids) == 1
message_id = message_ids[0]

# [0-9]{{12}}[.][0-9]{{5}}[.][0-9]{{20}}
assert bool(re.search(fr'<[0-9.]+@{domain}>', message_id))

# Check another email has not the same Message-ID
message_id_2 = re.findall(r'(?<=Message-ID: ).+', str(msg2))[0]
message_id_2 = re.findall(r'(?<=Message-ID: )[^\r\n]+', str(msg2))[0]
assert message_id != message_id_2

def test_cc_bcc():
Expand All @@ -73,7 +73,7 @@ def test_cc_bcc():
Message-ID: <<message_id>>
Date: <date>
""")[1:]
""")[1:].replace('\n', '\r\n')

@pytest.mark.parametrize("how", ["instance", "email"])
def test_custom_headers(how):
Expand All @@ -89,14 +89,14 @@ def test_custom_headers(how):

if how == "email":
msg = email.get_message(
sender="[email protected]",
subject="Some email",
sender="[email protected]",
subject="Some email",
headers=headers
)
elif how == "instance":
email.headers = headers
msg = email.get_message(
sender="[email protected]",
sender="[email protected]",
subject="Some email",
)
msg = prune_generated_headers(str(msg))
Expand All @@ -107,7 +107,7 @@ def test_custom_headers(how):
Date: <date>
Importance: high
""")[1:]
""")[1:].replace('\n', '\r\n')

@pytest.mark.parametrize("how", ["instance", "email"])
def test_custom_headers_override(how):
Expand All @@ -119,7 +119,7 @@ def test_custom_headers_override(how):

if how == "email":
msg = email.get_message(
sender="[email protected]",
sender="[email protected]",
subject="Some email",
headers=headers
)
Expand All @@ -135,4 +135,4 @@ def test_custom_headers_override(how):
Message-ID: <167294165062.31860.1664530310632362057@LAPTOP-1234GML0>
Date: Sun, 31 Jan 2021 06:56:46 +0000
""")[1:]
""")[1:].replace('\n', '\r\n')
2 changes: 1 addition & 1 deletion redmail/test/email/test_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ def test_jinja_env(tmpdir):
--===============<ID>==--
--===============<ID>==--
""")[1:]
""")[1:].replace('\n', '\r\n')

def test_body_and_template_error(tmpdir):

Expand Down

0 comments on commit 8511afc

Please sign in to comment.