Opened 4 months ago

Closed 2 weeks ago

#37167 closed Cleanup/optimization (fixed)

(Officially) allow Address objects as email addresses

Reported by: Mike Edmunds Owned by: VIZZARD-X
Component: Core (Mail) Version: dev
Severity: Normal Keywords:
Cc: VIZZARD-X Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Django should officially support Python email.headerregistry.Address objects in django.core.mail functions and the ADMINS, MANAGERS, DEFAULT_FROM_EMAIL, and SERVER_EMAIL settings.

This actually works now (for everything except ADMINS and MANAGERS), but isn't officially documented or tested. (And it would work for ADMINS and MANAGERS except that they specifically reject any non-str values to help avoid config errors.)

Forum request: ​https://forum.djangoproject.com/t/ticket-34753-document-how-to-properly-escape-to-in-email-messages/43551/10.

Background

Python's ​email.headerregistry.Address object can be used to compose an email address from parts (a display_name and addr_spec or username and domain). And for security, it should be used when building an email address from user-supplied parts (see #34753 and ​PR #21467).

Python's EmailMessage class accepts Address objects in all address headers. You can a set a message's "From" header to an Address, or its "Cc" header to a list of Address objects. (You can also set a "Date" header to a datetime object, etc.)

Django's EmailMessage class accidentally supports Address objects, in all headers since 6.0 and in all but "From" since at least 5.2 (maybe earlier). It currently converts the address objects to strings, and then Python parses them back into address objects.

Proposal

  • Update the ADMINS and MANAGERS recipient-type check in django.core.mail._send_server_message() to allow Address.
  • Change EmailMessage.message() and _set_list_header_if_not_empty() to avoid casting an Address to a str just so Python can parse it back again. (The cast is there primarily for lazy strings.)
  • Add tests!

Change History (10)

comment:1 by Tim Graham, 4 months ago

Triage Stage: Unreviewed → Accepted

comment:2 by Mike Edmunds, 4 months ago

Owner: Mike Edmunds removed
Status: assigned → new

comment:3 by VIZZARD-X, 3 months ago

Owner: set to VIZZARD-X
Status: new → assigned

comment:4 by VIZZARD-X, 3 months ago

Has patch: set

comment:5 by Mike Edmunds, 7 weeks ago

Patch needs improvement: set

comment:6 by VIZZARD-X, 5 weeks ago

Cc: VIZZARD-X added
Patch needs improvement: unset

comment:7 by Mike Edmunds, 5 weeks ago

Triage Stage: Accepted → Ready for checkin
Version: 6.0 → dev

comment:8 by Natalia Bidart, 4 weeks ago

Patch needs improvement: set
Triage Stage: Ready for checkin → Accepted

Updating flags based on latest review.

comment:9 by Natalia Bidart, 2 weeks ago

Patch needs improvement: unset
Triage Stage: Accepted → Ready for checkin

comment:10 by nessita <124304+nessita@…>, 2 weeks ago

Resolution: → fixed
Status: assigned → closed

In 80ea222:

Fixed #37167 -- Allowed email.headerregistry.Address objects as email addresses.

Address is the safe way to build an email address with a display name
from variable parts (see #34753), but ADMINS and MANAGERS rejected
non-string values, so it could not be used there. This branch allows
Address instances in those settings, documents, and tests the support
already present in DEFAULT_FROM_EMAIL, SERVER_EMAIL, send_mail(),
send_mass_mail(), and EmailMessage.

Co-authored-by: Natalia <124304+nessita@…>

Note: See TracTickets for help on using tickets.
Back to Top