| Age | Commit message (Collapse) | Author |
|
Bcc addresses are sent via the SMTP envelope and must never appear in
the message itself. A "Bcc" key in `extra_headers` was not excluded like
From/To/Cc/Reply-To, so it leaked into the generated message as a
visible header.
Thanks Mike Edmunds for reviews.
|
|
|
|
Thanks Kasper Dupont for the report, and Jacob Walls and Natalia Bidart
for reviews.
|
|
Versions of Python prior to 3.15 would incorrectly encode non-ASCII
email addresses using rfc2047, resulting in undeliverable email. The
SMTP EmailBackend detects and prevents that (#35713). Python 3.15 fixes
that behavior (CPython issue gh-122476).
Updated test_rejects_non_ascii_local_part() to feature-detect the fix
(in case it is backported) and check for a representative section of
the Python error message if so; otherwise test for the SMTP EmailBackend
workaround.
Updated comments to clarify need and requirement.
|
|
See DEP 0018.
Added:
* MAILERS setting.
* django.core.mail.mailers dict-like EmailBackend factory.
* `using` argument to mail sending APIs.
* `sent_using` attribute to mail.outbox messages in locmem backend.
* MAILERS in startproject settings template, set to console backend.
* AdminLogHandler.using argument.
* BrokenLinkEmailsMiddleware.send_mail() method.
Updated:
* BaseEmailBackend to track the MAILERS alias used to construct it, and
to report errors for unknown kwargs (OPTIONS).
* EmailBackend implementations to initialize from kwargs (OPTIONS) only
when MAILERS is being used.
* smtp.EmailBackend to require `host` option and to default `port`
option based on SSL/TLS options.
* SimpleTestCase setup to substitute the locmem backend for all defined
MAILERS configurations.
* Django's tests that send mail to define MAILERS.
Deprecated:
* EMAIL_BACKEND and other backend-related EMAIL_* settings.
* mail.get_connection().
* The `connection`, `fail_silently`, `auth_user`, and `auth_password`
arguments to mail functions.
* The EmailMessage.connection attribute.
* BaseEmailBackend support for `fail_silently`. Backends that support
fail_silently (SMTP, console, file) now implement it directly.
* AdminEmailHandler.email_backend argument.
Removed undocumented features without deprecation:
* EmailMessage.get_connection() method. (send() now raises an error if a
subclass has attempted to override it.)
* EmailMessage.send() no longer sets self.connection to the connection
used for sending. (It still _uses_ a pre-existing self.connection.)
* AdminEmailHandler.connection() method. (Init now raises an error if a
subclass has attempted to override it.)
Thanks to Natalia Bidart for shepherding DEP 0018 and for extensive
reviews and suggestions on the implementation.
Thanks to Jacob Rief for the initial implementation and multiple
iterations while refining the design.
Co-authored-by: Jacob Rief <jacob.rief@gmail.com>
|
|
Reworked tests/mail/test_backends.py so that cases covering functional
behavior don't depend on EMAIL_BACKEND or other EMAIL_* settings. (But
kept unchanged existing tests to verify backend instance properties are
initialized from EMAIL_* settings.)
Most backend behavior tests had implicitly relied on email settings
overrides in test setup (e.g., to use an emulated SMTP server). They
either used mail.get_connection(...) or directly constructed a backend
class instance with the specific attributes being tested, relying on
the settings overrides to initialize other required attributes. That
approach won't work after those settings are deprecated as part of
EMAIL_PROVIDERS.
Instead, replaced backend construction in "functional" tests with new
SharedEmailBackendTests.create_backend() which constructs the testable
backend instance with _all_ options needed to avoid global settings.
Tests to verify the settings are read correctly continue to directly
construct backend instances, without using create_backend().
|
|
Replaced TypeError in `os.path.abspath(None)` with ImproperlyConfigured
error when settings.EMAIL_FILE_PATH is required but missing.
|
|
Added tests for:
* BaseEmailBackend class.
* EmailBackend support for fail_silently arg and unknown kwargs.
* File backend support for EMAIL_FILE_PATH setting.
* File backend configuration error reporting (where possible).
* SMTP backend support for EMAIL_HOST and EMAIL_PORT settings.
* SMTP backend use of ssl_certfile, ssl_keyfile, timeout options.
* send_mail() return value.
* send_mass_mail() basic behavior.
* send_mail() and send_mass_mail() support for auth_user, auth_password,
and fail_silently args.
* get_connection() support for EMAIL_BACKEND setting and backend-specfic
kwargs.
|
|
* Removed unnecessary empty username/password args and unnecessary test
email content.
* Replaced monkeypatching with mock.patch. Minimized scope of patches.
* Added missing assertions in some tests.
* Cleaned up uses of assertTrue() and assertFalse().
* Removed implicit assumption in LocmemBackendTests that mail is always
sent by the locmem backend during tests.
* Made FileBackendTests tmp_dir cleanup more robust, and added helpers
to simplify test cases.
* Split FileBackendTests.test_sessions() into three distinct cases (and
removed unrelated, duplicative verification of message content).
* Used mock to simplify and improve accuracy of SMTP AUTH test.
* Replaced `get_connection("mail.custombackend.EmailBackend")` with
direct `custombackend.EmailBackend()` construction to avoid soon-to-
be-deprecated usage of `get_connection(backend_path)` in cases that
aren't trying to test creating a connection from an import path.
|
|
* Renamed shared backend test case class to SharedEmailBackendTests,
to avoid confusion with tests for the BaseEmailBackend.
* Used consistent module references to mail functions (removed `mail.`
from most uses; kept it for `mail.get_connection()`).
* Used consistent `backend` variable name for EmailBackend instances in
backend tests (matching most SMTP tests, replacing `connection` and
`conn` in other tests).
* Renamed some test cases for clarity.
* Removed some unnecessary docstrings from test cases.
* Reformatted some docstrings with nearby edits.
|
|
Moved tests for specific email backends from tests/mail/tests.py
to test_backends.py to reduce file size and discourage adding
non-backend-specific tests to BaseEmailBackendTests.
|
|
Relocated BaseEmailBackendTests that are _not_ dependent on the email
backend.
- In general, moved test cases to EmailMessageTests or SendMailTests
as appropriate, and changed them to work with the testing outbox.
- Replaced BaseEmailBackendTests.test_send_verbose_name() with
EmailMessageTests.test_unicode_display_name_in_from_email().
(EmailMessageTests.test_address_header_handling() also partly covers
the behavior, as well as Python's own message serialization tests.)
- Removed BaseEmailBackendTests.test_message_cc_header(), which was
already covered by EmailMessageTests.test_cc*() (and Python's own
message serialization tests).
- Replaced BaseEmailBackendTests.test_idn_send() with
EmailMessageTests.test_idn_addresses() to cover from_email and cc.
(EmailMessageTests.test_address_header_handling() already covered to.)
- Removed BaseEmailBackendTests.test_recipient_without_domain(), which
was partly covered by EmailMessageTests.test_localpart_only_address().
Updated the latter to cover a localpart-only from_email.
- Updated docstrings and comments to clarify a few tests that _do_
depend on the email backend.
|
|
Replaced large MailTests class with smaller classes focused on
specific django.core.mail APIs:
- EmailMessageTests: covering EmailMessage and EmailMultiAlternatives
classes (the bulk of the former MailTests cases).
- SendMailTests, SendMassMailTests, MailAdminsAndManagersTests:
covering the function-based mail APIs.
- GetConnectionTests: covering get_connection().
- DeprecatedInternalsTests: covering deprecated internal methods used
in deprecated functionality.
- DummyBackendTests: covering the dummy EmailBackend.
In the process, moved the two cases from MailTimeZoneTests into the new
EmailMessageTests, as they related to EmailMessage Date headers.
|
|
Broke apart independent cases in mail tests using subTest() or separate
methods.
|
|
Django automatically substitutes the locmem EmailBackend during tests,
and SimpleTestCase empties mail.outbox before each test.
|
|
A TypeError is now raised if fail_silently=True, auth_user, or auth_password
are provided along a connection.
Updated AdminEmailHandler in django.utils.log to remove redundant
fail_silently=True.
Thanks Mike Edmunds for the report and Jacob Tyler Walls for the review.
|
|
https://github.com/psf/black/releases/tag/26.1.0
|
|
|
|
- Changed EmailMessage.message() to construct a "modern email API"
email.message.EmailMessage and added policy keyword arg.
- Added support for modern MIMEPart objects in EmailMessage.attach()
(and EmailMessage constructor, EmailMessage.attachments list).
- Updated SMTP EmailBackend to use modern email.policy.SMTP.
Deprecated:
- Attaching MIMEBase objects (replace with MIMEPart)
- BadHeaderError (modern email uses ValueError)
- SafeMIMEText, SafeMIMEMultipart (unnecessary for modern email)
- django.core.mail.forbid_multi_line_headers()
(undocumented, but exposed via `__all__` and in wide use)
- django.core.mail.message.sanitize_address()
(undocumented, but in wide use)
Removed without deprecation (all undocumented):
- EmailMessage.mixed_subtype
- EmailMultiAlternatives.alternative_subtype
- Support for setting (undocumented) EmailMessage.encoding property
to a legacy email.charset.Charset object
Related changes:
- Dropped tests for incorrect RFC 2047 encoding of non-ASCII email
address localparts. This is specifically prohibited by RFC 2047, and
not supported by any known MTA or email client. (Python still
mis-applies encoded-word to non-ASCII localparts, but it is a bug that
may be fixed in the future.)
- Added tests that try to discourage using Python's legacy email APIs
in future updates to django.core.mail.
|
|
EmailMessage is intended to support lazy strings in any header field
(via coercion to `str` in forbid_multi_line_headers() called from
SafeMIMEMessage/Text/Multipart.__setitem__).
|
|
Manually reformatted some comments and docstrings where autofix_w505.py
changed the meaning of the formatting.
|
|
Rewrapped long docstrings and block comments to 79 characters + newline
using script from https://github.com/medmunds/autofix-w505.
|
|
In public mail APIs, changed less frequently used parameters from
keyword-or-positional to keyword-only, emitting a warning during the
required deprecation period.
|
|
See python/cpython#128110.
|
|
Updated mail tests in preparation for migrating from Python's legacy
to modern email API. The updated tests will pass with either Python API,
and focus on desired outcomes (e.g., that a message with non-ASCII
content parses accurately at the receiving end) rather than specific
implementation details (e.g., where rfc2047 encoded-words are split).
In a few cases that are still implementation dependent, added comments
identifying behavior specific to the legacy email API and expected to
change under the modern one.
Added comments identifying tests that cover internal functions planned
for deprecation, and (where meaningful) added similar tests to verify
the equivalent behavior in non-deprecated features.
Removed obsolete tests left over from Python 2.
|
|
Fixed an inconsistency between EmailMessage.attach() and .attachments
when attaching bytes content with a text/* mimetype. The attach()
function decodes UTF-8 bytes if possible and otherwise changes the
mimetype to application/octet-stream to preserve the content's unknown
encoding (refs #27007). Providing equivalent content directly in
EmailMessage.attachments did not apply the same logic, leading
to an "AttributeError: 'bytes' object has no attribute 'encode'"
in SafeMIMEText.set_payload().
Updated EmailMessage._create_mime_attachment() to match attach()'s
handling for text/* mimetypes with bytes content. Updated test cases
to accurately cover behavior on both paths.
|
|
Regression in aba0e541caaa086f183197eaaca0ac20a730bbe4 and in
d5bebc1c26d4c0ec9eaa057aefc5b38649c0ba3b.
Thanks Florent Messa for the report, and Jake Howard and Claude
Paroz for the review.
|
|
Python's modern email API will force a trailing newline onto all text/*
bodies and attachments. Updated mail tests to include (and check for)
the newline while still using the legacy email API.
See https://github.com/python/cpython/issues/121515 which reasons that,
apart from artificial test cases, most text content already ends in a
newline. If it doesn't, adding one won't change the meaning.
|
|
Previously, the ADMINS and MANAGERS settings were lists of (name, address)
tuples (where the name had been unused). Deprecated use of tuples.
Updated settings value sanity checks, and changed from ValueError to
ImproperlyConfigured.
|
|
- Separated MailTests.test_connection_arg test cases.
- Expanded test cases for incorrect values of ADMINS/MANAGERS settings.
- Added test case verifying correct values of ADMINS/MANAGERS settings.
|
|
Content-Transfer-Encoding.
|
|
|
|
structure, bcc header, encoding and sending.
|
|
- Used modern email API (policy.default) for tests that reparse
generated messages, and switched to modern accessors where helpful.
- Split get_raw_attachments() helper out of get_decoded_attachments(),
and used modern iter_attachments() to avoid finding nested attachments
in attached message/* emails.
- Stopped using legacy parseaddr.
|
|
- Converted HeadersCheckMixin to MailTestsMixin for all shared helpers:
- Hoisted assertStartsWith() from BaseEmailBackendTests.
- Added matching assertEndsWith().
- Hoisted get_decoded_attachments() from MailTests.
- Improved failure reporting in assertMessageHasHeaders().
- Used unittest subTest() to improve handling of compound test cases.
- Replaced `assertTrue(test on string)` with custom assertions,
so that failure reporting is more informative than `True != False`.
|
|
|
|
This also removed a duplicate CTE case (that used to be distinct in Python 2).
|
|
This also removed send() calls, as this doesn't check the serialized content, and
the backend tests cover sending.
|
|
|
|
sending fails.
On successful submission of a password reset request, an email is sent
to the accounts known to the system. If sending this email fails (due to
email backend misconfiguration, service provider outage, network issues,
etc.), an attacker might exploit this by detecting which password reset
requests succeed and which ones generate a 500 error response.
Thanks to Thibaut Spriet for the report, and to Mariusz Felisiak, Adam
Johnson, and Sarah Boyce for the reviews.
|
|
attachments and alternatives.
|
|
Fixed a regression which would cause multiple To, Cc, and
Reply-To headers in the result of EmailMessage.message() if
values were supplied for both to/cc/reply_to and the
corresponding extra_headers fields.
Updated related tests to check the generated message() has
exactly one of each expected header using get_all().
Regression in b03d5002955256c4b3ed7cfae5150eb79c0eb97e.
|
|
|
|
EmailMultiAlternatives.alternatives to use namedtuples.
This makes it more descriptive to pull out the named fields.
|
|
There is no point in asserting Python error messages.
|
|
surrogate pairs.
Refs #33173, #34118 and #34900.
|
|
https://github.com/psf/black/releases/tag/24.1.0
|
|
|
|
|
|
|