summaryrefslogtreecommitdiff
path: root/addons/payment_authorize/models
diff options
context:
space:
mode:
authorDamien Bouvy <dbo@odoo.com>2019-07-08 15:47:32 +0000
committerDamien Bouvy <dbo@odoo.com>2019-07-16 05:25:09 +0000
commitf7b6d3b0b81c447e3ec4dab244594717b703686d (patch)
treec6a0e008000dd2fbc8e276627c14c303292d8cf7 /addons/payment_authorize/models
parent565cb99ec02e6ec5e8480831128a57c6e0c176c2 (diff)
[FIX] payment_authorize: md5 to sha512 compat
This commit extends the changes introduced by 88de93114 to adapt Odoo payment flows to the switch in transaction signature done by Authorize.net. The initial fix was not sufficient for flows that mixed redirection payment flows and server-to-server flows (e.g. paying a quote with a card that gets saved then using the token to pay for a subscription). The problem comes from the fact that the server-to-server API uses the API Transaction Key and API Login ID as credentials to authenticate requests; there is no need for a signature since this data is never publicly exposed on the website and a MITM is mitigated by the fact that it would need to be done between the Odoo server and the Authorize.net servers (both of which use https in a normal deployment) which is admitedly more complex than doing a MITM on a Starbucks wifi. On the other hand, the 'redirection' flow will include all transaction parameters as inputs in an html form, therefore the signature is required to ensure that the values have not been modified by a website user or a mitm. Since both flows can coexist on the same configuration, we cannot use the same field depending on the payment flow configuration - we need both fields to be stored for the provider. This commit therefore has to introduce new fields on payment.acquirer record that can store the signature key for authorize in addition to the usual authorize fields. Instead of adding a new module, this commit uses non-stored computed fields that will generate System Parameters entries for any acquirer of the 'authorize' kind when set through the interface. closes odoo/odoo#34670 Signed-off-by: Damien Bouvy (dbo) <dbo@odoo.com>
Diffstat (limited to 'addons/payment_authorize/models')
-rw-r--r--addons/payment_authorize/models/payment.py29
1 files changed, 26 insertions, 3 deletions
diff --git a/addons/payment_authorize/models/payment.py b/addons/payment_authorize/models/payment.py
index f77504d738e..0e97d630c69 100644
--- a/addons/payment_authorize/models/payment.py
+++ b/addons/payment_authorize/models/payment.py
@@ -24,6 +24,7 @@ class PaymentAcquirerAuthorize(models.Model):
provider = fields.Selection(selection_add=[('authorize', 'Authorize.Net')])
authorize_login = fields.Char(string='API Login Id', required_if_provider='authorize', groups='base.group_user')
authorize_transaction_key = fields.Char(string='API Transaction Key', required_if_provider='authorize', groups='base.group_user')
+ authorize_signature_key = fields.Char(string='API Signature Key', groups='base.group_user', compute="_compute_auth_signature_key", inverse="_inverse_auth_signature_key")
def _get_feature_support(self):
"""Get advanced feature support by provider.
@@ -41,6 +42,16 @@ class PaymentAcquirerAuthorize(models.Model):
res['tokenize'].append('authorize')
return res
+ def _compute_auth_signature_key(self):
+ ICP = self.env['ir.config_parameter'].sudo()
+ for acquirer in self.filtered(lambda a: a.provider == 'authorize'):
+ acquirer.authorize_signature_key = ICP.get_param('payment_authorize.signature_key_%s' % acquirer.id)
+
+ def _inverse_auth_signature_key(self):
+ ICP = self.env['ir.config_parameter'].sudo()
+ for acquirer in self.filtered(lambda a: a.provider == 'authorize'):
+ ICP.set_param('payment_authorize.signature_key_%s' % acquirer.id, acquirer.authorize_signature_key)
+
def _get_authorize_urls(self, environment):
""" Authorize URLs """
if environment == 'prod':
@@ -56,12 +67,24 @@ class PaymentAcquirerAuthorize(models.Model):
values['x_amount'],
values['x_currency_code']])
- # [BACKWARD COMPATIBILITY] Check that the merchant did update his transaction
- # key to signature key (end of MD5 support from Authorize.net)
+ # [BACKWARD COMPATIBILITY, 2nd edition]
# The signature key is now '128-character hexadecimal format', while the
# transaction key was only 16-character.
- if len(values['x_trans_key']) == 128:
+ # One of 2 things should have happened:
+ # 1/ the Transaction Key has been replaced with the Signature Key value (patch from March 2019)
+ # => Use that to sign, but server-to-server won't work since it uses transaction key
+ # as its credentials
+ # 2/ the Signature key is a new field (patch from July 2019)
+ # => Use that field for the signature
+
+ # FORWARD-PORT NOTE: be careful, hexadecimal decoding in python 3 is done by using bytes.fromhex(str)
+ # (P2) self.authorize_signature_key.decode("hex") ==> (P3) bytes.fromhex(self.authorize_signature_key)
+ # FORWARD-PORT NOTE NUMERO DOS: forward part to saas-12.4 but no further
+ if len(values['x_trans_key']) == 128 and not self.authorize_signature_key:
+ self.authorize_signature_key = values['x_trans_key'] # store in the correct field
return hmac.new(values['x_trans_key'].decode("hex"), data, hashlib.sha512).hexdigest().upper()
+ elif self.authorize_signature_key:
+ return hmac.new(self.authorize_signature_key.decode("hex"), data, hashlib.sha512).hexdigest().upper()
else:
return hmac.new(str(values['x_trans_key']), data, hashlib.md5).hexdigest()