Skip to content

Commit 8c38b69

Browse files
sebbaconmedmunds
authored andcommitted
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 (cherry picked from commit f0589e3)
1 parent 5ea93ce commit 8c38b69

File tree

4 files changed

+9
-12
lines changed

4 files changed

+9
-12
lines changed

anymail/webhooks/mailgun.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
import hashlib
55
import hmac
6+
from django.utils.crypto import constant_time_compare
67
from django.utils.timezone import utc
78

89
from .base import AnymailBaseWebhookView
@@ -34,7 +35,7 @@ def validate_request(self, request):
3435
raise AnymailWebhookValidationFailure("Mailgun webhook called without required security fields")
3536
expected_signature = hmac.new(key=self.api_key, msg='{}{}'.format(timestamp, token).encode('ascii'),
3637
digestmod=hashlib.sha256).hexdigest()
37-
if not hmac.compare_digest(signature, expected_signature):
38+
if not constant_time_compare(signature, expected_signature):
3839
raise AnymailWebhookValidationFailure("Mailgun webhook called with incorrect signature")
3940

4041
def parse_events(self, request):

anymail/webhooks/mandrill.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import hashlib
55
import hmac
66
from base64 import b64encode
7+
from django.utils.crypto import constant_time_compare
78
from django.utils.timezone import utc
89

910
from .base import AnymailBaseWebhookView
@@ -44,7 +45,7 @@ def validate_request(self, request):
4445

4546
expected_signature = b64encode(hmac.new(key=self.webhook_key, msg=signed_data.encode('utf-8'),
4647
digestmod=hashlib.sha1).digest())
47-
if not hmac.compare_digest(signature, expected_signature):
48+
if not constant_time_compare(signature, expected_signature):
4849
raise AnymailWebhookValidationFailure("Mandrill webhook called with incorrect signature")
4950

5051

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def long_description_from_readme(rst):
4747
},
4848
include_package_data=True,
4949
test_suite="runtests.runtests",
50-
tests_require=["mock"],
50+
tests_require=["mock", "sparkpost"],
5151
classifiers=[
5252
"Development Status :: 2 - Pre-Alpha",
5353
"Programming Language :: Python",

tests/test_sparkpost_backend.py

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from datetime import datetime, date
44
from email.mime.base import MIMEBase
55
from email.mime.image import MIMEImage
6+
import os
67

78
import requests
89
import six
@@ -17,13 +18,6 @@
1718
AnymailConfigurationError)
1819
from anymail.message import attach_inline_image_file
1920

20-
try:
21-
# noinspection PyUnresolvedReferences
22-
from test.support import EnvironmentVarGuard # python3
23-
except ImportError:
24-
# noinspection PyUnresolvedReferences
25-
from test.test_support import EnvironmentVarGuard # python2
26-
2721
from .utils import AnymailTestMixin, decode_att, SAMPLE_IMAGE_FILENAME, sample_image_path, sample_image_content
2822

2923

@@ -579,8 +573,9 @@ def test_missing_api_key(self):
579573

580574
def test_api_key_in_env(self):
581575
"""SparkPost package allows API key in env var; make sure Anymail works with that"""
582-
with EnvironmentVarGuard() as env:
583-
env['SPARKPOST_API_KEY'] = 'key_from_environment'
576+
with patch.dict(
577+
os.environ,
578+
{'SPARKPOST_API_KEY': 'key_from_environment'}):
584579
conn = mail.get_connection()
585580
# Poke into implementation details to verify:
586581
self.assertIsNone(conn.api_key) # Anymail prop

0 commit comments

Comments
 (0)