Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed #35365 -- Add RFC 3824 Auto-Submitted header to emails by default #18099

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ answer newbie questions, and generally made Django that much better:
Can Burak Çilingir <canburak@cs.bilgi.edu.tr>
Can Sarıgöl <ertugrulsarigol@gmail.com>
Carl Meyer <carl@oddbird.net>
Carter Gracin <carter.rgracin@gmail.com>
Carles Pina i Estany <carles@pina.cat>
Carlos Eduardo de Paula <carlosedp@gmail.com>
Carlos Matías de la Torre <cmdelatorre@gmail.com>
Expand Down
2 changes: 2 additions & 0 deletions django/core/mail/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
BadHeaderError,
EmailMessage,
EmailMultiAlternatives,
NoAutoSubmittedHeaderEmailMessage,
SafeMIMEMultipart,
SafeMIMEText,
forbid_multi_line_headers,
Expand All @@ -26,6 +27,7 @@
"DNS_NAME",
"EmailMessage",
"EmailMultiAlternatives",
"NoAutoSubmittedHeaderEmailMessage",
"SafeMIMEText",
"SafeMIMEMultipart",
"DEFAULT_ATTACHMENT_MIME_TYPE",
Expand Down
24 changes: 24 additions & 0 deletions django/core/mail/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -280,9 +280,15 @@ def message(self):
if "message-id" not in header_names:
# Use cached DNS_NAME for performance
msg["Message-ID"] = make_msgid(domain=DNS_NAME)

if "Auto-Submitted" not in self.extra_headers:
# Default to adding the Auto-Submitted : auto-generated header
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should not be a space after "Auth-Submitted" (also in other places).

Copy link
Contributor

@shangxiao shangxiao Apr 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I'd ask this comment be removed pls. We have a policy of not commenting the "what", rather focusing on commenting the "why" 👍

self.extra_headers["Auto-Submitted"] = "auto-generated"

for name, value in self.extra_headers.items():
if name.lower() != "from": # From is already handled
msg[name] = value

return msg

def recipients(self):
Expand Down Expand Up @@ -432,6 +438,24 @@ def _set_list_header_if_not_empty(self, msg, header, values):
msg[header] = value


class NoAutoSubmittedHeaderEmailMessage(EmailMessage):
"""
A version of EmailMessage that does not have the default
Auto-Submitted : auto-generated header attached to it.
"""

def message(self):
"""
This removes the default Auto-Submitted : auto-generated
header from the message
"""
msg = super().message()
if "Auto-Submitted" in msg:
del msg["Auto-Submitted"]

return msg


class EmailMultiAlternatives(EmailMessage):
"""
A version of EmailMessage that makes it easy to send multipart/alternative
Expand Down
4 changes: 3 additions & 1 deletion docs/releases/5.1.txt
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,9 @@ Decorators
Email
~~~~~

* ...
* :class:`<django.core.mail.EmailMessage>` now attaches a default header of "Auto-Submitted : auto-generated"
to outgoing emails. You can opt-out of this by using :class:`<django.core.mail.NoAutoSubmittedHeaderEmailMessage>`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The angle brackets are not required and should be removed.

which does not attach this default header.

Error Reporting
~~~~~~~~~~~~~~~
Expand Down
16 changes: 15 additions & 1 deletion docs/topics/email.txt
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,21 @@ All parameters are optional and can be set at any time prior to calling the
* ``headers``: A dictionary of extra headers to put on the message. The
keys are the header name, values are the header values. It's up to the
caller to ensure header names and values are in the correct format for
an email message. The corresponding attribute is ``extra_headers``.
an email message. The corresponding attribute is ``extra_headers``. The
EmailMessage class attaches a default header of ``Auto-Submitted :
auto-generated ``. The sender can opt-out of this default header by using
the ``NoAutoSubmittedHeaderEmailMessage`` subclass.

For example::

from django.core.mail import NoAutoSubmittedHeaderEmailMessage

email = NoAutoSubmittedHeaderEmailMessage(
"Hello",
"Body goes here",
"from@example.com",
["to@example.com"]
)

* ``cc``: A list or tuple of recipient addresses used in the "Cc" header
when sending the email.
Expand Down
13 changes: 13 additions & 0 deletions tests/mail/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
DNS_NAME,
EmailMessage,
EmailMultiAlternatives,
NoAutoSubmittedHeaderEmailMessage,
mail_admins,
mail_managers,
send_mail,
Expand Down Expand Up @@ -449,6 +450,18 @@ def test_reply_to_in_headers_only(self):
).message()
self.assertEqual(message["Reply-To"], "reply_to@example.com")

def test_default_auto_generated_header(self):
message = EmailMessage(
"Subject", "Content", "from@example.com", ["to@example.com"]
).message()
self.assertEqual(message["Auto-Submitted"], "auto-generated")

def test_no_default_auto_generated_header(self):
message = NoAutoSubmittedHeaderEmailMessage(
"Subject", "Content", "from@example.com", ["to@example.com"]
).message()
self.assertNotIn("Auto-Submitted", message)

def test_multiple_message_call(self):
"""
Regression for #13259 - Make sure that headers are not changed when
Expand Down