Check read access on parent field of child/parent operators
The 4th element of the clause is the parent field for the child_of/parent_of operators, so it must be used to check access as related field. Also we must remove the 4th element when checking related domain. issue11115 review391371002
This commit is contained in:
@@ -496,13 +496,20 @@ class ModelStorage(Model):
|
||||
if is_leaf(domain):
|
||||
local, relate = (domain[0].split('.', 1) + [None])[:2]
|
||||
to_check[cls.__name__].add(local)
|
||||
if relate:
|
||||
if len(domain) >= 4:
|
||||
target = pool.get(domain[3])
|
||||
elif hasattr(cls._fields[local], 'get_target'):
|
||||
target = cls._fields[local].get_target()
|
||||
else:
|
||||
return
|
||||
field = cls._fields[local]
|
||||
target = None
|
||||
if hasattr(field, 'get_target'):
|
||||
target = cls._fields[local].get_target()
|
||||
if (not relate
|
||||
and (domain[1].endswith('child_of')
|
||||
or domain[1].endswith('parent_of'))
|
||||
and len(domain) >= 4):
|
||||
relate = domain[3]
|
||||
domain = domain[:3] + domain[4:]
|
||||
if field._type == 'reference' and len(domain) >= 4:
|
||||
target = pool.get(domain[3])
|
||||
domain = domain[:3] + domain[4:]
|
||||
if relate and target:
|
||||
target_domain = [(relate,) + tuple(domain[1:])]
|
||||
check_domain(target_domain, target, to_check)
|
||||
elif not domain:
|
||||
@@ -518,8 +525,9 @@ class ModelStorage(Model):
|
||||
for oexpr, otype in order:
|
||||
local, _, relate = oexpr.partition('.')
|
||||
to_check[cls.__name__].add(local)
|
||||
if relate and hasattr(cls._fields[local], 'get_target'):
|
||||
target = cls._fields[local].get_target()
|
||||
field = cls._fields[local]
|
||||
if relate and hasattr(field, 'get_target'):
|
||||
target = field.get_target()
|
||||
target_order = [(relate, otype)]
|
||||
check_order(target_order, target, to_check)
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ class TestAccessRelate(ModelSQL):
|
||||
"Test Access"
|
||||
__name__ = 'test.access.relate'
|
||||
value = fields.Integer("Value")
|
||||
parent = fields.Many2One('test.access.relate', "Parent")
|
||||
|
||||
|
||||
class TestAccessModel(TestAccess):
|
||||
|
||||
@@ -935,6 +935,8 @@ class ModelFieldAccessReadTestCase(_ModelFieldAccessTestCase):
|
||||
|
||||
TestAccess.search([('relate.value', '=', 42)])
|
||||
TestAccess.search([('reference.value', '=', 42, 'test.access.relate')])
|
||||
TestAccess.search([
|
||||
('reference.parent.value', '=', 42, 'test.access.relate')])
|
||||
TestAccess.search([], order=[('relate.value', 'ASC')])
|
||||
|
||||
@with_transaction(context=_context)
|
||||
@@ -958,9 +960,49 @@ class ModelFieldAccessReadTestCase(_ModelFieldAccessTestCase):
|
||||
with self.assertRaises(AccessError):
|
||||
TestAccess.search(
|
||||
[('reference.value', '=', 42, 'test.access.relate')])
|
||||
with self.assertRaises(AccessError):
|
||||
TestAccess.search(
|
||||
[('reference.parent.value', '=', 42, 'test.access.relate')])
|
||||
with self.assertRaises(AccessError):
|
||||
TestAccess.search([], order=[('relate.value', 'ASC')])
|
||||
|
||||
@with_transaction(context=_context)
|
||||
def test_access_search_relate_parent_field(self):
|
||||
"Test access on search relate with a parent field"
|
||||
pool = Pool()
|
||||
TestAccess = pool.get('test.access')
|
||||
Field = pool.get('ir.model.field')
|
||||
FieldAccess = pool.get('ir.model.field.access')
|
||||
field, = Field.search([
|
||||
('model.model', '=', 'test.access.relate'),
|
||||
('name', '=', 'parent'),
|
||||
])
|
||||
FieldAccess.create([{
|
||||
'field': field.id,
|
||||
'perm_read': True,
|
||||
}])
|
||||
|
||||
TestAccess.search([('relate', 'child_of', 42, 'parent')])
|
||||
|
||||
@with_transaction(context=_context)
|
||||
def test_no_access_search_relate_parent_field(self):
|
||||
"Test no access on search relate with a parent field"
|
||||
pool = Pool()
|
||||
TestAccess = pool.get('test.access')
|
||||
Field = pool.get('ir.model.field')
|
||||
FieldAccess = pool.get('ir.model.field.access')
|
||||
field, = Field.search([
|
||||
('model.model', '=', 'test.access.relate'),
|
||||
('name', '=', 'parent'),
|
||||
])
|
||||
FieldAccess.create([{
|
||||
'field': field.id,
|
||||
'perm_read': False,
|
||||
}])
|
||||
|
||||
with self.assertRaises(AccessError):
|
||||
TestAccess.search([('relate', 'child_of', 42, 'parent')])
|
||||
|
||||
|
||||
class ModelFieldAccessWriteTestCase(_ModelFieldAccessTestCase):
|
||||
_perm = 'perm_write'
|
||||
|
||||
Reference in New Issue
Block a user