Compute cache key for record rules using all models
As model can inherit the access rules from another, the key must include the keys of those other models. Closes #13162 (grafted from b04f36d27c78663851f6859e266aac203afd7600) --HG-- branch : 7.0
This commit is contained in:
1 parent
d1484be87e
commit
d92c741136
1 file changed
+30
-19
+30
-19
@@ -17,6 +17,28 @@ class DomainError(ValidationError):
|
||||
pass
|
||||
|
||||
|
||||
def _get_access_models(Model, names=None, model2field=None, path=None):
|
||||
"Return names and model2field"
|
||||
if names is None:
|
||||
names = set()
|
||||
if model2field is None:
|
||||
model2field = defaultdict(list)
|
||||
if Model.__name__ in names:
|
||||
return
|
||||
names.add(Model.__name__)
|
||||
if path:
|
||||
model2field[Model.__name__].append(path)
|
||||
for field_name in Model.__access__:
|
||||
field = getattr(Model, field_name)
|
||||
Target = field.get_target()
|
||||
if path:
|
||||
target_path = path + '.' + field_name
|
||||
else:
|
||||
target_path = field_name
|
||||
_get_access_models(Target, names, model2field, target_path)
|
||||
return names, model2field
|
||||
|
||||
|
||||
class RuleGroup(ModelSQL, ModelView):
|
||||
"Rule group"
|
||||
__name__ = 'ir.rule.group'
|
||||
@@ -179,24 +201,8 @@ class Rule(ModelSQL, ModelView):
|
||||
|
||||
groups = User.get_groups()
|
||||
|
||||
model_names = []
|
||||
model2field = defaultdict(list)
|
||||
|
||||
def update_model_names(Model, path=None):
|
||||
if Model.__name__ in model_names:
|
||||
return
|
||||
model_names.append(Model.__name__)
|
||||
if path:
|
||||
model2field[Model.__name__].append(path)
|
||||
for field_name in Model.__access__:
|
||||
field = getattr(Model, field_name)
|
||||
Target = field.get_target()
|
||||
if path:
|
||||
target_path = path + '.' + field_name
|
||||
else:
|
||||
target_path = field_name
|
||||
update_model_names(Target, target_path)
|
||||
update_model_names(pool.get(model_name))
|
||||
model_names, model2field = _get_access_models(pool.get(model_name))
|
||||
model_names = list(model_names)
|
||||
|
||||
cursor = transaction.connection.cursor()
|
||||
# root user above constraint
|
||||
@@ -258,6 +264,7 @@ class Rule(ModelSQL, ModelView):
|
||||
|
||||
@classmethod
|
||||
def domain_get(cls, model_name, mode='read'):
|
||||
pool = Pool()
|
||||
transaction = Transaction()
|
||||
# root user above constraint
|
||||
if transaction.user == 0 or not transaction.check_access:
|
||||
@@ -265,7 +272,11 @@ class Rule(ModelSQL, ModelView):
|
||||
|
||||
assert mode in cls.modes
|
||||
|
||||
key = (model_name, mode) + cls._get_cache_key(model_name)
|
||||
model_names, _ = _get_access_models(pool.get(model_name))
|
||||
|
||||
key = (model_name, mode)
|
||||
for m_name in sorted(model_names):
|
||||
key += cls._get_cache_key(m_name)
|
||||
domain = cls._domain_get_cache.get(key, False)
|
||||
if domain is not False:
|
||||
return domain
|
||||
|
||||
Reference in new issue
Block a user