Add unicode handling to the signing and verifying logic
This commit is contained in:
@@ -54,7 +54,7 @@ def processor_hash(value):
|
||||
Performs the base64(HMAC_SHA1(key, value)) used by CyberSource Hosted Order Page
|
||||
"""
|
||||
shared_secret = settings.CC_PROCESSOR['CyberSource'].get('SHARED_SECRET', '')
|
||||
hash_obj = hmac.new(shared_secret, value, sha1)
|
||||
hash_obj = hmac.new(shared_secret.encode('utf-8'), value.encode('utf-8'), sha1)
|
||||
return binascii.b2a_base64(hash_obj.digest())[:-1] # last character is a '\n', which we don't want
|
||||
|
||||
|
||||
@@ -71,10 +71,10 @@ def sign(params, signed_fields_key='orderPage_signedFields', full_sig_key='order
|
||||
params['orderPage_timestamp'] = int(time.time() * 1000)
|
||||
params['orderPage_version'] = order_page_version
|
||||
params['orderPage_serialNumber'] = serial_number
|
||||
fields = ",".join(params.keys())
|
||||
values = ",".join(["{0}={1}".format(i, params[i]) for i in params.keys()])
|
||||
fields = u",".join(params.keys())
|
||||
values = u",".join([u"{0}={1}".format(i, params[i]) for i in params.keys()])
|
||||
fields_sig = processor_hash(fields)
|
||||
values += ",signedFieldsPublicSignature=" + fields_sig
|
||||
values += u",signedFieldsPublicSignature=" + fields_sig
|
||||
params[full_sig_key] = processor_hash(values)
|
||||
params[signed_fields_key] = fields
|
||||
|
||||
@@ -90,13 +90,14 @@ def verify_signatures(params, signed_fields_key='signedFields', full_sig_key='si
|
||||
raises CCProcessorSignatureException if not verified
|
||||
"""
|
||||
signed_fields = params.get(signed_fields_key, '').split(',')
|
||||
data = ",".join(["{0}={1}".format(k, params.get(k, '')) for k in signed_fields])
|
||||
data = u",".join([u"{0}={1}".format(k, params.get(k, '')) for k in signed_fields])
|
||||
signed_fields_sig = processor_hash(params.get(signed_fields_key, ''))
|
||||
data += ",signedFieldsPublicSignature=" + signed_fields_sig
|
||||
data += u",signedFieldsPublicSignature=" + signed_fields_sig
|
||||
returned_sig = params.get(full_sig_key, '')
|
||||
if processor_hash(data) != returned_sig:
|
||||
raise CCProcessorSignatureException()
|
||||
|
||||
|
||||
def render_purchase_form_html(cart):
|
||||
"""
|
||||
Renders the HTML of the hidden POST form that must be used to initiate a purchase with CyberSource
|
||||
|
||||
@@ -58,6 +58,28 @@ class CyberSourceTests(TestCase):
|
||||
# testing for the absence of that exception. the trivial assert below does that
|
||||
self.assertEqual(1, 1)
|
||||
|
||||
def test_sign_then_verify_unicode(self):
|
||||
"""
|
||||
Similar to the test above, which loops back to the original.
|
||||
Testing to make sure we can handle unicode parameters
|
||||
"""
|
||||
params = {
|
||||
'card_accountNumber': '1234',
|
||||
'card_cardType': '001',
|
||||
'billTo_firstName': u'\u2699',
|
||||
'billTo_lastName': u"\u2603",
|
||||
'orderNumber': '1',
|
||||
'orderCurrency': 'usd',
|
||||
'decision': 'ACCEPT',
|
||||
'ccAuthReply_amount': '0.00'
|
||||
}
|
||||
|
||||
verify_signatures(sign(params), signed_fields_key='orderPage_signedFields',
|
||||
full_sig_key='orderPage_signaturePublic')
|
||||
# if the above verify_signature fails it will throw an exception, so basically we're just
|
||||
# testing for the absence of that exception. the trivial assert below does that
|
||||
self.assertEqual(1, 1)
|
||||
|
||||
def test_verify_exception(self):
|
||||
"""
|
||||
Tests that failure to verify raises the proper CCProcessorSignatureException
|
||||
@@ -162,6 +184,7 @@ class CyberSourceTests(TestCase):
|
||||
'card_accountNumber': '1234',
|
||||
'card_cardType': '001',
|
||||
'billTo_firstName': student1.first_name,
|
||||
'billTo_lastName': u"\u2603",
|
||||
'orderNumber': str(order1.id),
|
||||
'orderCurrency': 'usd',
|
||||
'decision': 'ACCEPT',
|
||||
@@ -194,6 +217,7 @@ class CyberSourceTests(TestCase):
|
||||
# finally, tests an accepted order
|
||||
self.assertTrue(payment_accepted(params)['accepted'])
|
||||
|
||||
|
||||
@patch('shoppingcart.processors.CyberSource.render_to_string', autospec=True)
|
||||
def test_render_purchase_form_html(self, render):
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user