Check relation access in fields_get and for default fields in read

issue3750
review4261002
This commit is contained in:
Cédric Krier committed 2014-03-15 11:01:14 +01:00
1 parent 4306811fe6
commit f72b983c0f
5 files changed
+53 -32

No files matched your search

+32
View File
@@ -526,6 +526,38 @@ class ModelAccess(ModelSQL, ModelView):
return False
return True
@classmethod
def check_relation(cls, model_name, field_name, mode='read'):
'Check access to relation field for model_name and mode'
pool = Pool()
Model = pool.get(model_name)
field = getattr(Model, field_name)
if field._type in ('one2many', 'many2one'):
return cls.check(field.model_name, mode=mode,
raise_exception=False)
elif field._type in ('many2many', 'one2one'):
if (field.target
and not cls.check(field.target, mode=mode,
raise_exception=False)):
return False
elif (field.relation_name
and not cls.check(field.relation_name, mode=mode,
raise_exception=False)):
return False
else:
return True
elif field._type == 'reference':
selection = field.selection
if isinstance(selection, basestring):
selection = getattr(Model, field.selection)()
for model_name, _ in selection:
if not cls.check(model_name, mode=mode,
raise_exception=False):
return False
return True
else:
return True
@classmethod
def write(cls, accesses, values, *args):
super(ModelAccess, cls).write(accesses, values, *args)
+5 -2
View File
@@ -226,6 +226,7 @@ class Model(WarningErrorMixin, URLMixin, PoolBase):
pool = Pool()
Translation = pool.get('ir.translation')
FieldAccess = pool.get('ir.model.field.access')
ModelAccess = pool.get('ir.model.access')
#Add translation to cache
language = Transaction().language
@@ -389,11 +390,13 @@ class Model(WarningErrorMixin, URLMixin, PoolBase):
if attr in res[field]:
res[field][attr] = encoder.encode(res[field][attr])
if fields_names:
for i in res.keys():
# filter out fields which aren't in the fields_names list
for i in res.keys():
if fields_names:
if i not in fields_names:
del res[i]
elif not ModelAccess.check_relation(cls.__name__, i, mode='read'):
del res[i]
return res
def on_change_with(self, fieldnames):
+7 -3
View File
@@ -417,12 +417,16 @@ class ModelSQL(ModelStorage):
pool = Pool()
Rule = pool.get('ir.rule')
Translation = pool.get('ir.translation')
ModelAccess = pool.get('ir.model.access')
if not fields_names:
fields_names = []
for field_name in cls._fields.keys():
if ModelAccess.check_relation(cls.__name__, field_name,
mode='read'):
fields_names.append(field_name)
super(ModelSQL, cls).read(ids, fields_names=fields_names)
cursor = Transaction().cursor
if not fields_names:
fields_names = cls._fields.keys()
if not ids:
return []
+8 -2
View File
@@ -120,9 +120,15 @@ class ModelStorage(Model):
ModelAccess = pool.get('ir.model.access')
ModelFieldAccess = pool.get('ir.model.field.access')
if not fields_names:
fields_names = []
for field_name in cls._fields.keys():
if ModelAccess.check_relation(cls.__name__, field_name,
mode='read'):
fields_names.append(field_name)
ModelAccess.check(cls.__name__, 'read')
ModelFieldAccess.check(cls.__name__,
fields_names or cls._fields.keys(), 'read')
ModelFieldAccess.check(cls.__name__, fields_names, 'read')
return []
@classmethod
+1 -25
View File
@@ -295,33 +295,9 @@ class ModelView(Model):
fields_to_remove = list(x for x, y in fread_accesses.iteritems()
if not y)
def check_relation(model, field):
if field._type in ('one2many', 'many2one'):
if not ModelAccess.check(field.model_name, mode='read',
raise_exception=False):
return False
if field._type in ('many2many', 'one2one'):
if (field.target
and not ModelAccess.check(field.target, mode='read',
raise_exception=False)):
return False
elif (field.relation_name
and not ModelAccess.check(field.relation_name,
mode='read', raise_exception=False)):
return False
if field._type == 'reference':
selection = field.selection
if isinstance(selection, basestring):
selection = getattr(model, field.selection)()
for model_name, _ in selection:
if not ModelAccess.check(model_name, mode='read',
raise_exception=False):
return False
return True
# Find relation field without read access
for name, field in cls._fields.iteritems():
if not check_relation(cls, field):
if not ModelAccess.check_relation(cls.__name__, name, mode='read'):
fields_to_remove.append(name)
for name, field in cls._fields.iteritems():