changeset 6572:ccd53bd0fa25 4.2

Check read access on field in search domain issue7766 review50591002 (grafted from 52b1acb313aaed76417de1153680f0920e9d8123)
author Cédric Krier <ced@b2ck.com>
date Mon, 12 Nov 2018 17:18:06 +0100
parents 01b47e46bbcd
children 6a80c192098b
files CHANGELOG trytond/model/modelsql.py trytond/model/modelstorage.py
diffstat 3 files changed, 45 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGELOG	Wed Oct 31 18:13:02 2018 +0100
+++ b/CHANGELOG	Mon Nov 12 17:18:06 2018 +0100
@@ -1,3 +1,5 @@
+* Check read access on field in search domain (issue7766)
+
 Version 4.2.15 - 2018-08-20
 * Bug fixes (see mercurial logs for details)
 
--- a/trytond/model/modelsql.py	Wed Oct 31 18:13:02 2018 +0100
+++ b/trytond/model/modelsql.py	Mon Nov 12 17:18:06 2018 +0100
@@ -14,7 +14,6 @@
 from trytond.model import fields
 from trytond import backend
 from trytond.tools import reduce_ids, grouped_slice, cursor_dict
-from trytond.const import OPERATORS
 from trytond.transaction import Transaction
 from trytond.pool import Pool
 from trytond.cache import LRUDict
@@ -22,7 +21,7 @@
 from trytond.rpc import RPC
 from trytond.config import config
 
-from .modelstorage import cache_size
+from .modelstorage import cache_size, is_leaf
 
 
 class Constraint(object):
@@ -1116,6 +1115,9 @@
         transaction = Transaction()
         cursor = transaction.connection.cursor()
 
+        super(ModelSQL, cls).search(
+            domain, offset=offset, limit=limit, order=order, count=count)
+
         # Get domain clauses
         tables, expression = cls.search_domain(domain)
 
@@ -1274,12 +1276,6 @@
             else:
                 tables[None] = (cls.__table__(), None)
 
-        def is_leaf(expression):
-            return (isinstance(expression, (list, tuple))
-                and len(expression) > 2
-                and isinstance(expression[1], basestring)
-                and expression[1] in OPERATORS)  # TODO remove OPERATORS test
-
         def convert(domain):
             if is_leaf(domain):
                 fname = domain[0].split('.', 1)[0]
--- a/trytond/model/modelstorage.py	Wed Oct 31 18:13:02 2018 +0100
+++ b/trytond/model/modelstorage.py	Mon Nov 12 17:18:06 2018 +0100
@@ -43,6 +43,13 @@
         config.getint('cache', 'record'))
 
 
+def is_leaf(expression):
+    return (isinstance(expression, (list, tuple))
+        and len(expression) > 2
+        and isinstance(expression[1], basestring)
+        and expression[1] in OPERATORS)  # TODO remove OPERATORS test
+
+
 class ModelStorage(Model):
     """
     Define a model with storage capability in Tryton.
@@ -369,6 +376,36 @@
         '''
         Return a list of records that match the domain.
         '''
+        pool = Pool()
+        transaction = Transaction()
+        ModelAccess = pool.get('ir.model.access')
+        ModelFieldAccess = pool.get('ir.model.field.access')
+
+        ModelAccess.check(cls.__name__, 'read')
+
+        def check(domain, cls, to_check):
+            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])
+                    else:
+                        target = cls._fields[local].get_target()
+                    target_domain = [(relate,) + tuple(domain[1:])]
+                    check(target_domain, target, to_check)
+            elif not domain:
+                return
+            else:
+                i = 1 if domain[0] in ['OR', 'AND'] else 0
+                for d in domain[i:]:
+                    check(d, cls, to_check)
+        if transaction.user and transaction.context.get('_check_access'):
+            to_check = defaultdict(set)
+            check(domain, cls, to_check)
+            for name, fields_names in to_check.items():
+                ModelAccess.check(name, 'read')
+                ModelFieldAccess.check(name, fields_names, 'read')
         if count:
             return 0
         return []
@@ -418,10 +455,7 @@
             while i < len(domain):
                 arg = domain[i]
                 # add test for xmlrpc that doesn't handle tuple
-                if (isinstance(arg, tuple)
-                        or (isinstance(arg, list)
-                            and len(arg) > 2
-                            and arg[1] in OPERATORS)):
+                if is_leaf(arg):
                     if arg[0] == 'active':
                         active_found = True
                 elif isinstance(arg, list):
@@ -886,6 +920,7 @@
         pass
 
     @classmethod
+    @without_check_access
     def _validate(cls, records, field_names=None):
         pool = Pool()
         # Ensure that records are readable

Repository Layout

/ Tryton top level repositories
modules Modules
public Public repositories
tpf Tryton Foundation repositories
sandbox Sandbox