mirror of
https://github.com/pacnpal/django-anymail.git
synced 2025-12-20 11:51:05 -05:00
Docs: document DEBUG_API_REQUESTS setting
(And add a system check to warn about its use in production deployment.)
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
from django.apps import AppConfig
|
from django.apps import AppConfig
|
||||||
from django.core import checks
|
from django.core import checks
|
||||||
|
|
||||||
from .checks import check_deprecated_settings
|
from .checks import check_deprecated_settings, check_insecure_settings
|
||||||
|
|
||||||
|
|
||||||
class AnymailBaseConfig(AppConfig):
|
class AnymailBaseConfig(AppConfig):
|
||||||
@@ -10,3 +10,4 @@ class AnymailBaseConfig(AppConfig):
|
|||||||
|
|
||||||
def ready(self):
|
def ready(self):
|
||||||
checks.register(check_deprecated_settings)
|
checks.register(check_deprecated_settings)
|
||||||
|
checks.register(check_insecure_settings)
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core import checks
|
from django.core import checks
|
||||||
|
|
||||||
|
from anymail.utils import get_anymail_setting
|
||||||
|
|
||||||
|
|
||||||
def check_deprecated_settings(app_configs, **kwargs):
|
def check_deprecated_settings(app_configs, **kwargs):
|
||||||
errors = []
|
errors = []
|
||||||
@@ -24,3 +26,18 @@ def check_deprecated_settings(app_configs, **kwargs):
|
|||||||
))
|
))
|
||||||
|
|
||||||
return errors
|
return errors
|
||||||
|
|
||||||
|
|
||||||
|
def check_insecure_settings(app_configs, **kwargs):
|
||||||
|
errors = []
|
||||||
|
|
||||||
|
# anymail.W002: DEBUG_API_REQUESTS can leak private information
|
||||||
|
if get_anymail_setting("debug_api_requests", default=False) and not settings.DEBUG:
|
||||||
|
errors.append(checks.Warning(
|
||||||
|
"You have enabled the ANYMAIL setting DEBUG_API_REQUESTS, which can "
|
||||||
|
"leak API keys and other sensitive data into logs or the console.",
|
||||||
|
hint="You should not use DEBUG_API_REQUESTS in production deployment.",
|
||||||
|
id="anymail.W002",
|
||||||
|
))
|
||||||
|
|
||||||
|
return errors
|
||||||
|
|||||||
@@ -44,6 +44,14 @@ often help you pinpoint the problem...
|
|||||||
other than Anymail. And you can look through the :setting:`EMAIL_FILE_PATH`
|
other than Anymail. And you can look through the :setting:`EMAIL_FILE_PATH`
|
||||||
file contents afterward to see if you're generating the email you want.
|
file contents afterward to see if you're generating the email you want.
|
||||||
|
|
||||||
|
**Examine the raw API communication**
|
||||||
|
|
||||||
|
Sometimes you just want to see exactly what Anymail is telling your ESP to do
|
||||||
|
and how your ESP is responding. In a dev environment, enable the Anymail setting
|
||||||
|
:setting:`DEBUG_API_REQUESTS <ANYMAIL_DEBUG_API_REQUESTS>`
|
||||||
|
to show the raw HTTP requests and responses from (most) ESP APIs. (This is not
|
||||||
|
recommended in production, as it can leak sensitive data into your logs.)
|
||||||
|
|
||||||
|
|
||||||
.. _contact:
|
.. _contact:
|
||||||
.. _support:
|
.. _support:
|
||||||
|
|||||||
@@ -299,3 +299,25 @@ For Requests-based Anymail backends, the timeout value used for all API calls to
|
|||||||
The default is 30 seconds. You can set to a single float, a 2-tuple of floats for
|
The default is 30 seconds. You can set to a single float, a 2-tuple of floats for
|
||||||
separate connection and read timeouts, or `None` to disable timeouts (not recommended).
|
separate connection and read timeouts, or `None` to disable timeouts (not recommended).
|
||||||
See :ref:`requests:timeouts` in the Requests docs for more information.
|
See :ref:`requests:timeouts` in the Requests docs for more information.
|
||||||
|
|
||||||
|
|
||||||
|
.. setting:: ANYMAIL_DEBUG_API_REQUESTS
|
||||||
|
|
||||||
|
.. rubric:: DEBUG_API_REQUESTS
|
||||||
|
|
||||||
|
.. versionadded:: 4.3
|
||||||
|
|
||||||
|
When set to `True`, outputs the raw API communication with the ESP, to assist in
|
||||||
|
debugging. Each HTTP request and ESP response is dumped to :data:`sys.stdout` once
|
||||||
|
the response is received.
|
||||||
|
|
||||||
|
.. caution::
|
||||||
|
|
||||||
|
Do not enable :setting:`!DEBUG_API_REQUESTS` in production deployments. The debug
|
||||||
|
output will include your API keys, email addresses, and other sensitive data
|
||||||
|
that you generally don't want to capture in server logs or reveal on the console.
|
||||||
|
|
||||||
|
:setting:`!DEBUG_API_REQUESTS` only applies to sending email through Requests-based
|
||||||
|
Anymail backends. For other backends, there may be similar debugging facilities
|
||||||
|
available in the ESP's API wrapper package (e.g., ``boto3.set_stream_logger`` for
|
||||||
|
Amazon SES).
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ from django.core import checks
|
|||||||
from django.test import SimpleTestCase
|
from django.test import SimpleTestCase
|
||||||
from django.test.utils import override_settings
|
from django.test.utils import override_settings
|
||||||
|
|
||||||
from anymail.checks import check_deprecated_settings
|
from anymail.checks import check_deprecated_settings, check_insecure_settings
|
||||||
|
|
||||||
from .utils import AnymailTestMixin
|
from .utils import AnymailTestMixin
|
||||||
|
|
||||||
@@ -25,3 +25,16 @@ class DeprecatedSettingsTests(SimpleTestCase, AnymailTestMixin):
|
|||||||
hint="You must update your settings.py.",
|
hint="You must update your settings.py.",
|
||||||
id="anymail.E001",
|
id="anymail.E001",
|
||||||
)])
|
)])
|
||||||
|
|
||||||
|
|
||||||
|
class InsecureSettingsTests(SimpleTestCase, AnymailTestMixin):
|
||||||
|
@override_settings(ANYMAIL={"DEBUG_API_REQUESTS": True})
|
||||||
|
def test_debug_api_requests_deployed(self):
|
||||||
|
errors = check_insecure_settings(None)
|
||||||
|
self.assertEqual(len(errors), 1)
|
||||||
|
self.assertEqual(errors[0].id, "anymail.W002")
|
||||||
|
|
||||||
|
@override_settings(ANYMAIL={"DEBUG_API_REQUESTS": True}, DEBUG=True)
|
||||||
|
def test_debug_api_requests_debug(self):
|
||||||
|
errors = check_insecure_settings(None)
|
||||||
|
self.assertEqual(len(errors), 0) # no warning in DEBUG (non-production) config
|
||||||
|
|||||||
Reference in New Issue
Block a user