From 860c842313e7eef4f197eafc2d4492929fc7dcac Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Thu, 10 Jan 2019 13:28:17 +0000 Subject: [PATCH] [IMP] base: error message on ACL failure, test --- odoo/addons/base/models/ir_model.py | 21 +++--- .../test_access_rights/tests/__init__.py | 1 + .../test_access_rights/tests/test_feedback.py | 73 +++++++++++++++++++ 3 files changed, 86 insertions(+), 9 deletions(-) create mode 100644 odoo/addons/test_access_rights/tests/test_feedback.py diff --git a/odoo/addons/base/models/ir_model.py b/odoo/addons/base/models/ir_model.py index 84f993bca79..a9ab795e4b7 100644 --- a/odoo/addons/base/models/ir_model.py +++ b/odoo/addons/base/models/ir_model.py @@ -1233,20 +1233,23 @@ class IrModelAccess(models.Model): r = self._cr.fetchone()[0] if not r and raise_exception: - groups = '\n\t'.join('- %s' % g for g in self.group_names_with_access(model, mode)) + groups = '\n'.join('\t- %s' % g for g in self.group_names_with_access(model, mode)) msg_heads = { # Messages are declared in extenso so they are properly exported in translation terms - 'read': _("Sorry, you are not allowed to access this document."), - 'write': _("Sorry, you are not allowed to modify this document."), - 'create': _("Sorry, you are not allowed to create this kind of document."), - 'unlink': _("Sorry, you are not allowed to delete this document."), + 'read': _("Sorry, you are not allowed to access documents of type '%(document_kind)s' (%(document_model)s)."), + 'write': _("Sorry, you are not allowed to modify documents of type '%(document_kind)s' (%(document_model)s)."), + 'create': _("Sorry, you are not allowed to create documents of type '%(document_kind)s' (%(document_model)s)."), + 'unlink': _("Sorry, you are not allowed to delete documents of type '%(document_kind)s' (%(document_model)s)."), + } + msg_params = { + 'document_kind': self.env['ir.model']._get(model).name or model, + 'document_model': model, } if groups: - msg_tail = _("Only users with the following access level are currently allowed to do that") + ":\n%s\n\n(" + _("Document model") + ": %s)" - msg_params = (groups, model) + msg_tail = _("This operation is allowed for the groups:\n%(groups_list)s") + msg_params['groups_list'] = groups else: - msg_tail = _("Please contact your system administrator if you think this is an error.") + "\n\n(" + _("Document model") + ": %s)" - msg_params = (model,) + msg_tail = _("No group currently allows this operation.") _logger.info('Access Denied by ACLs for operation: %s, uid: %s, model: %s', mode, self._uid, model) msg = '%s %s' % (msg_heads[mode], msg_tail) raise AccessError(msg % msg_params) diff --git a/odoo/addons/test_access_rights/tests/__init__.py b/odoo/addons/test_access_rights/tests/__init__.py index 1ba8765ddc0..cba993681cf 100644 --- a/odoo/addons/test_access_rights/tests/__init__.py +++ b/odoo/addons/test_access_rights/tests/__init__.py @@ -1 +1,2 @@ from . import test_ir_rules +from . import test_feedback diff --git a/odoo/addons/test_access_rights/tests/test_feedback.py b/odoo/addons/test_access_rights/tests/test_feedback.py new file mode 100644 index 00000000000..ff7df6cd47d --- /dev/null +++ b/odoo/addons/test_access_rights/tests/test_feedback.py @@ -0,0 +1,73 @@ +# -*- coding: utf-8 -*- +from odoo.exceptions import AccessError +from odoo.tests import common, TransactionCase + + +class Feedback(TransactionCase): + def setUp(self): + super().setUp() + + self.group0 = self.env['res.groups'].create({'name': "Group 0"}) + self.group1 = self.env['res.groups'].create({'name': "Group 1"}) + self.user = self.env['res.users'].create({ + 'login': 'bob', + 'name': "Bob Bobman", + 'groups_id': [(4, self.env.ref('base.group_no_one').id)] + }) + + +class TestACLFeedback(Feedback): + """ Tests that proper feedback is returned on ir.model.access errors + """ + def setUp(self): + super().setUp() + ACL = self.env['ir.model.access'] + m = self.env['ir.model'].search([('model', '=', 'test_access_right.some_obj')]) + ACL.search([('model_id', '=', m.id)]).unlink() + ACL.create({ + 'name': "read", + 'model_id': m.id, + 'group_id': self.group1.id, + 'perm_read': True, + }) + ACL.create({ + 'name': "create-and-read", + 'model_id': m.id, + 'group_id': self.group0.id, + 'perm_read': True, + 'perm_create': True, + }) + self.record = self.env['test_access_right.some_obj'].create({'val': 5}) + + def test_no_groups(self): + """ Operation is never allowed + """ + with self.assertRaises(AccessError) as ctx: + self.record.sudo(self.user).write({'val': 10}) + self.assertEqual( + ctx.exception.args[0], + """Sorry, you are not allowed to modify documents of type 'Object For Test Access Right' (test_access_right.some_obj). No group currently allows this operation.""" + ) + + def test_one_group(self): + with self.assertRaises(AccessError) as ctx: + self.env(user=self.user)['test_access_right.some_obj'].create({ + 'val': 1 + }) + self.assertEqual( + ctx.exception.args[0], + """Sorry, you are not allowed to create documents of type 'Object For Test Access Right' (test_access_right.some_obj). This operation is allowed for the groups: + - Group 0""" + ) + def test_two_groups(self): + r = self.record.sudo(self.user) + expected = """Sorry, you are not allowed to access documents of type 'Object For Test Access Right' (test_access_right.some_obj). This operation is allowed for the groups: + - Group 0 + - Group 1""" + with self.assertRaises(AccessError) as ctx: + # noinspection PyStatementEffect + r.val + self.assertEqual(ctx.exception.args[0], expected) + with self.assertRaises(AccessError) as ctx: + r.read(['val']) + self.assertEqual(ctx.exception.args[0], expected)