diff --git a/addons/payment_authorize/models/payment.py b/addons/payment_authorize/models/payment.py index 73c7c044e0a..6c31e7a499e 100644 --- a/addons/payment_authorize/models/payment.py +++ b/addons/payment_authorize/models/payment.py @@ -5,6 +5,7 @@ from datetime import datetime import hashlib import hmac import logging +import string import time import urlparse @@ -54,7 +55,15 @@ class PaymentAcquirerAuthorize(models.Model): values['x_fp_timestamp'], values['x_amount'], values['x_currency_code']]) - return hmac.new(str(values['x_trans_key']), data, hashlib.md5).hexdigest() + + # [BACKWARD COMPATIBILITY] Check that the merchant did update his transaction + # key to signature key (end of MD5 support from Authorize.net) + # The signature key is now '128-character hexadecimal format', while the + # transaction key was only 16-character. + if len(values['x_trans_key']) == 128: + return hmac.new(values['x_trans_key'].decode("hex"), data, hashlib.sha512).hexdigest().upper() + else: + return hmac.new(str(values['x_trans_key']), data, hashlib.md5).hexdigest() @api.multi def authorize_form_generate_values(self, values): @@ -172,7 +181,7 @@ class TxAuthorize(models.Model): def _authorize_form_get_tx_from_data(self, data): """ Given a data dict coming from authorize, verify it and find the related transaction record. """ - reference, trans_id, fingerprint = data.get('x_invoice_num'), data.get('x_trans_id'), data.get('x_MD5_Hash') + reference, trans_id, fingerprint = data.get('x_invoice_num'), data.get('x_trans_id'), data.get('x_SHA2_Hash') or data.get('x_MD5_Hash') if not reference or not trans_id or not fingerprint: error_msg = _('Authorize: received data with missing reference (%s) or trans_id (%s) or fingerprint (%s)') % (reference, trans_id, fingerprint) _logger.info(error_msg) diff --git a/addons/payment_authorize/tests/test_authorize.py b/addons/payment_authorize/tests/test_authorize.py index 35be8a99b17..2d1d7665ce3 100644 --- a/addons/payment_authorize/tests/test_authorize.py +++ b/addons/payment_authorize/tests/test_authorize.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- -import hashlib -import hmac import time import urlparse import unittest @@ -32,15 +30,6 @@ class AuthorizeCommon(PaymentAcquirerCommon): @odoo.tests.common.post_install(True) class AuthorizeForm(AuthorizeCommon): - def _authorize_generate_hashing(self, values): - data = '^'.join([ - values['x_login'], - values['x_fp_sequence'], - values['x_fp_timestamp'], - values['x_amount'], - ]) + '^' - return hmac.new(str(values['x_trans_key']), data, hashlib.md5).hexdigest() - def test_10_Authorize_form_render(self): self.assertEqual(self.authorize.environment, 'test', 'test without test environment') @@ -84,7 +73,7 @@ class AuthorizeForm(AuthorizeCommon): 'x_ship_to_state': None, } - form_values['x_fp_hash'] = self._authorize_generate_hashing(form_values) + form_values['x_fp_hash'] = self.env['payment.acquirer']._authorize_generate_hashing(form_values) # render the button res = self.authorize.render('SO004', 320.0, self.currency_usd.id, values=self.buyer_values) # check form result @@ -108,7 +97,9 @@ class AuthorizeForm(AuthorizeCommon): # typical data posted by authorize after client has successfully paid authorize_post_data = { 'return_url': u'/shop/payment/validate', + # x_MD5_Hash will be empty starting the 28th March 2019 'x_MD5_Hash': u'7934485E1C105940BE854208D10FAB4F', + 'x_SHA2_Hash': u'7D3AC844BE8CA3F649AB885A90D22CFE35B850338EC91D1A5ADD819A85FF948A3D777334A18CDE36821DC8F2B42A6E1950C1FF96B52B60F23201483A656195FB', 'x_account_number': u'XXXX0027', 'x_address': u'Huge Street 2/543', 'x_amount': u'320.00',