Loading django/conf/global_settings.py +1 −0 Original line number Diff line number Diff line Loading @@ -184,6 +184,7 @@ EMAIL_PORT = 25 EMAIL_HOST_USER = '' EMAIL_HOST_PASSWORD = '' EMAIL_USE_TLS = False EMAIL_USE_SSL = False # List of strings representing installed apps. INSTALLED_APPS = () Loading django/core/mail/backends/smtp.py +20 −18 Original line number Diff line number Diff line Loading @@ -15,22 +15,18 @@ class EmailBackend(BaseEmailBackend): A wrapper that manages the SMTP network connection. """ def __init__(self, host=None, port=None, username=None, password=None, use_tls=None, fail_silently=False, **kwargs): use_tls=None, fail_silently=False, use_ssl=None, **kwargs): super(EmailBackend, self).__init__(fail_silently=fail_silently) self.host = host or settings.EMAIL_HOST self.port = port or settings.EMAIL_PORT if username is None: self.username = settings.EMAIL_HOST_USER else: self.username = username if password is None: self.password = settings.EMAIL_HOST_PASSWORD else: self.password = password if use_tls is None: self.use_tls = settings.EMAIL_USE_TLS else: self.use_tls = use_tls self.username = settings.EMAIL_HOST_USER if username is None else username self.password = settings.EMAIL_HOST_PASSWORD if password is None else password self.use_tls = settings.EMAIL_USE_TLS if use_tls is None else use_tls self.use_ssl = settings.EMAIL_USE_SSL if use_ssl is None else use_ssl if self.use_ssl and self.use_tls: raise ValueError( "EMAIL_USE_TLS/EMAIL_USE_SSL are mutually exclusive, so only set " "one of those settings to True.") self.connection = None self._lock = threading.RLock() Loading @@ -45,8 +41,14 @@ class EmailBackend(BaseEmailBackend): try: # If local_hostname is not specified, socket.getfqdn() gets used. # For performance, we use the cached FQDN for local_hostname. if self.use_ssl: self.connection = smtplib.SMTP_SSL(self.host, self.port, local_hostname=DNS_NAME.get_fqdn()) else: self.connection = smtplib.SMTP(self.host, self.port, local_hostname=DNS_NAME.get_fqdn()) # TLS/SSL are mutually exclusive, so only attempt TLS over # non-secure connections. if self.use_tls: self.connection.ehlo() self.connection.starttls() Loading docs/ref/settings.txt +20 −0 Original line number Diff line number Diff line Loading @@ -1055,6 +1055,26 @@ EMAIL_USE_TLS Default: ``False`` Whether to use a TLS (secure) connection when talking to the SMTP server. This is used for explicit TLS connections, generally on port 587. If you are experiencing hanging connections, see the implicit TLS setting :setting:`EMAIL_USE_SSL`. .. setting:: EMAIL_USE_SSL EMAIL_USE_SSL ------------- .. versionadded:: 1.7 Default: ``False`` Whether to use an implicit TLS (secure) connection when talking to the SMTP server. In most email documentation this type of TLS connection is referred to as SSL. It is generally used on port 465. If you are experiencing problems, see the explicit TLS setting :setting:`EMAIL_USE_TLS`. Note that :setting:`EMAIL_USE_TLS`/:setting:`EMAIL_USE_SSL` are mutually exclusive, so only set one of those settings to ``True``. .. setting:: FILE_CHARSET Loading docs/topics/email.txt +4 −3 Original line number Diff line number Diff line Loading @@ -27,7 +27,8 @@ Mail is sent using the SMTP host and port specified in the :setting:`EMAIL_HOST` and :setting:`EMAIL_PORT` settings. The :setting:`EMAIL_HOST_USER` and :setting:`EMAIL_HOST_PASSWORD` settings, if set, are used to authenticate to the SMTP server, and the :setting:`EMAIL_USE_TLS` setting controls whether a secure connection is used. :setting:`EMAIL_USE_TLS` and :setting:`EMAIL_USE_SSL` settings control whether a secure connection is used. .. note:: Loading Loading @@ -408,8 +409,8 @@ SMTP backend This is the default backend. Email will be sent through a SMTP server. The server address and authentication credentials are set in the :setting:`EMAIL_HOST`, :setting:`EMAIL_PORT`, :setting:`EMAIL_HOST_USER`, :setting:`EMAIL_HOST_PASSWORD` and :setting:`EMAIL_USE_TLS` settings in your settings file. :setting:`EMAIL_HOST_PASSWORD`, :setting:`EMAIL_USE_TLS` and :setting:`EMAIL_USE_SSL` settings in your settings file. The SMTP backend is the default configuration inherited by Django. If you want to specify it explicitly, put the following in your settings:: Loading tests/mail/tests.py +55 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,8 @@ import smtpd import sys import tempfile import threading from smtplib import SMTPException from ssl import SSLError from django.core import mail from django.core.mail import (EmailMessage, mail_admins, mail_managers, Loading Loading @@ -621,11 +623,23 @@ class ConsoleBackendTests(BaseEmailBackendTests, TestCase): self.assertTrue(s.getvalue().startswith('Content-Type: text/plain; charset="utf-8"\nMIME-Version: 1.0\nContent-Transfer-Encoding: 7bit\nSubject: Subject\nFrom: from@example.com\nTo: to@example.com\nDate: ')) class FakeSMTPChannel(smtpd.SMTPChannel): def collect_incoming_data(self, data): try: super(FakeSMTPChannel, self).collect_incoming_data(data) except UnicodeDecodeError: # ignore decode error in SSL/TLS connection tests as we only care # whether the connection attempt was made pass class FakeSMTPServer(smtpd.SMTPServer, threading.Thread): """ Asyncore SMTP server wrapped into a thread. Based on DummyFTPServer from: http://svn.python.org/view/python/branches/py3k/Lib/test/test_ftplib.py?revision=86061&view=markup """ channel_class = FakeSMTPChannel def __init__(self, *args, **kwargs): threading.Thread.__init__(self) Loading Loading @@ -738,3 +752,44 @@ class SMTPBackendTests(BaseEmailBackendTests, TestCase): backend.close() except Exception as e: self.fail("close() unexpectedly raised an exception: %s" % e) @override_settings(EMAIL_USE_TLS=True) def test_email_tls_use_settings(self): backend = smtp.EmailBackend() self.assertTrue(backend.use_tls) @override_settings(EMAIL_USE_TLS=True) def test_email_tls_override_settings(self): backend = smtp.EmailBackend(use_tls=False) self.assertFalse(backend.use_tls) def test_email_tls_default_disabled(self): backend = smtp.EmailBackend() self.assertFalse(backend.use_tls) @override_settings(EMAIL_USE_SSL=True) def test_email_ssl_use_settings(self): backend = smtp.EmailBackend() self.assertTrue(backend.use_ssl) @override_settings(EMAIL_USE_SSL=True) def test_email_ssl_override_settings(self): backend = smtp.EmailBackend(use_ssl=False) self.assertFalse(backend.use_ssl) def test_email_ssl_default_disabled(self): backend = smtp.EmailBackend() self.assertFalse(backend.use_ssl) @override_settings(EMAIL_USE_TLS=True) def test_email_tls_attempts_starttls(self): backend = smtp.EmailBackend() self.assertTrue(backend.use_tls) self.assertRaisesMessage(SMTPException, 'STARTTLS extension not supported by server.', backend.open) @override_settings(EMAIL_USE_SSL=True) def test_email_ssl_attempts_ssl_connection(self): backend = smtp.EmailBackend() self.assertTrue(backend.use_ssl) self.assertRaises(SSLError, backend.open) Loading
django/conf/global_settings.py +1 −0 Original line number Diff line number Diff line Loading @@ -184,6 +184,7 @@ EMAIL_PORT = 25 EMAIL_HOST_USER = '' EMAIL_HOST_PASSWORD = '' EMAIL_USE_TLS = False EMAIL_USE_SSL = False # List of strings representing installed apps. INSTALLED_APPS = () Loading
django/core/mail/backends/smtp.py +20 −18 Original line number Diff line number Diff line Loading @@ -15,22 +15,18 @@ class EmailBackend(BaseEmailBackend): A wrapper that manages the SMTP network connection. """ def __init__(self, host=None, port=None, username=None, password=None, use_tls=None, fail_silently=False, **kwargs): use_tls=None, fail_silently=False, use_ssl=None, **kwargs): super(EmailBackend, self).__init__(fail_silently=fail_silently) self.host = host or settings.EMAIL_HOST self.port = port or settings.EMAIL_PORT if username is None: self.username = settings.EMAIL_HOST_USER else: self.username = username if password is None: self.password = settings.EMAIL_HOST_PASSWORD else: self.password = password if use_tls is None: self.use_tls = settings.EMAIL_USE_TLS else: self.use_tls = use_tls self.username = settings.EMAIL_HOST_USER if username is None else username self.password = settings.EMAIL_HOST_PASSWORD if password is None else password self.use_tls = settings.EMAIL_USE_TLS if use_tls is None else use_tls self.use_ssl = settings.EMAIL_USE_SSL if use_ssl is None else use_ssl if self.use_ssl and self.use_tls: raise ValueError( "EMAIL_USE_TLS/EMAIL_USE_SSL are mutually exclusive, so only set " "one of those settings to True.") self.connection = None self._lock = threading.RLock() Loading @@ -45,8 +41,14 @@ class EmailBackend(BaseEmailBackend): try: # If local_hostname is not specified, socket.getfqdn() gets used. # For performance, we use the cached FQDN for local_hostname. if self.use_ssl: self.connection = smtplib.SMTP_SSL(self.host, self.port, local_hostname=DNS_NAME.get_fqdn()) else: self.connection = smtplib.SMTP(self.host, self.port, local_hostname=DNS_NAME.get_fqdn()) # TLS/SSL are mutually exclusive, so only attempt TLS over # non-secure connections. if self.use_tls: self.connection.ehlo() self.connection.starttls() Loading
docs/ref/settings.txt +20 −0 Original line number Diff line number Diff line Loading @@ -1055,6 +1055,26 @@ EMAIL_USE_TLS Default: ``False`` Whether to use a TLS (secure) connection when talking to the SMTP server. This is used for explicit TLS connections, generally on port 587. If you are experiencing hanging connections, see the implicit TLS setting :setting:`EMAIL_USE_SSL`. .. setting:: EMAIL_USE_SSL EMAIL_USE_SSL ------------- .. versionadded:: 1.7 Default: ``False`` Whether to use an implicit TLS (secure) connection when talking to the SMTP server. In most email documentation this type of TLS connection is referred to as SSL. It is generally used on port 465. If you are experiencing problems, see the explicit TLS setting :setting:`EMAIL_USE_TLS`. Note that :setting:`EMAIL_USE_TLS`/:setting:`EMAIL_USE_SSL` are mutually exclusive, so only set one of those settings to ``True``. .. setting:: FILE_CHARSET Loading
docs/topics/email.txt +4 −3 Original line number Diff line number Diff line Loading @@ -27,7 +27,8 @@ Mail is sent using the SMTP host and port specified in the :setting:`EMAIL_HOST` and :setting:`EMAIL_PORT` settings. The :setting:`EMAIL_HOST_USER` and :setting:`EMAIL_HOST_PASSWORD` settings, if set, are used to authenticate to the SMTP server, and the :setting:`EMAIL_USE_TLS` setting controls whether a secure connection is used. :setting:`EMAIL_USE_TLS` and :setting:`EMAIL_USE_SSL` settings control whether a secure connection is used. .. note:: Loading Loading @@ -408,8 +409,8 @@ SMTP backend This is the default backend. Email will be sent through a SMTP server. The server address and authentication credentials are set in the :setting:`EMAIL_HOST`, :setting:`EMAIL_PORT`, :setting:`EMAIL_HOST_USER`, :setting:`EMAIL_HOST_PASSWORD` and :setting:`EMAIL_USE_TLS` settings in your settings file. :setting:`EMAIL_HOST_PASSWORD`, :setting:`EMAIL_USE_TLS` and :setting:`EMAIL_USE_SSL` settings in your settings file. The SMTP backend is the default configuration inherited by Django. If you want to specify it explicitly, put the following in your settings:: Loading
tests/mail/tests.py +55 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,8 @@ import smtpd import sys import tempfile import threading from smtplib import SMTPException from ssl import SSLError from django.core import mail from django.core.mail import (EmailMessage, mail_admins, mail_managers, Loading Loading @@ -621,11 +623,23 @@ class ConsoleBackendTests(BaseEmailBackendTests, TestCase): self.assertTrue(s.getvalue().startswith('Content-Type: text/plain; charset="utf-8"\nMIME-Version: 1.0\nContent-Transfer-Encoding: 7bit\nSubject: Subject\nFrom: from@example.com\nTo: to@example.com\nDate: ')) class FakeSMTPChannel(smtpd.SMTPChannel): def collect_incoming_data(self, data): try: super(FakeSMTPChannel, self).collect_incoming_data(data) except UnicodeDecodeError: # ignore decode error in SSL/TLS connection tests as we only care # whether the connection attempt was made pass class FakeSMTPServer(smtpd.SMTPServer, threading.Thread): """ Asyncore SMTP server wrapped into a thread. Based on DummyFTPServer from: http://svn.python.org/view/python/branches/py3k/Lib/test/test_ftplib.py?revision=86061&view=markup """ channel_class = FakeSMTPChannel def __init__(self, *args, **kwargs): threading.Thread.__init__(self) Loading Loading @@ -738,3 +752,44 @@ class SMTPBackendTests(BaseEmailBackendTests, TestCase): backend.close() except Exception as e: self.fail("close() unexpectedly raised an exception: %s" % e) @override_settings(EMAIL_USE_TLS=True) def test_email_tls_use_settings(self): backend = smtp.EmailBackend() self.assertTrue(backend.use_tls) @override_settings(EMAIL_USE_TLS=True) def test_email_tls_override_settings(self): backend = smtp.EmailBackend(use_tls=False) self.assertFalse(backend.use_tls) def test_email_tls_default_disabled(self): backend = smtp.EmailBackend() self.assertFalse(backend.use_tls) @override_settings(EMAIL_USE_SSL=True) def test_email_ssl_use_settings(self): backend = smtp.EmailBackend() self.assertTrue(backend.use_ssl) @override_settings(EMAIL_USE_SSL=True) def test_email_ssl_override_settings(self): backend = smtp.EmailBackend(use_ssl=False) self.assertFalse(backend.use_ssl) def test_email_ssl_default_disabled(self): backend = smtp.EmailBackend() self.assertFalse(backend.use_ssl) @override_settings(EMAIL_USE_TLS=True) def test_email_tls_attempts_starttls(self): backend = smtp.EmailBackend() self.assertTrue(backend.use_tls) self.assertRaisesMessage(SMTPException, 'STARTTLS extension not supported by server.', backend.open) @override_settings(EMAIL_USE_SSL=True) def test_email_ssl_attempts_ssl_connection(self): backend = smtp.EmailBackend() self.assertTrue(backend.use_ssl) self.assertRaises(SSLError, backend.open)