From 565cb99ec02e6ec5e8480831128a57c6e0c176c2 Mon Sep 17 00:00:00 2001 From: "Lucas Perais (lpe)" Date: Wed, 17 Jul 2019 14:03:40 +0000 Subject: [PATCH 1/2] [FIX] l10n_be_intrastat: weight must be > 0.01 Fine tuning of 06d149a3b1c59594d776e418658e7b5db043a7d2 It appears that according to https://www.nbb.be/doc/dq/f_pdf_ex/nieuwsbriefintrastat_n28_2018_fr.pdf minimum weight is 0.01, and that anything below should be rounded to 0.01 OPW 2031682 closes odoo/odoo#34951 Signed-off-by: Lucas Perais (lpe) --- addons/l10n_be_intrastat/wizard/xml_decl.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/addons/l10n_be_intrastat/wizard/xml_decl.py b/addons/l10n_be_intrastat/wizard/xml_decl.py index d6ca134aa97..170f49e0d68 100644 --- a/addons/l10n_be_intrastat/wizard/xml_decl.py +++ b/addons/l10n_be_intrastat/wizard/xml_decl.py @@ -114,6 +114,11 @@ class XmlDeclaration(models.TransientModel): round_digits = self._get_rounding_digits() _round = partial(float_round, precision_digits=round_digits) + value, weight, supply_units = amounts + # Assuming weight cannot be negative + if weight >= 0 and weight < 0.01: + weight = 0.01 + self._set_Dim(item, 'EXSEQCODE', unicode(numlgn)) self._set_Dim(item, 'EXTRF', unicode(linekey.EXTRF)) self._set_Dim(item, 'EXCNT', unicode(linekey.EXCNT)) @@ -123,9 +128,9 @@ class XmlDeclaration(models.TransientModel): if extendedmode: self._set_Dim(item, 'EXTPC', unicode(linekey.EXTPC)) self._set_Dim(item, 'EXDELTRM', unicode(linekey.EXDELTRM)) - self._set_Dim(item, 'EXTXVAL', unicode(_round(amounts[0])).replace(".", ",")) - self._set_Dim(item, 'EXWEIGHT', unicode(_round(amounts[1])).replace(".", ",")) - self._set_Dim(item, 'EXUNITS', unicode(_round(amounts[2])).replace(".", ",")) + self._set_Dim(item, 'EXTXVAL', unicode(_round(value)).replace(".", ",")) + self._set_Dim(item, 'EXWEIGHT', unicode(_round(weight)).replace(".", ",")) + self._set_Dim(item, 'EXUNITS', unicode(_round(supply_units)).replace(".", ",")) def _get_intrastat_linekey(self, declcode, inv_line, dispatchmode, extendedmode): IntrastatRegion = self.env['l10n_be_intrastat.region'] From f7b6d3b0b81c447e3ec4dab244594717b703686d Mon Sep 17 00:00:00 2001 From: Damien Bouvy Date: Mon, 8 Jul 2019 15:47:32 +0000 Subject: [PATCH 2/2] [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) --- addons/payment_authorize/models/payment.py | 29 +++++++++++++++++-- .../payment_authorize/views/payment_views.xml | 1 + 2 files changed, 27 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() diff --git a/addons/payment_authorize/views/payment_views.xml b/addons/payment_authorize/views/payment_views.xml index 7a957e41442..b3f3ed8e535 100644 --- a/addons/payment_authorize/views/payment_views.xml +++ b/addons/payment_authorize/views/payment_views.xml @@ -9,6 +9,7 @@ + How to get paid with Authorize.Net