[FIX] base: Module category can reference itself as parent
Steps: - Update a module category to reference itself as parent OR - Update multiple module categories to create a circular dependency (A -> B -> A) Actual result: - Upgrade a module is impossible - Un/Install a module is impossible - Infinite loop: https://github.com/odoo/odoo/blob/15.0/odoo/addons/base/models/ir_module.py#L900 Expected result: - Circular dependencies not possible - Module can be upgrade and un/install opw-3490162 closes odoo/odoo#149284 X-original-commit: 6932714200d158a21bf10b90b2f71fa5cae0b13f Signed-off-by: Raphael Collet <rco@odoo.com>
This commit is contained in:
@@ -26,7 +26,7 @@ import psycopg2
|
||||
import odoo
|
||||
from odoo import api, fields, models, modules, tools, _
|
||||
from odoo.addons.base.models.ir_model import MODULE_UNINSTALL_FLAG
|
||||
from odoo.exceptions import AccessDenied, UserError
|
||||
from odoo.exceptions import AccessDenied, UserError, ValidationError
|
||||
from odoo.osv import expression
|
||||
from odoo.tools.parse_version import parse_version
|
||||
from odoo.tools.misc import topological_sort, get_flag
|
||||
@@ -98,6 +98,12 @@ class ModuleCategory(models.Model):
|
||||
for cat in self:
|
||||
cat.xml_id = xml_ids.get(cat.id, [''])[0]
|
||||
|
||||
@api.constrains('parent_id')
|
||||
def _check_parent_not_circular(self):
|
||||
if not self._check_recursion():
|
||||
raise ValidationError(_("Error ! You cannot create recursive categories."))
|
||||
|
||||
|
||||
class MyFilterMessages(Transform):
|
||||
"""
|
||||
Custom docutils transform to remove `system message` for a document and
|
||||
|
||||
@@ -64,3 +64,4 @@ from . import test_profiler
|
||||
from . import test_pdf
|
||||
from . import test_neutralize
|
||||
from . import test_config_parameter
|
||||
from . import test_ir_module_category
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
from odoo.exceptions import ValidationError
|
||||
from odoo.tests.common import TransactionCase
|
||||
|
||||
class TestModuleCategory(TransactionCase):
|
||||
|
||||
def test_parent_circular_dependencies(self):
|
||||
Cats = self.env['ir.module.category']
|
||||
|
||||
def create(name, **kw):
|
||||
return Cats.create(dict(kw, name=name))
|
||||
|
||||
category_a = create('A', parent_id=False)
|
||||
category_b = create('B', parent_id=category_a.id)
|
||||
category_c = create('C', parent_id=category_b.id)
|
||||
|
||||
with self.assertRaises(ValidationError):
|
||||
category_a.write({'parent_id': category_c.id})
|
||||
with self.assertRaises(ValidationError):
|
||||
category_b.write({'parent_id': category_b.id})
|
||||
Reference in New Issue
Block a user