mirror of
https://github.com/pacnpal/django-anymail.git
synced 2025-12-20 11:51:05 -05:00
Compatibility with earlier Python 2.7 versions
Compatibility with Python 2.7 versions older than 2.7.7 * Use Django's constant_time_compare method * Include sparkpost in test requirements * Don't use non-public `EnvironmentVarGuard` in tests Fixes #41
This commit is contained in:
@@ -3,6 +3,7 @@ from datetime import datetime
|
|||||||
|
|
||||||
import hashlib
|
import hashlib
|
||||||
import hmac
|
import hmac
|
||||||
|
from django.utils.crypto import constant_time_compare
|
||||||
from django.utils.timezone import utc
|
from django.utils.timezone import utc
|
||||||
|
|
||||||
from .base import AnymailBaseWebhookView
|
from .base import AnymailBaseWebhookView
|
||||||
@@ -34,7 +35,7 @@ class MailgunBaseWebhookView(AnymailBaseWebhookView):
|
|||||||
raise AnymailWebhookValidationFailure("Mailgun webhook called without required security fields")
|
raise AnymailWebhookValidationFailure("Mailgun webhook called without required security fields")
|
||||||
expected_signature = hmac.new(key=self.api_key, msg='{}{}'.format(timestamp, token).encode('ascii'),
|
expected_signature = hmac.new(key=self.api_key, msg='{}{}'.format(timestamp, token).encode('ascii'),
|
||||||
digestmod=hashlib.sha256).hexdigest()
|
digestmod=hashlib.sha256).hexdigest()
|
||||||
if not hmac.compare_digest(signature, expected_signature):
|
if not constant_time_compare(signature, expected_signature):
|
||||||
raise AnymailWebhookValidationFailure("Mailgun webhook called with incorrect signature")
|
raise AnymailWebhookValidationFailure("Mailgun webhook called with incorrect signature")
|
||||||
|
|
||||||
def parse_events(self, request):
|
def parse_events(self, request):
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ from datetime import datetime
|
|||||||
import hashlib
|
import hashlib
|
||||||
import hmac
|
import hmac
|
||||||
from base64 import b64encode
|
from base64 import b64encode
|
||||||
|
from django.utils.crypto import constant_time_compare
|
||||||
from django.utils.timezone import utc
|
from django.utils.timezone import utc
|
||||||
|
|
||||||
from .base import AnymailBaseWebhookView
|
from .base import AnymailBaseWebhookView
|
||||||
@@ -44,7 +45,7 @@ class MandrillSignatureMixin(object):
|
|||||||
|
|
||||||
expected_signature = b64encode(hmac.new(key=self.webhook_key, msg=signed_data.encode('utf-8'),
|
expected_signature = b64encode(hmac.new(key=self.webhook_key, msg=signed_data.encode('utf-8'),
|
||||||
digestmod=hashlib.sha1).digest())
|
digestmod=hashlib.sha1).digest())
|
||||||
if not hmac.compare_digest(signature, expected_signature):
|
if not constant_time_compare(signature, expected_signature):
|
||||||
raise AnymailWebhookValidationFailure("Mandrill webhook called with incorrect signature")
|
raise AnymailWebhookValidationFailure("Mandrill webhook called with incorrect signature")
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
2
setup.py
2
setup.py
@@ -47,7 +47,7 @@ setup(
|
|||||||
},
|
},
|
||||||
include_package_data=True,
|
include_package_data=True,
|
||||||
test_suite="runtests.runtests",
|
test_suite="runtests.runtests",
|
||||||
tests_require=["mock"],
|
tests_require=["mock", "sparkpost"],
|
||||||
classifiers=[
|
classifiers=[
|
||||||
"Development Status :: 2 - Pre-Alpha",
|
"Development Status :: 2 - Pre-Alpha",
|
||||||
"Programming Language :: Python",
|
"Programming Language :: Python",
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
from datetime import datetime, date
|
from datetime import datetime, date
|
||||||
from email.mime.base import MIMEBase
|
from email.mime.base import MIMEBase
|
||||||
from email.mime.image import MIMEImage
|
from email.mime.image import MIMEImage
|
||||||
|
import os
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
import six
|
import six
|
||||||
@@ -17,13 +18,6 @@ from anymail.exceptions import (AnymailAPIError, AnymailUnsupportedFeature, Anym
|
|||||||
AnymailConfigurationError)
|
AnymailConfigurationError)
|
||||||
from anymail.message import attach_inline_image_file
|
from anymail.message import attach_inline_image_file
|
||||||
|
|
||||||
try:
|
|
||||||
# noinspection PyUnresolvedReferences
|
|
||||||
from test.support import EnvironmentVarGuard # python3
|
|
||||||
except ImportError:
|
|
||||||
# noinspection PyUnresolvedReferences
|
|
||||||
from test.test_support import EnvironmentVarGuard # python2
|
|
||||||
|
|
||||||
from .utils import AnymailTestMixin, decode_att, SAMPLE_IMAGE_FILENAME, sample_image_path, sample_image_content
|
from .utils import AnymailTestMixin, decode_att, SAMPLE_IMAGE_FILENAME, sample_image_path, sample_image_content
|
||||||
|
|
||||||
|
|
||||||
@@ -579,8 +573,9 @@ class SparkPostBackendImproperlyConfiguredTests(SimpleTestCase, AnymailTestMixin
|
|||||||
|
|
||||||
def test_api_key_in_env(self):
|
def test_api_key_in_env(self):
|
||||||
"""SparkPost package allows API key in env var; make sure Anymail works with that"""
|
"""SparkPost package allows API key in env var; make sure Anymail works with that"""
|
||||||
with EnvironmentVarGuard() as env:
|
with patch.dict(
|
||||||
env['SPARKPOST_API_KEY'] = 'key_from_environment'
|
os.environ,
|
||||||
|
{'SPARKPOST_API_KEY': 'key_from_environment'}):
|
||||||
conn = mail.get_connection()
|
conn = mail.get_connection()
|
||||||
# Poke into implementation details to verify:
|
# Poke into implementation details to verify:
|
||||||
self.assertIsNone(conn.api_key) # Anymail prop
|
self.assertIsNone(conn.api_key) # Anymail prop
|
||||||
|
|||||||
Reference in New Issue
Block a user