mirror of
https://github.com/django/django.git
synced 2025-06-05 11:39:13 +00:00
Fixed 35653 -- Added ssl_cafile to smtp email backend.
This commit is contained in:
parent
58e548db8b
commit
495420eec3
@ -206,6 +206,7 @@ EMAIL_HOST_USER = ""
|
|||||||
EMAIL_HOST_PASSWORD = ""
|
EMAIL_HOST_PASSWORD = ""
|
||||||
EMAIL_USE_TLS = False
|
EMAIL_USE_TLS = False
|
||||||
EMAIL_USE_SSL = False
|
EMAIL_USE_SSL = False
|
||||||
|
EMAIL_SSL_CAFILE = None
|
||||||
EMAIL_SSL_CERTFILE = None
|
EMAIL_SSL_CERTFILE = None
|
||||||
EMAIL_SSL_KEYFILE = None
|
EMAIL_SSL_KEYFILE = None
|
||||||
EMAIL_TIMEOUT = None
|
EMAIL_TIMEOUT = None
|
||||||
|
@ -28,6 +28,7 @@ class EmailBackend(BaseEmailBackend):
|
|||||||
timeout=None,
|
timeout=None,
|
||||||
ssl_keyfile=None,
|
ssl_keyfile=None,
|
||||||
ssl_certfile=None,
|
ssl_certfile=None,
|
||||||
|
ssl_cafile=None,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
):
|
):
|
||||||
super().__init__(fail_silently=fail_silently)
|
super().__init__(fail_silently=fail_silently)
|
||||||
@ -44,6 +45,9 @@ class EmailBackend(BaseEmailBackend):
|
|||||||
self.ssl_certfile = (
|
self.ssl_certfile = (
|
||||||
settings.EMAIL_SSL_CERTFILE if ssl_certfile is None else ssl_certfile
|
settings.EMAIL_SSL_CERTFILE if ssl_certfile is None else ssl_certfile
|
||||||
)
|
)
|
||||||
|
self.ssl_cafile = (
|
||||||
|
settings.EMAIL_SSL_CAFILE if ssl_cafile is None else ssl_cafile
|
||||||
|
)
|
||||||
if self.use_ssl and self.use_tls:
|
if self.use_ssl and self.use_tls:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"EMAIL_USE_TLS/EMAIL_USE_SSL are mutually exclusive, so only set "
|
"EMAIL_USE_TLS/EMAIL_USE_SSL are mutually exclusive, so only set "
|
||||||
@ -61,9 +65,13 @@ class EmailBackend(BaseEmailBackend):
|
|||||||
if self.ssl_certfile or self.ssl_keyfile:
|
if self.ssl_certfile or self.ssl_keyfile:
|
||||||
ssl_context = ssl.SSLContext(protocol=ssl.PROTOCOL_TLS_CLIENT)
|
ssl_context = ssl.SSLContext(protocol=ssl.PROTOCOL_TLS_CLIENT)
|
||||||
ssl_context.load_cert_chain(self.ssl_certfile, self.ssl_keyfile)
|
ssl_context.load_cert_chain(self.ssl_certfile, self.ssl_keyfile)
|
||||||
return ssl_context
|
|
||||||
else:
|
else:
|
||||||
return ssl.create_default_context()
|
ssl_context = ssl.create_default_context()
|
||||||
|
|
||||||
|
if self.ssl_cafile:
|
||||||
|
ssl_context.load_verify_locations(cafile=self.ssl_cafile)
|
||||||
|
|
||||||
|
return ssl_context
|
||||||
|
|
||||||
def open(self):
|
def open(self):
|
||||||
"""
|
"""
|
||||||
|
@ -1495,6 +1495,17 @@ see the explicit TLS setting :setting:`EMAIL_USE_TLS`.
|
|||||||
Note that :setting:`EMAIL_USE_TLS`/:setting:`EMAIL_USE_SSL` are mutually
|
Note that :setting:`EMAIL_USE_TLS`/:setting:`EMAIL_USE_SSL` are mutually
|
||||||
exclusive, so only set one of those settings to ``True``.
|
exclusive, so only set one of those settings to ``True``.
|
||||||
|
|
||||||
|
.. setting:: EMAIL_SSL_CAFILE
|
||||||
|
|
||||||
|
``EMAIL_SSL_CAFILE``
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
Default: ``None``
|
||||||
|
|
||||||
|
If :setting:`EMAIL_USE_SSL` or :setting:`EMAIL_USE_TLS` is ``True``, you can
|
||||||
|
optionally specify the path to a PEM-formatted certificate authority
|
||||||
|
root certificate to validate the SSL connection.
|
||||||
|
|
||||||
.. setting:: EMAIL_SSL_CERTFILE
|
.. setting:: EMAIL_SSL_CERTFILE
|
||||||
|
|
||||||
``EMAIL_SSL_CERTFILE``
|
``EMAIL_SSL_CERTFILE``
|
||||||
@ -1517,8 +1528,9 @@ If :setting:`EMAIL_USE_SSL` or :setting:`EMAIL_USE_TLS` is ``True``, you can
|
|||||||
optionally specify the path to a PEM-formatted private key file to use for the
|
optionally specify the path to a PEM-formatted private key file to use for the
|
||||||
SSL connection.
|
SSL connection.
|
||||||
|
|
||||||
Note that setting :setting:`EMAIL_SSL_CERTFILE` and :setting:`EMAIL_SSL_KEYFILE`
|
Note that setting :setting:`EMAIL_SSL_CERTFILE`, :setting:`EMAIL_SSL_KEYFILE`
|
||||||
doesn't result in any certificate checking. They're passed to the underlying SSL
|
or :setting:`EMAIL_SSL_CAFILE` doesn't result in any certificate checking.
|
||||||
|
They're passed to the underlying SSL
|
||||||
connection. Please refer to the documentation of Python's
|
connection. Please refer to the documentation of Python's
|
||||||
:meth:`python:ssl.SSLContext.wrap_socket` function for details on how the
|
:meth:`python:ssl.SSLContext.wrap_socket` function for details on how the
|
||||||
certificate chain file and private key file are handled.
|
certificate chain file and private key file are handled.
|
||||||
@ -3631,6 +3643,7 @@ Email
|
|||||||
* :setting:`EMAIL_HOST_PASSWORD`
|
* :setting:`EMAIL_HOST_PASSWORD`
|
||||||
* :setting:`EMAIL_HOST_USER`
|
* :setting:`EMAIL_HOST_USER`
|
||||||
* :setting:`EMAIL_PORT`
|
* :setting:`EMAIL_PORT`
|
||||||
|
* :setting:`EMAIL_SSL_CAFILE`
|
||||||
* :setting:`EMAIL_SSL_CERTFILE`
|
* :setting:`EMAIL_SSL_CERTFILE`
|
||||||
* :setting:`EMAIL_SSL_KEYFILE`
|
* :setting:`EMAIL_SSL_KEYFILE`
|
||||||
* :setting:`EMAIL_SUBJECT_PREFIX`
|
* :setting:`EMAIL_SUBJECT_PREFIX`
|
||||||
|
@ -220,6 +220,9 @@ Email
|
|||||||
returns a boolean indicating whether a provided text is contained in the
|
returns a boolean indicating whether a provided text is contained in the
|
||||||
email ``body`` and in all attached MIME type ``text/*`` alternatives.
|
email ``body`` and in all attached MIME type ``text/*`` alternatives.
|
||||||
|
|
||||||
|
* The SMTP email backend now supports certificate validation using a ``cafile``
|
||||||
|
with the :setting:`EMAIL_SSL_CAFILE` setting.
|
||||||
|
|
||||||
Error Reporting
|
Error Reporting
|
||||||
~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
@ -605,7 +605,7 @@ can :ref:`write your own email backend <topic-custom-email-backend>`.
|
|||||||
SMTP backend
|
SMTP backend
|
||||||
~~~~~~~~~~~~
|
~~~~~~~~~~~~
|
||||||
|
|
||||||
.. class:: backends.smtp.EmailBackend(host=None, port=None, username=None, password=None, use_tls=None, fail_silently=False, use_ssl=None, timeout=None, ssl_keyfile=None, ssl_certfile=None, **kwargs)
|
.. class:: backends.smtp.EmailBackend(host=None, port=None, username=None, password=None, use_tls=None, fail_silently=False, use_ssl=None, timeout=None, ssl_keyfile=None, ssl_certfile=None, ssl_cafile=None, **kwargs)
|
||||||
|
|
||||||
This is the default backend. Email will be sent through a SMTP server.
|
This is the default backend. Email will be sent through a SMTP server.
|
||||||
|
|
||||||
@ -621,6 +621,7 @@ SMTP backend
|
|||||||
* ``timeout``: :setting:`EMAIL_TIMEOUT`
|
* ``timeout``: :setting:`EMAIL_TIMEOUT`
|
||||||
* ``ssl_keyfile``: :setting:`EMAIL_SSL_KEYFILE`
|
* ``ssl_keyfile``: :setting:`EMAIL_SSL_KEYFILE`
|
||||||
* ``ssl_certfile``: :setting:`EMAIL_SSL_CERTFILE`
|
* ``ssl_certfile``: :setting:`EMAIL_SSL_CERTFILE`
|
||||||
|
* ``ssl_cafile``: :setting:`EMAIL_SSL_CAFILE`
|
||||||
|
|
||||||
The SMTP backend is the default configuration inherited by Django. If you
|
The SMTP backend is the default configuration inherited by Django. If you
|
||||||
want to specify it explicitly, put the following in your settings::
|
want to specify it explicitly, put the following in your settings::
|
||||||
|
@ -2269,16 +2269,30 @@ class SMTPBackendTests(BaseEmailBackendTests, SMTPBackendTestsBase):
|
|||||||
backend = smtp.EmailBackend()
|
backend = smtp.EmailBackend()
|
||||||
self.assertFalse(backend.use_ssl)
|
self.assertFalse(backend.use_ssl)
|
||||||
|
|
||||||
|
@override_settings(EMAIL_SSL_CAFILE="foo")
|
||||||
|
def test_email_ssl_cafile_use_settings(self):
|
||||||
|
backend = smtp.EmailBackend()
|
||||||
|
self.assertEqual(backend.ssl_cafile, "foo")
|
||||||
|
|
||||||
@override_settings(EMAIL_SSL_CERTFILE="foo")
|
@override_settings(EMAIL_SSL_CERTFILE="foo")
|
||||||
def test_email_ssl_certfile_use_settings(self):
|
def test_email_ssl_certfile_use_settings(self):
|
||||||
backend = smtp.EmailBackend()
|
backend = smtp.EmailBackend()
|
||||||
self.assertEqual(backend.ssl_certfile, "foo")
|
self.assertEqual(backend.ssl_certfile, "foo")
|
||||||
|
|
||||||
|
@override_settings(EMAIL_SSL_CAFILE="foo")
|
||||||
|
def test_email_ssl_cafile_override_settings(self):
|
||||||
|
backend = smtp.EmailBackend(ssl_cafile="bar")
|
||||||
|
self.assertEqual(backend.ssl_cafile, "bar")
|
||||||
|
|
||||||
@override_settings(EMAIL_SSL_CERTFILE="foo")
|
@override_settings(EMAIL_SSL_CERTFILE="foo")
|
||||||
def test_email_ssl_certfile_override_settings(self):
|
def test_email_ssl_certfile_override_settings(self):
|
||||||
backend = smtp.EmailBackend(ssl_certfile="bar")
|
backend = smtp.EmailBackend(ssl_certfile="bar")
|
||||||
self.assertEqual(backend.ssl_certfile, "bar")
|
self.assertEqual(backend.ssl_certfile, "bar")
|
||||||
|
|
||||||
|
def test_email_ssl_cafile_default_disabled(self):
|
||||||
|
backend = smtp.EmailBackend()
|
||||||
|
self.assertIsNone(backend.ssl_cafile)
|
||||||
|
|
||||||
def test_email_ssl_certfile_default_disabled(self):
|
def test_email_ssl_certfile_default_disabled(self):
|
||||||
backend = smtp.EmailBackend()
|
backend = smtp.EmailBackend()
|
||||||
self.assertIsNone(backend.ssl_certfile)
|
self.assertIsNone(backend.ssl_certfile)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user