[IMP] core: use inert SQL based neutralization
Before this commit the neutralize system introduced in v16 was using ORM
methods in order to change appropriate records. Although flexible, this approach
could lead to call some methods with side effects while neutralizing
(eg: overloads of write).
This patch converts the neutralize system to a safer "inert" SQL based approach
by migrating the generic method _neutralize to SQL files exposed in the
data folder.
Task id: 2961687
closes odoo/odoo#102792
X-original-commit: e5dbded9bb363351feff7ca8a56c7f8a6860f492
Related: odoo/enterprise#32580
Signed-off-by: Fabien Meghazi <fme@odoo.com>
This commit is contained in:
committed by
Fabien Meghazi
parent
90ddaf871d
commit
7593c073d2
@@ -0,0 +1,5 @@
|
||||
-- disable edi connections in general, and the Italian one (l10n_it_edi_sdicoop) in particular
|
||||
INSERT INTO ir_config_parameter (key, value)
|
||||
VALUES ('account_edi_proxy_client.demo', true)
|
||||
ON CONFLICT (key) DO
|
||||
UPDATE SET value = true;
|
||||
@@ -206,13 +206,3 @@ class AccountEdiProxyClientUser(models.Model):
|
||||
)
|
||||
f = Fernet(key)
|
||||
return f.decrypt(base64.b64decode(data))
|
||||
|
||||
def _neutralize(self):
|
||||
super()._neutralize()
|
||||
self.env.flush_all()
|
||||
self.env.invalidate_all()
|
||||
self.env.cr.execute("""
|
||||
INSERT INTO ir_config_parameter(key, value)
|
||||
VALUES ('account_edi_proxy_client.demo', true)
|
||||
ON CONFLICT (key) DO UPDATE SET value = true
|
||||
""")
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
-- disable oauth providers
|
||||
UPDATE auth_oauth_provider
|
||||
SET enabled = false;
|
||||
@@ -20,9 +20,3 @@ class AuthOAuthProvider(models.Model):
|
||||
css_class = fields.Char(string='CSS class', default='fa fa-fw fa-sign-in text-primary')
|
||||
body = fields.Char(required=True, string="Login button label", help='Link text in Login Dialog', translate=True)
|
||||
sequence = fields.Integer(default=10)
|
||||
|
||||
def _neutralize(self):
|
||||
super()._neutralize()
|
||||
self.flush_model(['enabled'])
|
||||
self.env.cr.execute("UPDATE auth_oauth_provider SET enabled = false")
|
||||
self.invalidate_model(['enabled'])
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
-- disable delivery carriers
|
||||
UPDATE delivery_carrier
|
||||
SET prod_environment = false,
|
||||
active = false;
|
||||
@@ -390,16 +390,3 @@ class DeliveryCarrier(models.Model):
|
||||
|
||||
def _product_price_to_company_currency(self, quantity, product, company):
|
||||
return company.currency_id._convert(quantity * product.standard_price, product.currency_id, company, fields.Date.today())
|
||||
|
||||
# -------------------------- #
|
||||
# neutralize #
|
||||
# -------------------------- #
|
||||
|
||||
def _neutralize(self):
|
||||
super()._neutralize()
|
||||
self.flush_model()
|
||||
self.invalidate_model()
|
||||
self.env.cr.execute("""
|
||||
UPDATE delivery_carrier
|
||||
SET prod_environment = false, active = false
|
||||
""")
|
||||
|
||||
@@ -76,9 +76,3 @@ class TestPacking(TestPackingCommon):
|
||||
# default weight was set.
|
||||
pack_wiz = self.env['choose.delivery.package'].with_context(pack_action_ctx).create({})
|
||||
self.assertEqual(pack_wiz.shipping_weight, 13.5)
|
||||
|
||||
def test_delivery_carrier_neutralize(self):
|
||||
""" ensure that devlivery carriers can be nautralized """
|
||||
self.assertTrue(self.test_carrier.active)
|
||||
self.env['delivery.carrier']._neutralize()
|
||||
self.assertFalse(self.test_carrier.active, "Delivery Carrier was not neutralized")
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
INSERT INTO ir_config_parameter (key, value)
|
||||
VALUES ('iap.endpoint', 'https://iap-sandbox.odoo.com')
|
||||
ON CONFLICT (key) DO
|
||||
UPDATE SET value = 'https://iap-sandbox.odoo.com';
|
||||
@@ -130,26 +130,3 @@ class IapAccount(models.Model):
|
||||
credit = -1
|
||||
|
||||
return credit
|
||||
|
||||
def _neutralize(self):
|
||||
super()._neutralize()
|
||||
self.env.flush_all()
|
||||
self.env.invalidate_all()
|
||||
|
||||
self.env.cr.execute("""
|
||||
INSERT INTO ir_config_parameter(key, value)
|
||||
VALUES ('iap.endpoint', 'https://iap-sandbox.odoo.com')
|
||||
ON CONFLICT (key) DO UPDATE SET value = 'https://iap-sandbox.odoo.com'
|
||||
""")
|
||||
|
||||
iap_service_endpoints = self._get_iap_config_parameters()
|
||||
if iap_service_endpoints:
|
||||
self.env.cr.execute("""
|
||||
UPDATE ir_config_parameter
|
||||
SET value = 'https://iap-services-test.odoo.com'
|
||||
WHERE key IN %s
|
||||
""", [tuple(iap_service_endpoints)])
|
||||
|
||||
def _get_iap_config_parameters(self):
|
||||
"""override this method to extend the list with each parameter"""
|
||||
return []
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
-- disable l10n_eg_edi_eta integration
|
||||
UPDATE res_company
|
||||
SET l10n_eg_production_env = false,
|
||||
l10n_eg_client_secret = 'dummy';
|
||||
@@ -14,17 +14,3 @@ class ResCompany(models.Model):
|
||||
l10n_eg_invoicing_threshold = fields.Float('Invoicing Threshold', default=0.0,
|
||||
help="Threshold at which you are required to give the VAT number "
|
||||
"of the customer. ")
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# neutralize
|
||||
# ------------------------------------------------------------
|
||||
|
||||
def _neutralize(self):
|
||||
super()._neutralize()
|
||||
self.flush_model()
|
||||
self.invalidate_model()
|
||||
self.env.cr.execute("""
|
||||
UPDATE res_company
|
||||
SET l10n_eg_production_env = False,
|
||||
l10n_eg_client_secret = 'dummy'
|
||||
""")
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
-- disable_l10n_es_edi_integration
|
||||
UPDATE res_company
|
||||
SET l10n_es_edi_test_env = true;
|
||||
@@ -43,9 +43,3 @@ class ResCompany(models.Model):
|
||||
)
|
||||
else:
|
||||
company.l10n_es_edi_certificate_id = False
|
||||
|
||||
def _neutralize(self):
|
||||
super()._neutralize()
|
||||
self.flush_model()
|
||||
self.invalidate_model()
|
||||
self.env.cr.execute("UPDATE res_company SET l10n_es_edi_test_env = true")
|
||||
|
||||
@@ -2,4 +2,3 @@
|
||||
|
||||
from . import test_edi_xml
|
||||
from . import test_edi_web_services
|
||||
from . import test_neutralize
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
from odoo.tests.common import tagged, TransactionCase
|
||||
|
||||
|
||||
@tagged('post_install_l10n', 'post_install', '-at_install')
|
||||
class TestL10nEsEdiNeutralize(TransactionCase):
|
||||
|
||||
def test_l10n_es_edi_neutralize(self):
|
||||
ar_company = self.env['res.company'].create({
|
||||
'name': 'Test ES Company',
|
||||
'l10n_es_edi_test_env': False,
|
||||
})
|
||||
|
||||
self.env['res.company']._neutralize()
|
||||
self.assertEqual(ar_company.l10n_es_edi_test_env, True)
|
||||
@@ -0,0 +1,7 @@
|
||||
-- disable l10n_in_edi integration
|
||||
UPDATE res_company
|
||||
SET l10n_in_edi_production_env = false,
|
||||
l10n_in_edi_username = NULL,
|
||||
l10n_in_edi_password = NULL,
|
||||
l10n_in_edi_token = NULL,
|
||||
l10n_in_edi_token_validity = NULL;
|
||||
@@ -22,15 +22,3 @@ class ResCompany(models.Model):
|
||||
if self.l10n_in_edi_token and self.l10n_in_edi_token_validity > fields.Datetime.now():
|
||||
return True
|
||||
return False
|
||||
|
||||
def _neutralize(self):
|
||||
super()._neutralize()
|
||||
self.flush_model()
|
||||
self.invalidate_model()
|
||||
self.env.cr.execute("""UPDATE res_company SET
|
||||
l10n_in_edi_production_env = false,
|
||||
l10n_in_edi_username = Null,
|
||||
l10n_in_edi_password = Null,
|
||||
l10n_in_edi_token = Null,
|
||||
l10n_in_edi_token_validity = Null
|
||||
""")
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
-- deactivate mail template
|
||||
UPDATE mail_template
|
||||
SET mail_server_id = NULL;
|
||||
@@ -401,13 +401,3 @@ class MailTemplate(models.Model):
|
||||
if force_send:
|
||||
mail.send(raise_exception=raise_exception)
|
||||
return mail.id # TDE CLEANME: return mail + api.returns ?
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# neutralize
|
||||
# ------------------------------------------------------------
|
||||
|
||||
def _neutralize(self):
|
||||
super()._neutralize()
|
||||
self.flush_model()
|
||||
self.invalidate_model()
|
||||
self.env.cr.execute("UPDATE mail_template SET mail_server_id=NULL")
|
||||
|
||||
@@ -450,19 +450,3 @@ class TestMailRender(common.MailCommon):
|
||||
self.assertEqual(result, '''<div style="display:none;font-size:1px;height:0px;width:0px;opacity:0;">
|
||||
foo<t t-out=""false" if 1 > 2 else "true""/>bar
|
||||
</div>body''')
|
||||
|
||||
def test_mail_template_neutralize(self):
|
||||
""" ensure mail templates can be neutralized """
|
||||
fake_mail_server = self.env['ir.mail_server'].create({
|
||||
'name': "fake test email server",
|
||||
'smtp_host': "mail.example.com",
|
||||
'smtp_port': 15626,
|
||||
})
|
||||
self.test_template.mail_server_id = fake_mail_server
|
||||
self.env['mail.template']._neutralize()
|
||||
self.assertFalse(self.test_template.mail_server_id)
|
||||
|
||||
# bonus test mail server neutralize too
|
||||
self.assertTrue(fake_mail_server.active)
|
||||
self.env['ir.mail_server']._neutralize()
|
||||
self.assertFalse(fake_mail_server.active)
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
INSERT INTO ir_config_parameter (key, value)
|
||||
VALUES ('iap.partner_autocomplete.endpoint', 'https://iap-services-test.odoo.com')
|
||||
ON CONFLICT (key) DO
|
||||
UPDATE SET value = 'https://iap-services-test.odoo.com';
|
||||
@@ -1,7 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import iap_account
|
||||
from . import iap_autocomplete_api
|
||||
from . import ir_http
|
||||
from . import res_partner
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import models
|
||||
|
||||
|
||||
class IapAccount(models.Model):
|
||||
_inherit = 'iap.account'
|
||||
|
||||
def _get_iap_config_parameters(self):
|
||||
return super()._get_iap_config_parameters() + ['iap.partner_autocomplete.endpoint']
|
||||
@@ -1,5 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import test_neutralize
|
||||
from . import test_res_company
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.tests.common import TransactionCase
|
||||
|
||||
|
||||
class TestPartnerAutocompleteNeutralize(TransactionCase):
|
||||
|
||||
def test_partner_autocomplete_neutralize(self):
|
||||
iap_key = 'iap.partner_autocomplete.endpoint'
|
||||
self.env['ir.config_parameter'].create({
|
||||
'key': iap_key,
|
||||
'value': 'fake test iap partner autocomplete endpoint'
|
||||
})
|
||||
|
||||
self.env['iap.account']._neutralize()
|
||||
self.assertEqual(self.env['ir.config_parameter'].get_param(iap_key), 'https://iap-services-test.odoo.com')
|
||||
@@ -0,0 +1,4 @@
|
||||
-- disable generic payment provider
|
||||
UPDATE payment_provider
|
||||
SET state = 'disabled'
|
||||
WHERE state NOT IN ('test', 'disabled');
|
||||
@@ -593,31 +593,3 @@ class PaymentProvider(models.Model):
|
||||
'code': 'none',
|
||||
'state': 'disabled',
|
||||
})
|
||||
|
||||
def _neutralize(self):
|
||||
super()._neutralize()
|
||||
self.flush_model()
|
||||
self.invalidate_model()
|
||||
self.env.cr.execute("""
|
||||
UPDATE payment_provider SET state = 'disabled'
|
||||
WHERE state NOT IN ('test', 'disabled')
|
||||
""")
|
||||
|
||||
def _neutralize_fields(self, provider_code, field_names):
|
||||
""" Helper to neutralize API keys for the given provider.
|
||||
|
||||
:param str provider_code: The code of the provider whose fields to neutralize.
|
||||
:param list field_names: The names of the fields to neutralize.
|
||||
:return: None
|
||||
"""
|
||||
self.flush_model()
|
||||
self.invalidate_model()
|
||||
query = sql.SQL("""
|
||||
UPDATE payment_provider
|
||||
SET ({fields}) = ROW({vals})
|
||||
WHERE code = %s
|
||||
""").format(
|
||||
fields=sql.SQL(','.join(field_names)),
|
||||
vals=sql.SQL(', '.join(['NULL'] * len(field_names))),
|
||||
)
|
||||
self.env.cr.execute(query, (provider_code,))
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
-- disable adyen payment provider
|
||||
UPDATE payment_provider
|
||||
SET adyen_merchant_account = NULL,
|
||||
adyen_api_key = NULL,
|
||||
adyen_hmac_key = NULL;
|
||||
@@ -139,11 +139,3 @@ class PaymentProvider(models.Model):
|
||||
:rtype: str
|
||||
"""
|
||||
return f'ODOO_PARTNER_{partner_id}'
|
||||
|
||||
def _neutralize(self):
|
||||
super()._neutralize()
|
||||
self._neutralize_fields('adyen', [
|
||||
'adyen_merchant_account',
|
||||
'adyen_api_key',
|
||||
'adyen_hmac_key',
|
||||
])
|
||||
|
||||
@@ -334,10 +334,3 @@ class AdyenTest(AdyenCommon, PaymentHttpCommon):
|
||||
payload = dict(self.webhook_notification_payload, additionalData={'hmacSignature': 'dummy'})
|
||||
tx = self._create_transaction('direct')
|
||||
self.assertRaises(Forbidden, AdyenController._verify_notification_signature, payload, tx)
|
||||
|
||||
def test_adyen_neutralize(self):
|
||||
self.env['payment.provider']._neutralize()
|
||||
|
||||
self.assertEqual(self.provider.adyen_merchant_account, False)
|
||||
self.assertEqual(self.provider.adyen_api_key, False)
|
||||
self.assertEqual(self.provider.adyen_hmac_key, False)
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
-- disable adyen payment provider
|
||||
UPDATE payment_provider
|
||||
SET alipay_merchant_partner_id = NULL,
|
||||
alipay_md5_signature_key = NULL,
|
||||
alipay_seller_email = NULL;
|
||||
@@ -68,11 +68,3 @@ class PaymentProvider(models.Model):
|
||||
return 'https://mapi.alipay.com/gateway.do'
|
||||
else: # test environment
|
||||
return 'https://openapi.alipaydev.com/gateway.do'
|
||||
|
||||
def _neutralize(self):
|
||||
super()._neutralize()
|
||||
self._neutralize_fields('alipay', [
|
||||
'alipay_merchant_partner_id',
|
||||
'alipay_md5_signature_key',
|
||||
'alipay_seller_email',
|
||||
])
|
||||
|
||||
@@ -208,10 +208,3 @@ class AlipayTest(AlipayCommon, PaymentHttpCommon):
|
||||
tx = self._create_transaction('redirect')
|
||||
payload = dict(self.notification_data, sign='dummy')
|
||||
self.assertRaises(Forbidden, AlipayController._verify_notification_signature, payload, tx)
|
||||
|
||||
def test_alipay_neutralize(self):
|
||||
self.env['payment.provider']._neutralize()
|
||||
|
||||
self.assertEqual(self.provider.alipay_merchant_partner_id, False)
|
||||
self.assertEqual(self.provider.alipay_md5_signature_key, False)
|
||||
self.assertEqual(self.provider.alipay_seller_email, False)
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
-- disable aps payment provider
|
||||
UPDATE payment_provider
|
||||
SET aps_merchant_identifier = NULL,
|
||||
aps_access_code = NULL,
|
||||
aps_sha_request = NULL,
|
||||
aps_sha_response = NULL;
|
||||
@@ -58,12 +58,3 @@ class PaymentProvider(models.Model):
|
||||
key = self.aps_sha_response if incoming else self.aps_sha_request
|
||||
signing_string = ''.join([key, sign_data, key])
|
||||
return hashlib.sha256(signing_string.encode()).hexdigest()
|
||||
|
||||
def _neutralize(self):
|
||||
super()._neutralize()
|
||||
self._neutralize_fields('aps', [
|
||||
'aps_merchant_identifier',
|
||||
'aps_access_code',
|
||||
'aps_sha_request',
|
||||
'aps_sha_response',
|
||||
])
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import common
|
||||
from . import test_payment_provider
|
||||
from . import test_payment_transaction
|
||||
from . import test_processing_flows
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.tests import tagged
|
||||
|
||||
from odoo.addons.payment_aps.tests.common import APSCommon
|
||||
|
||||
|
||||
@tagged('post_install', '-at_install')
|
||||
class TestPaymentProvider(APSCommon):
|
||||
|
||||
def test_neutralize(self):
|
||||
self.env['payment.provider']._neutralize()
|
||||
self.assertEqual(self.provider.aps_merchant_identifier, False)
|
||||
self.assertEqual(self.provider.aps_access_code, False)
|
||||
self.assertEqual(self.provider.aps_sha_request, False)
|
||||
self.assertEqual(self.provider.aps_sha_response, False)
|
||||
@@ -0,0 +1,6 @@
|
||||
-- disable asiapay payment provider
|
||||
UPDATE payment_provider
|
||||
SET asiapay_merchant_id = NULL,
|
||||
asiapay_currency_id = NULL,
|
||||
asiapay_secure_hash_secret = NULL,
|
||||
asiapay_secure_hash_function = NULL;
|
||||
@@ -85,12 +85,3 @@ class PaymentProvider(models.Model):
|
||||
shasign = hashnew(self.asiapay_secure_hash_function)
|
||||
shasign.update(signing_string.encode())
|
||||
return shasign.hexdigest()
|
||||
|
||||
def _neutralize(self):
|
||||
super()._neutralize()
|
||||
self._neutralize_fields('asiapay', [
|
||||
'asiapay_merchant_id',
|
||||
'asiapay_currency_id',
|
||||
'asiapay_secure_hash_secret',
|
||||
'asiapay_secure_hash_function',
|
||||
])
|
||||
|
||||
@@ -37,11 +37,3 @@ class TestPaymentProvider(AsiaPayCommon):
|
||||
self.webhook_notification_data, incoming=True
|
||||
)
|
||||
self.assertEqual(calculated_signature, '3e5bf55d9a23969130a6686db7aa4f0230956d0a')
|
||||
|
||||
def test_neutralize(self):
|
||||
""" Test that the sensitive fields of the provider are correctly neutralized. """
|
||||
self.env['payment.provider']._neutralize()
|
||||
self.assertFalse(self.provider.asiapay_merchant_id)
|
||||
self.assertFalse(self.provider.asiapay_currency_id)
|
||||
self.assertFalse(self.provider.asiapay_secure_hash_secret)
|
||||
self.assertFalse(self.provider.asiapay_secure_hash_function)
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
-- disable authorize payment provider
|
||||
UPDATE payment_provider
|
||||
SET authorize_login = NULL,
|
||||
authorize_transaction_key = NULL,
|
||||
authorize_signature_key = NULL,
|
||||
authorize_client_key = NULL;
|
||||
@@ -145,12 +145,3 @@ class PaymentProvider(models.Model):
|
||||
return res
|
||||
|
||||
return self.authorize_currency_id
|
||||
|
||||
def _neutralize(self):
|
||||
super()._neutralize()
|
||||
self._neutralize_fields('authorize', [
|
||||
'authorize_login',
|
||||
'authorize_transaction_key',
|
||||
'authorize_signature_key',
|
||||
'authorize_client_key',
|
||||
])
|
||||
|
||||
@@ -46,11 +46,3 @@ class AuthorizeTest(AuthorizeCommon):
|
||||
self.assertEqual(self.authorize.authorize_currency_id, self.currency_usd)
|
||||
self.assertEqual(self.authorize._get_validation_amount(), 0.01)
|
||||
self.assertEqual(self.authorize._get_validation_currency(), self.currency_usd)
|
||||
|
||||
def test_authorize_neutralize(self):
|
||||
self.env['payment.provider']._neutralize()
|
||||
|
||||
self.assertEqual(self.provider.authorize_login, False)
|
||||
self.assertEqual(self.provider.authorize_transaction_key, False)
|
||||
self.assertEqual(self.provider.authorize_signature_key, False)
|
||||
self.assertEqual(self.provider.authorize_client_key, False)
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
-- disable buckaroo payment provider
|
||||
UPDATE payment_provider
|
||||
SET buckaroo_website_key = NULL,
|
||||
buckaroo_secret_key = NULL;
|
||||
@@ -63,7 +63,3 @@ class PaymentProvider(models.Model):
|
||||
sign_string += self.buckaroo_secret_key
|
||||
# Calculate the SHA-1 hash over the signing string
|
||||
return sha1(sign_string.encode('utf-8')).hexdigest()
|
||||
|
||||
def _neutralize(self):
|
||||
super()._neutralize()
|
||||
self._neutralize_fields('buckaroo', ['buckaroo_website_key', 'buckaroo_secret_key'])
|
||||
|
||||
@@ -140,9 +140,3 @@ class BuckarooTest(BuckarooCommon, PaymentHttpCommon):
|
||||
'937cca8f486b75e93df1e9811a5ebf43357fc3f2',
|
||||
msg="The signing string items should be ordered based on a lower-case copy of the keys",
|
||||
)
|
||||
|
||||
def test_buckaroo_neutralize(self):
|
||||
self.env['payment.provider']._neutralize()
|
||||
|
||||
self.assertEqual(self.provider.buckaroo_website_key, False)
|
||||
self.assertEqual(self.provider.buckaroo_secret_key, False)
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
-- disable flutterwave payment provider
|
||||
UPDATE payment_provider
|
||||
SET flutterwave_public_key = NULL,
|
||||
flutterwave_secret_key = NULL,
|
||||
flutterwave_webhook_secret = NULL;
|
||||
@@ -99,11 +99,3 @@ class PaymentProvider(models.Model):
|
||||
"Flutterwave: " + _("Could not establish the connection to the API.")
|
||||
)
|
||||
return response.json()
|
||||
|
||||
def _neutralize(self):
|
||||
super()._neutralize()
|
||||
self._neutralize_fields('flutterwave', [
|
||||
'flutterwave_public_key',
|
||||
'flutterwave_secret_key',
|
||||
'flutterwave_webhook_secret',
|
||||
])
|
||||
|
||||
@@ -19,9 +19,3 @@ class TestPaymentProvider(FlutterwaveCommon):
|
||||
self.company_id, self.partner.id, 0., is_validation=True
|
||||
)
|
||||
self.assertNotIn(self.flutterwave, compatible_providers)
|
||||
|
||||
def test_neutralize(self):
|
||||
self.env['payment.provider']._neutralize()
|
||||
self.assertEqual(self.provider.flutterwave_public_key, False)
|
||||
self.assertEqual(self.provider.flutterwave_secret_key, False)
|
||||
self.assertEqual(self.provider.flutterwave_webhook_secret, False)
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
-- disable mercado_pago payment provider
|
||||
UPDATE payment_provider
|
||||
SET mercado_pago_access_token = NULL;
|
||||
@@ -80,10 +80,3 @@ class Paymentprovider(models.Model):
|
||||
"Mercado Pago: " + _("Could not establish the connection to the API.")
|
||||
)
|
||||
return response.json()
|
||||
|
||||
def _neutralize(self):
|
||||
super()._neutralize()
|
||||
|
||||
self._neutralize_fields('mercado_pago', [
|
||||
'mercado_pago_access_token',
|
||||
])
|
||||
|
||||
@@ -15,8 +15,3 @@ class TestPaymentProvider(MercadoPagoCommon):
|
||||
self.company_id, self.partner.id, self.amount, currency_id=self.env.ref('base.AFN').id
|
||||
)
|
||||
self.assertNotIn(self.provider, compatible_providers)
|
||||
|
||||
def test_neutralize(self):
|
||||
""" Test that the sensitive fields of the provider are correctly neutralized. """
|
||||
self.env['payment.provider']._neutralize()
|
||||
self.assertFalse(self.provider.mercado_pago_access_token)
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
-- disable ogone payment provider
|
||||
UPDATE payment_provider
|
||||
SET ogone_pspid = NULL,
|
||||
ogone_userid = NULL,
|
||||
ogone_password = NULL,
|
||||
ogone_shakey_in = NULL,
|
||||
ogone_shakey_out = NULL;
|
||||
@@ -131,13 +131,3 @@ class PaymentProvider(models.Model):
|
||||
_logger.exception("invalid API request at %s with data %s", url, payload)
|
||||
raise ValidationError("Ogone: " + _("The communication with the API failed."))
|
||||
return response.content
|
||||
|
||||
def _neutralize(self):
|
||||
super()._neutralize()
|
||||
self._neutralize_fields('ogone', [
|
||||
'ogone_pspid',
|
||||
'ogone_userid',
|
||||
'ogone_password',
|
||||
'ogone_shakey_in',
|
||||
'ogone_shakey_out',
|
||||
])
|
||||
|
||||
@@ -164,12 +164,3 @@ class OgoneTest(OgoneCommon, PaymentHttpCommon):
|
||||
'dummy',
|
||||
tx,
|
||||
)
|
||||
|
||||
def test_ogone_neutralize(self):
|
||||
self.env['payment.provider']._neutralize()
|
||||
|
||||
self.assertEqual(self.provider.ogone_pspid, False)
|
||||
self.assertEqual(self.provider.ogone_userid, False)
|
||||
self.assertEqual(self.provider.ogone_password, False)
|
||||
self.assertEqual(self.provider.ogone_shakey_in, False)
|
||||
self.assertEqual(self.provider.ogone_shakey_out, False)
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
-- disable paypal payment provider
|
||||
UPDATE payment_provider
|
||||
SET paypal_email_account = NULL,
|
||||
paypal_seller_account = NULL,
|
||||
paypal_pdt_token = NULL;
|
||||
@@ -77,11 +77,3 @@ class PaymentProvider(models.Model):
|
||||
'author_id': self.create_uid.partner_id.id,
|
||||
}
|
||||
self.env['mail.mail'].sudo().create(mail_values).send()
|
||||
|
||||
def _neutralize(self):
|
||||
super()._neutralize()
|
||||
self._neutralize_fields('paypal', [
|
||||
'paypal_email_account',
|
||||
'paypal_seller_account',
|
||||
'paypal_pdt_token',
|
||||
])
|
||||
|
||||
@@ -154,10 +154,3 @@ class PaypalTest(PaypalCommon, PaymentHttpCommon):
|
||||
):
|
||||
self._make_http_post_request(url, data=self.notification_data)
|
||||
self.assertEqual(origin_check_mock.call_count, 1)
|
||||
|
||||
def test_paypal_neutralize(self):
|
||||
self.env['payment.provider']._neutralize()
|
||||
|
||||
self.assertEqual(self.provider.paypal_email_account, False)
|
||||
self.assertEqual(self.provider.paypal_seller_account, False)
|
||||
self.assertEqual(self.provider.paypal_pdt_token, False)
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
-- disable payulatam payment provider
|
||||
UPDATE payment_provider
|
||||
SET payulatam_merchant_id = NULL,
|
||||
payulatam_account_id = NULL,
|
||||
payulatam_api_key = NULL;
|
||||
@@ -68,11 +68,3 @@ class PaymentProvider(models.Model):
|
||||
values['currency'],
|
||||
])
|
||||
return md5(data_string.encode('utf-8')).hexdigest()
|
||||
|
||||
def _neutralize(self):
|
||||
super()._neutralize()
|
||||
self._neutralize_fields('payulatam', [
|
||||
'payulatam_merchant_id',
|
||||
'payulatam_account_id',
|
||||
'payulatam_api_key',
|
||||
])
|
||||
|
||||
@@ -211,10 +211,3 @@ class PayULatamTest(PayULatamCommon, PaymentHttpCommon):
|
||||
self.assertRaises(
|
||||
Forbidden, PayuLatamController._verify_notification_signature, payload, tx
|
||||
)
|
||||
|
||||
def test_payulatam_neutralize(self):
|
||||
self.env['payment.provider']._neutralize()
|
||||
|
||||
self.assertEqual(self.provider.payulatam_merchant_id, False)
|
||||
self.assertEqual(self.provider.payulatam_account_id, False)
|
||||
self.assertEqual(self.provider.payulatam_api_key, False)
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
-- disable payumoney payment provider
|
||||
UPDATE payment_provider
|
||||
SET payumoney_merchant_key = NULL,
|
||||
payumoney_merchant_salt = NULL;
|
||||
@@ -49,7 +49,3 @@ class PaymentProvider(models.Model):
|
||||
keys = 'key|txnid|amount|productinfo|firstname|email|udf1|udf2|udf3|udf4|udf5||||||salt'
|
||||
sign = '|'.join(f'{sign_values.get(k) or ""}' for k in keys.split('|'))
|
||||
return hashlib.sha512(sign.encode('utf-8')).hexdigest()
|
||||
|
||||
def _neutralize(self):
|
||||
super()._neutralize()
|
||||
self._neutralize_fields('payumoney', ['payumoney_merchant_key', 'payumoney_merchant_salt'])
|
||||
|
||||
@@ -81,9 +81,3 @@ class PayUMoneyTest(PayumoneyCommon, PaymentHttpCommon):
|
||||
self.assertRaises(
|
||||
Forbidden, PayUMoneyController._verify_notification_signature, payload, tx
|
||||
)
|
||||
|
||||
def test_payumoney_neutralize(self):
|
||||
self.env['payment.provider']._neutralize()
|
||||
|
||||
self.assertEqual(self.provider.payumoney_merchant_key, False)
|
||||
self.assertEqual(self.provider.payumoney_merchant_salt, False)
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
-- disable razorpay payment provider
|
||||
UPDATE payment_provider
|
||||
SET razorpay_key_id = NULL,
|
||||
razorpay_key_secret = NULL,
|
||||
razorpay_webhook_secret = NULL;
|
||||
@@ -121,11 +121,3 @@ class PaymentProvider(models.Model):
|
||||
else: # Notification data.
|
||||
secret = self.razorpay_webhook_secret
|
||||
return hmac.new(secret.encode(), msg=data, digestmod=hashlib.sha256).hexdigest()
|
||||
|
||||
def _neutralize(self):
|
||||
super()._neutralize()
|
||||
self._neutralize_fields('razorpay', [
|
||||
'razorpay_key_id',
|
||||
'razorpay_key_secret',
|
||||
'razorpay_webhook_secret',
|
||||
])
|
||||
|
||||
@@ -24,10 +24,3 @@ class TestPaymentProvider(RazorpayCommon):
|
||||
self.assertEqual(
|
||||
calculated_signature, '437b72e4e87362a39951b44487cf698410b074afdbed19ec44fffd32d2f863f3'
|
||||
)
|
||||
|
||||
def test_neutralize(self):
|
||||
""" Test that the sensitive fields of the provider are correctly neutralized. """
|
||||
self.env['payment.provider']._neutralize()
|
||||
self.assertFalse(self.provider.razorpay_key_id)
|
||||
self.assertFalse(self.provider.razorpay_key_secret)
|
||||
self.assertFalse(self.provider.razorpay_webhook_secret)
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
-- disable sips payment provider
|
||||
UPDATE payment_provider
|
||||
SET sips_merchant_id = NULL,
|
||||
sips_secret = NULL;
|
||||
@@ -54,7 +54,3 @@ class PaymentProvider(models.Model):
|
||||
key = self.sips_secret
|
||||
shasign = sha256((data + key).encode('utf-8'))
|
||||
return shasign.hexdigest()
|
||||
|
||||
def _neutralize(self):
|
||||
super()._neutralize()
|
||||
self._neutralize_fields('sips', ['sips_merchant_id', 'sips_secret'])
|
||||
|
||||
@@ -138,9 +138,3 @@ class SipsTest(SipsCommon, PaymentHttpCommon):
|
||||
tx = self._create_transaction('redirect')
|
||||
payload = dict(self.notification_data, Seal='dummy')
|
||||
self.assertRaises(Forbidden, SipsController._verify_notification_signature, payload, tx)
|
||||
|
||||
def test_sips_neutralize(self):
|
||||
self.env['payment.provider']._neutralize()
|
||||
|
||||
self.assertEqual(self.provider.sips_merchant_id, False)
|
||||
self.assertEqual(self.provider.sips_secret, False)
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
-- disable stripe payment provider
|
||||
UPDATE payment_provider
|
||||
SET stripe_secret_key = NULL,
|
||||
stripe_publishable_key = NULL,
|
||||
stripe_webhook_secret = NULL;
|
||||
@@ -264,14 +264,6 @@ class PaymentProvider(models.Model):
|
||||
"""
|
||||
return {}
|
||||
|
||||
def _neutralize(self):
|
||||
super()._neutralize()
|
||||
self._neutralize_fields('stripe', [
|
||||
'stripe_secret_key',
|
||||
'stripe_publishable_key',
|
||||
'stripe_webhook_secret',
|
||||
])
|
||||
|
||||
# === BUSINESS METHODS - STRIPE CONNECT ONBOARDING === #
|
||||
|
||||
def _stripe_fetch_or_create_connected_account(self):
|
||||
|
||||
@@ -114,13 +114,6 @@ class StripeTest(StripeCommon, PaymentHttpCommon):
|
||||
self._make_json_request(url, data=self.notification_data)
|
||||
self.assertEqual(signature_check_mock.call_count, 1)
|
||||
|
||||
def test_stripe_neutralize(self):
|
||||
self.env['payment.provider']._neutralize()
|
||||
|
||||
self.assertEqual(self.provider.stripe_secret_key, False)
|
||||
self.assertEqual(self.provider.stripe_publishable_key, False)
|
||||
self.assertEqual(self.provider.stripe_webhook_secret, False)
|
||||
|
||||
def test_onboarding_action_redirect_to_url(self):
|
||||
""" Test that the action generate and return an URL when the provider is disabled. """
|
||||
with patch.object(
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
-- disable Adyen Payement POS integration
|
||||
UPDATE pos_payment_method
|
||||
SET adyen_test_mode = true;
|
||||
@@ -0,0 +1,4 @@
|
||||
INSERT INTO ir_config_parameter (key, value)
|
||||
VALUES ('sms.endpoint', 'https://iap-services-test.odoo.com')
|
||||
ON CONFLICT (key) DO
|
||||
UPDATE SET value = 'https://iap-services-test.odoo.com';
|
||||
@@ -1,7 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import iap_account
|
||||
from . import ir_actions_server
|
||||
from . import ir_model
|
||||
from . import mail_followers
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import models
|
||||
|
||||
|
||||
class IapAccount(models.Model):
|
||||
_inherit = 'iap.account'
|
||||
|
||||
def _get_iap_config_parameters(self):
|
||||
return super()._get_iap_config_parameters() + ['sms.endpoint']
|
||||
@@ -2,5 +2,4 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import common
|
||||
from . import test_neutralize
|
||||
from . import test_sms_template
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.tests.common import TransactionCase
|
||||
|
||||
|
||||
class TestSmsNeutralize(TransactionCase):
|
||||
|
||||
def test_sms_neutralize(self):
|
||||
sms_key = 'sms.endpoint'
|
||||
self.env['ir.config_parameter'].create({
|
||||
'key': sms_key,
|
||||
'value': 'fake test sms endpoint'
|
||||
})
|
||||
|
||||
self.env['iap.account']._neutralize()
|
||||
self.assertEqual(self.env['ir.config_parameter'].get_param(sms_key), 'https://iap-services-test.odoo.com')
|
||||
@@ -0,0 +1,4 @@
|
||||
INSERT INTO ir_config_parameter (key, value)
|
||||
VALUES ('snailmail.endpoint', 'https://iap-services-test.odoo.com')
|
||||
ON CONFLICT (key) DO
|
||||
UPDATE SET value = 'https://iap-services-test.odoo.com';
|
||||
@@ -1,6 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from . import iap_account
|
||||
from . import ir_actions_report
|
||||
from . import mail_message
|
||||
from . import mail_notification
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import models
|
||||
|
||||
|
||||
class IapAccount(models.Model):
|
||||
_inherit = 'iap.account'
|
||||
|
||||
def _get_iap_config_parameters(self):
|
||||
return super()._get_iap_config_parameters() + ['snailmail.endpoint']
|
||||
@@ -1,4 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import test_neutralize
|
||||
@@ -1,17 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.tests.common import TransactionCase
|
||||
|
||||
|
||||
class TestSnailMailNeutralize(TransactionCase):
|
||||
|
||||
def test_snailmail_neutralize(self):
|
||||
key = 'snailmail.endpoint'
|
||||
self.env['ir.config_parameter'].create({
|
||||
'key': key,
|
||||
'value': 'fake test snailmail endpoint'
|
||||
})
|
||||
|
||||
self.env['iap.account']._neutralize()
|
||||
self.assertEqual(self.env['ir.config_parameter'].get_param(key), 'https://iap-services-test.odoo.com')
|
||||
@@ -20,6 +20,7 @@ This module provides the core of the Odoo Web Client.
|
||||
'views/base_document_layout_views.xml',
|
||||
'views/speedscope_template.xml',
|
||||
'views/lazy_assets.xml',
|
||||
'views/neutralize_views.xml',
|
||||
'data/ir_attachment.xml',
|
||||
'data/report_layout.xml',
|
||||
],
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
-- activate neutralization watermarks
|
||||
UPDATE ir_ui_view
|
||||
SET active = true
|
||||
WHERE key = 'web.neutralize_banner';
|
||||
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<template id="web.neutralize_banner" name="Neutralize Banner" inherit_id="web.layout" active="False">
|
||||
<xpath expr="//body" position="inside">
|
||||
<div>
|
||||
<span id="oe_neutralize_banner" t-attf-style="
|
||||
text-align: center;
|
||||
color: #FFFFFF;
|
||||
background-color: #D0442C;
|
||||
position: relative;
|
||||
display: block;
|
||||
font-size: 16px;
|
||||
{{ neutralize_banner_style or '' }}">
|
||||
<t t-out="neutralize_banner_text">This database is neutralized.</t>
|
||||
</span>
|
||||
</div>
|
||||
</xpath>
|
||||
</template>
|
||||
</odoo>
|
||||
@@ -103,6 +103,7 @@
|
||||
'views/ir_attachment_views.xml',
|
||||
'views/ir_model_views.xml',
|
||||
'views/res_partner_views.xml',
|
||||
'views/neutralize_views.xml',
|
||||
'wizard/base_language_install_views.xml',
|
||||
'wizard/website_robots.xml',
|
||||
],
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
-- delete domains on websites
|
||||
UPDATE website
|
||||
SET domain = NULL;
|
||||
|
||||
-- activate neutralization watermarks
|
||||
UPDATE ir_ui_view
|
||||
SET active = true
|
||||
WHERE key = 'website.neutralize_ribbon';
|
||||
@@ -1761,12 +1761,3 @@ class Website(models.Model):
|
||||
for word in re.findall(match_pattern, value):
|
||||
if word[0] == search[0]:
|
||||
yield word.lower()
|
||||
|
||||
# ----------------------------------------------------------
|
||||
# ORM overrides
|
||||
# ----------------------------------------------------------
|
||||
def _neutralize(self):
|
||||
super()._neutralize()
|
||||
self.flush_model()
|
||||
self.invalidate_model()
|
||||
self.env.cr.execute("UPDATE website SET domain=NULL")
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<template id="website.neutralize_ribbon" name="Neutralize Ribbon" inherit_id="website.layout" active="False">
|
||||
<xpath expr="//body" position="inside">
|
||||
<div>
|
||||
<span id="oe_neutralize_ribbon" t-attf-style="
|
||||
width: 400px;
|
||||
top: 55px;
|
||||
left: -100px;
|
||||
font-size: 32px;
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
line-height: 30px;
|
||||
color: #F0F0F0;
|
||||
transform: rotate(-45deg);
|
||||
position: fixed;
|
||||
box-shadow: 0 0 3px rgba(0, 0, 0, 0.3);
|
||||
background: #D0442C;
|
||||
opacity: 0.6;
|
||||
pointer-events: none;
|
||||
text-transform: uppercase;
|
||||
z-index: 9999;
|
||||
{{ neutralize_ribbon_style or ''}}">
|
||||
<t t-out="neutralize_ribbon_text">Neutralized</t>
|
||||
</span>
|
||||
</div>
|
||||
</xpath>
|
||||
</template>
|
||||
</odoo>
|
||||
@@ -0,0 +1,4 @@
|
||||
INSERT INTO ir_config_parameter (key, value)
|
||||
VALUES ('reveal.endpoint', 'https://iap-services-test.odoo.com')
|
||||
ON CONFLICT (key) DO
|
||||
UPDATE SET value = 'https://iap-services-test.odoo.com';
|
||||
@@ -4,5 +4,4 @@
|
||||
from . import crm_lead
|
||||
from . import crm_reveal_rule
|
||||
from . import crm_reveal_view
|
||||
from . import iap_account
|
||||
from . import ir_http
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import models
|
||||
|
||||
|
||||
class IapAccount(models.Model):
|
||||
_inherit = 'iap.account'
|
||||
|
||||
def _get_iap_config_parameters(self):
|
||||
return super()._get_iap_config_parameters() + ['reveal.endpoint']
|
||||
@@ -2,4 +2,3 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import test_lead_reveal
|
||||
from . import test_neutralize
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.tests.common import TransactionCase
|
||||
|
||||
|
||||
class TestIapLeadWebsiteNeutralize(TransactionCase):
|
||||
|
||||
def test_iap_lead_website_neutralize(self):
|
||||
ICP = self.env['ir.config_parameter']
|
||||
key = 'reveal.endpoint'
|
||||
ICP.set_param(key, 'Fake test reveal endpoint')
|
||||
|
||||
self.env['iap.account']._neutralize()
|
||||
self.assertEqual(ICP.get_param(key), 'https://iap-services-test.odoo.com')
|
||||
@@ -0,0 +1,19 @@
|
||||
-- deactivate mail servers
|
||||
UPDATE ir_mail_server
|
||||
SET active = false;
|
||||
|
||||
-- deactivate crons
|
||||
UPDATE ir_cron
|
||||
SET active = false
|
||||
WHERE id NOT IN (
|
||||
SELECT res_id
|
||||
FROM ir_model_data
|
||||
WHERE model = 'ir.cron'
|
||||
AND name = 'autovacuum_job'
|
||||
);
|
||||
|
||||
-- neutralization flag for the database
|
||||
INSERT INTO ir_config_parameter (key, value)
|
||||
VALUES ('database.is_neutralized', true)
|
||||
ON CONFLICT (key) DO
|
||||
UPDATE SET value = true;
|
||||
@@ -502,19 +502,6 @@ class ir_cron(models.Model):
|
||||
cr.execute('NOTIFY cron_trigger, %s', [self.env.cr.dbname])
|
||||
_logger.debug("cron workers notified")
|
||||
|
||||
def _neutralize(self):
|
||||
super()._neutralize()
|
||||
self.env.flush_all()
|
||||
self.env.invalidate_all()
|
||||
self.env.cr.execute("""
|
||||
UPDATE ir_cron
|
||||
SET active = false
|
||||
WHERE id NOT IN (
|
||||
SELECT res_id FROM ir_model_data
|
||||
WHERE model='ir.cron' AND name = 'autovacuum_job'
|
||||
)
|
||||
""")
|
||||
|
||||
|
||||
class ir_cron_trigger(models.Model):
|
||||
_name = 'ir.cron.trigger'
|
||||
|
||||
@@ -784,9 +784,3 @@ class IrMailServer(models.Model):
|
||||
outgoing mail server.
|
||||
"""
|
||||
return getattr(threading.current_thread(), 'testing', False) or self.env.registry.in_test_mode()
|
||||
|
||||
def _neutralize(self):
|
||||
super()._neutralize()
|
||||
self.env.flush_all()
|
||||
self.env.invalidate_all()
|
||||
self.env.cr.execute("UPDATE ir_mail_server SET active = false")
|
||||
|
||||
@@ -53,3 +53,4 @@ from . import test_form_create
|
||||
from . import test_cloc
|
||||
from . import test_profiler
|
||||
from . import test_pdf
|
||||
from . import test_neutralize
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user