From e096a210aa3c0ab0bc1cf637009613ae3627c620 Mon Sep 17 00:00:00 2001 From: sami odoo Date: Tue, 7 Nov 2023 09:29:20 +0000 Subject: [PATCH] [FIX] base: prevent language deactivation Before this commit user was able to archive the language used by superuser Odoobot by activating different language. Because of which whenever odoobot was in action then the user faced error. Steps to produce: - Install `contacts`. - Settings > Translations > Languages > Choose a language eg: English (UK). - Activate that language and switch to it. - In `contacts` change the language of each contact in the contacts to the newly selected language. - Settings > Translations > Languages > Choose English (US) and archive it. - Settings > User & Companies > User, Apply the filter of Inactive Users. After this commit user would not be able to archive the language used by superuser or the language in which there db was installed. Task-2896526 closes odoo/odoo#149215 X-original-commit: 681fc0a04c7ca625c7120ff2f7b537b75398b23d Related: odoo/enterprise#54209 Signed-off-by: Raphael Collet --- odoo/addons/base/i18n/base.pot | 8 ++++++++ odoo/addons/base/models/res_lang.py | 6 ++++-- odoo/addons/base/tests/test_res_lang.py | 19 +++++++++++++++++++ 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/odoo/addons/base/i18n/base.pot b/odoo/addons/base/i18n/base.pot index 424adb8a8e7..41b75b2d060 100644 --- a/odoo/addons/base/i18n/base.pot +++ b/odoo/addons/base/i18n/base.pot @@ -31475,6 +31475,14 @@ msgstr "" #. module: base #. odoo-python +#: code:addons/base/models/res_lang.py:0 +#, python-format +msgid "" +"You cannot archive the language in which Odoo was setup as it is used by " +"automated processes." +msgstr "" + +#. module: base #: code:addons/base/models/res_partner.py:0 #, python-format msgid "You cannot create recursive Partner hierarchies." diff --git a/odoo/addons/base/models/res_lang.py b/odoo/addons/base/models/res_lang.py index ff8ae31778b..0ebfd61f430 100644 --- a/odoo/addons/base/models/res_lang.py +++ b/odoo/addons/base/models/res_lang.py @@ -292,10 +292,12 @@ class Lang(models.Model): if 'code' in vals and any(code != vals['code'] for code in lang_codes): raise UserError(_("Language code cannot be modified.")) if vals.get('active') == False: - if self.env['res.users'].search_count([('lang', 'in', lang_codes)]): + if self.env['res.users'].with_context(active_test=True).search_count([('lang', 'in', lang_codes)], limit=1): raise UserError(_("Cannot deactivate a language that is currently used by users.")) - if self.env['res.partner'].search_count([('lang', 'in', lang_codes)]): + if self.env['res.partner'].with_context(active_test=True).search_count([('lang', 'in', lang_codes)], limit=1): raise UserError(_("Cannot deactivate a language that is currently used by contacts.")) + if self.env['res.users'].with_context(active_test=False).search_count([('lang', 'in', lang_codes)], limit=1): + raise UserError(_("You cannot archive the language in which Odoo was setup as it is used by automated processes.")) # delete linked ir.default specifying default partner's language self.env['ir.default'].discard_values('res.partner', 'lang', lang_codes) diff --git a/odoo/addons/base/tests/test_res_lang.py b/odoo/addons/base/tests/test_res_lang.py index 3f6cf27b64e..bf42748e225 100644 --- a/odoo/addons/base/tests/test_res_lang.py +++ b/odoo/addons/base/tests/test_res_lang.py @@ -2,6 +2,7 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. from odoo.tests.common import TransactionCase +from odoo.exceptions import UserError class test_res_lang(TransactionCase): @@ -40,3 +41,21 @@ class test_res_lang(TransactionCase): assert intersperse("abc12", [3], '.') == ('abc12', 0) assert intersperse("abc12", [2], '.') == ('abc12', 0) assert intersperse("abc12", [1], '.') == ('abc1.2', 1) + + def test_inactive_users_lang_deactivation(self): + # activate the language en_GB + language = self.env['res.lang']._activate_lang('en_GB') + + # assign it to an inactive (new) user + user = self.env['res.users'].create({ + 'name': 'Foo', + 'login': 'foo@example.com', + 'lang': 'en_GB', + 'active': False, + }) + + # make sure it is only used by that user + self.assertEqual(self.env['res.users'].with_context(active_test=False).search([('lang', '=', 'en_GB')]), user) + + with self.assertRaises(UserError): + language.active = False