Commit 8548d557 by Will Daly

Gracefully handle credit provider keys with unicode type

parent 091dc4c3
......@@ -16,17 +16,30 @@ we receive from the credit provider.
"""
import logging
import hashlib
import hmac
from django.conf import settings
log = logging.getLogger(__name__)
def get_shared_secret_key(provider_id):
"""
Retrieve the shared secret key for a particular credit provider.
"""
return getattr(settings, "CREDIT_PROVIDER_SECRET_KEYS", {}).get(provider_id)
secret = getattr(settings, "CREDIT_PROVIDER_SECRET_KEYS", {}).get(provider_id)
if isinstance(secret, unicode):
try:
secret = str(secret)
except UnicodeEncodeError:
secret = None
log.error(u'Shared secret key for credit provider "%s" contains non-ASCII unicode.', provider_id)
return secret
def signature(params, shared_secret):
......@@ -35,6 +48,7 @@ def signature(params, shared_secret):
Arguments:
params (dict): Parameters to sign. Ignores the "signature" key if present.
shared_secret (str): The shared secret string.
Returns:
str: The 32-character signature.
......
"""
Tests for digital signatures used to validate messages to/from credit providers.
"""
from django.test import TestCase
from django.test.utils import override_settings
from openedx.core.djangoapps.credit import signature
class SignatureTest(TestCase):
"""
Tests for digital signatures.
"""
@override_settings(CREDIT_PROVIDER_SECRET_KEYS={
"asu": u'abcd1234'
})
def test_unicode_secret_key(self):
# Test a key that has type `unicode` but consists of ASCII characters
# (This can happen, for example, when loading the key from a JSON configuration file)
# When retrieving the shared secret, the type should be converted to `str`
key = signature.get_shared_secret_key("asu")
sig = signature.signature({}, key)
self.assertEqual(sig, "7d70a26b834d9881cc14466eceac8d39188fc5ef5ffad9ab281a8327c2c0d093")
@override_settings(CREDIT_PROVIDER_SECRET_KEYS={
"asu": u'\u4567'
})
def test_non_ascii_unicode_secret_key(self):
# Test a key that contains non-ASCII unicode characters
# This should return `None` and log an error; the caller
# is then responsible for logging the appropriate errors
# so we can fix the misconfiguration.
key = signature.get_shared_secret_key("asu")
self.assertIs(key, None)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment