diff --git a/base_extended_security/__manifest__.py b/base_extended_security/__manifest__.py index 46aababe..1947e972 100644 --- a/base_extended_security/__manifest__.py +++ b/base_extended_security/__manifest__.py @@ -3,13 +3,13 @@ { "name": "Base Extended Security", - "version": "16.0.1.1.0", + "version": "16.0.1.1.1", "author": "Numigi", "maintainer": "Numigi", "license": "LGPL-3", "category": "Other", "summary": "Securize access to records", - "depends": ["web", "account"], + "depends": ["web"], "data": [ "security/ir.model.access.csv", "views/extended_security_rule.xml", diff --git a/base_extended_security/models/base.py b/base_extended_security/models/base.py index 595a8a40..5716dfc7 100644 --- a/base_extended_security/models/base.py +++ b/base_extended_security/models/base.py @@ -4,7 +4,7 @@ from odoo import models, api -class BaseWithExtendedSecurity(models.AbstractModel): +class Base(models.AbstractModel): _inherit = "base" diff --git a/base_extended_security/models/ir_ui_view.py b/base_extended_security/models/ir_ui_view.py index f13e842f..13ec389f 100644 --- a/base_extended_security/models/ir_ui_view.py +++ b/base_extended_security/models/ir_ui_view.py @@ -5,7 +5,7 @@ from odoo import api, models -class ViewWithButtonsHiden(models.Model): +class IrUiView(models.Model): _inherit = "ir.ui.view" def _remove_write_access_buttons(self, env, model, tree): diff --git a/base_extended_security/tests/test_security_rules.py b/base_extended_security/tests/test_security_rules.py index c0ffd797..26c4309b 100644 --- a/base_extended_security/tests/test_security_rules.py +++ b/base_extended_security/tests/test_security_rules.py @@ -29,15 +29,41 @@ def setUpClass(cls): } ) - cls.product = cls.env["product.product"].create( + # PARTNER + cls.partner = cls.env["res.partner"].create( { - "name": "Product 1", + "name": "Partner 1", } ) cls.rule = cls.env["extended.security.rule"].create( { - "model_id": cls.env.ref("product.model_product_product").id, + "model_id": cls.env.ref("base.model_res_partner").id, + "group_ids": [(4, cls.group.id)], + "perm_read": False, + "perm_write": False, + "perm_create": False, + "perm_unlink": False, + } + ) + + # IR ACTIONS SERVER + cls.res_partner_model = cls.env["ir.model"].search( + [("model", "=", "res.partner")] + ) + cls.comment_html = "
MyComment
" + cls.action_1 = cls.env["ir.actions.server"].create( + { + "name": "TestAction", + "model_id": cls.res_partner_model.id, + "model_name": "res.partner", + "state": "code", + "code": 'record.write({"comment": "%s"})' % cls.comment_html, + } + ) + cls.rule_1 = cls.env["extended.security.rule"].create( + { + "model_id": cls.env.ref("base.model_ir_actions_server").id, "group_ids": [(4, cls.group.id)], "perm_read": False, "perm_write": False, @@ -51,12 +77,12 @@ def test_if_member_of_group__access_error_not_raised(self, access_type): self.rule["perm_{}".format(access_type)] = True self.user.groups_id |= self.group method = "check_extended_security_{}".format(access_type) - getattr(self.product.with_user(self.user), method)() + getattr(self.partner.with_user(self.user), method)() @data("read", "write", "create", "unlink") def test_if_access_type_uncheked__access_error_raised(self, access_type): method = "check_extended_security_{}".format(access_type) - getattr(self.product.with_user(self.user), method)() + getattr(self.partner.with_user(self.user), method)() @data("read", "write", "create", "unlink") def test_if_not_member_of_group__access_error_raised(self, access_type): @@ -64,74 +90,70 @@ def test_if_not_member_of_group__access_error_raised(self, access_type): method = "check_extended_security_{}".format(access_type) with pytest.raises(AccessError): - getattr(self.product.with_user(self.user), method)() + getattr(self.partner.with_user(self.user), method)() def test_after_rule_deleted__rule_not_applied(self): self.rule.perm_read = True with pytest.raises(AccessError): - self.product.with_user(self.user).check_extended_security_read() + self.partner.with_user(self.user).check_extended_security_read() self.rule.unlink() - self.product.with_user(self.user).check_extended_security_read() + self.partner.with_user(self.user).check_extended_security_read() def test_after_rule_created__rule_applied(self): - self.product.with_user(self.user).check_extended_security_read() + self.partner.with_user(self.user).check_extended_security_read() self.rule.copy({"perm_read": True}) with pytest.raises(AccessError): - self.product.with_user(self.user).check_extended_security_read() + self.partner.with_user(self.user).check_extended_security_read() def test_after_rule_unchecked__rule_not_applied(self): self.rule.perm_read = True with pytest.raises(AccessError): - self.product.with_user(self.user).check_extended_security_read() + self.partner.with_user(self.user).check_extended_security_read() self.rule.perm_read = False - self.product.with_user(self.user).check_extended_security_read() + self.partner.with_user(self.user).check_extended_security_read() def test_after_rule_archived__rule_not_applied(self): self.rule.perm_read = True with pytest.raises(AccessError): - self.product.with_user(self.user).check_extended_security_read() + self.partner.with_user(self.user).check_extended_security_read() self.rule.active = False - self.product.with_user(self.user).check_extended_security_read() + self.partner.with_user(self.user).check_extended_security_read() def test_after_rule_checked__rule_applied(self): - self.product.with_user(self.user).check_extended_security_read() + self.partner.with_user(self.user).check_extended_security_read() self.rule.perm_read = True with pytest.raises(AccessError): - self.product.with_user(self.user).check_extended_security_read() + self.partner.with_user(self.user).check_extended_security_read() def test_on_search__if_not_authorized__domain_is_empty(self): self.rule.perm_read = True domain = ( - self.env["product.product"] - .with_user(self.user) - .get_extended_security_domain() + self.env["res.partner"].with_user(self.user).get_extended_security_domain() ) - search_result = self.env["product.product"].search(domain) - assert self.product not in search_result + search_result = self.env["res.partner"].search(domain) + assert self.partner not in search_result def test_on_search__if_authorized__domain_not_empty(self): self.rule.perm_read = True self.user.groups_id |= self.group domain = ( - self.env["product.product"] - .with_user(self.user) - .get_extended_security_domain() + self.env["res.partner"].with_user(self.user).get_extended_security_domain() ) - search_result = self.env["product.product"].search(domain) + search_result = self.env["res.partner"].search(domain) - assert self.product in search_result + assert self.partner in search_result - def _get_product_list_view_arch(self): - view = self.env.ref("product.product_product_tree_view") - arch = self.env["product.product"].get_view(view_id=view.id)["arch"] + def _get_partner_list_view_arch(self): + view = self.env.ref("base.view_partner_tree") + arch = self.env["res.partner"].get_view(view_id=view.id)["arch"] return etree.fromstring(arch) @data( @@ -143,7 +165,7 @@ def _get_product_list_view_arch(self): def test_if_authorized__view_property_not_disabled( self, access_type, view_property ): - list_view = self._get_product_list_view_arch() + list_view = self._get_partner_list_view_arch() assert view_property not in list_view.attrib def _get_nested_ir_rule_many2many_arch(self): @@ -177,6 +199,15 @@ def _get_nested_ir_model_access_one2many_arch(self): tree_attrib = model_access_field["edition_view"]["tree"].attrib return tree_attrib + def test_if_not_authorized__toggle_button_hidden(self): + self.rule_1.perm_write = True + form_view = self._get_ir_actions_server_form_view_arch() + assert not form_view.xpath("//header/button[@name='create_action']") + + def test_if_authorized__toggle_button_not_hidden(self): + form_view = self._get_ir_actions_server_form_view_arch() + assert form_view.xpath("//header/button[@name='create_action']") + @data( ("write", "edit"), ("create", "create"), @@ -197,11 +228,6 @@ def test_in_nested_one2many_list__view_property_disabled( one2many_list = self._get_nested_ir_model_access_one2many_arch() assert view_property in one2many_list - def test_if_not_authorized__toggle_button_hidden(self): - self.rule.perm_write = True - form_view = self._get_product_form_view_arch() - assert not form_view.xpath("//button[@name='action_update_quantity_on_hand']") - def test_read_access_action(self): self.rule.model_id = self.env.ref("base.model_res_partner") self.rule.perm_write = True @@ -217,22 +243,22 @@ def test_read_access_action(self): def test_if_unauthorized__view_property_disabled(self, access_type, view_property): self.rule["perm_{}".format(access_type)] = True - list_view = self._get_product_list_view_arch() + list_view = self._get_partner_list_view_arch() assert list_view.attrib[view_property] == "false" - def _get_product_form_view_arch(self): - return self._get_form_view_arch( - "product.product", "product.product_normal_form_view" - ) - def _get_partner_form_view_arch(self): return self._get_form_view_arch("res.partner", "base.view_partner_form") + def _get_ir_actions_server_form_view_arch(self): + return self._get_form_view_arch( + "ir.actions.server", "base.view_server_action_form" + ) + def _get_form_view_arch(self, model, view_ref): view = self.env.ref(view_ref) arch = self.env[model].get_view(view_id=view.id)["arch"] return etree.fromstring(arch) - def test_if_authorized__toggle_button_not_hidden(self): - form_view = self._get_product_form_view_arch() - assert form_view.xpath("//button[@name='action_open_label_layout']") + def test_if_authorized__field_not_hidden(self): + form_view = self._get_partner_form_view_arch() + assert form_view.xpath("//field[@name='name']")