Add ModelFieldAccess.get_access

review598002
This commit is contained in:
Cédric Krier committed 2012-11-28 22:42:51 +01:00
1 parent db7a805991
commit cf0636e095
3 files changed
+61 -36

No files matched your search

+49 -27
View File
@@ -434,6 +434,53 @@ class ModelFieldAccess(ModelSQL, ModelView):
def default_perm_delete():
return True
@classmethod
def get_access(cls, models):
'Return fields access for models'
pool = Pool()
Model = pool.get('ir.model')
ModelField = pool.get('ir.model.field')
UserGroup = pool.get('res.user-res.group')
cursor = Transaction().cursor
user = Transaction().user
accesses = {}
for model in models:
maccesses = cls._get_access_cache.get((user, model))
if maccesses is None:
break
accesses[model] = maccesses
else:
return accesses
default = {}
accesses = dict((m, default) for m in models)
cursor.execute(('SELECT '
'm.model, '
'f.name, '
'MAX(CASE WHEN a.perm_read THEN 1 ELSE 0 END), '
'MAX(CASE WHEN a.perm_write THEN 1 ELSE 0 END), '
'MAX(CASE WHEN a.perm_create THEN 1 ELSE 0 END), '
'MAX(CASE WHEN a.perm_delete THEN 1 ELSE 0 END) '
'FROM "%s" AS a '
'JOIN "%s" AS f '
'ON (a.field = f.id) '
'JOIN "%s" AS m '
'ON (f.model = m.id) '
'LEFT JOIN "%s" AS gu '
'ON (gu."group" = a."group") '
'WHERE m.model IN (' + ','.join(('%%s',) * len(models)) + ') '
'AND (gu."user" = %%s OR a."group" IS NULL) '
'GROUP BY m.model, f.name')
% (cls._table, ModelField._table,
Model._table, UserGroup._table),
list(models) + [Transaction().user])
for m, f, r, w, c, d in cursor.fetchall():
accesses[m][f] = {'read': r, 'write': w, 'create': c, 'delete': d}
for model, maccesses in accesses.iteritems():
cls._get_access_cache.set((user, model), maccesses)
return accesses
@classmethod
def check(cls, model_name, fields, mode='read', raise_exception=True,
access=False):
@@ -447,33 +494,8 @@ class ModelFieldAccess(ModelSQL, ModelView):
return dict((x, True) for x in fields)
return True
pool = Pool()
Model = pool.get('ir.model')
ModelField = pool.get('ir.model.field')
UserGroup = pool.get('res.user-res.group')
cursor = Transaction().cursor
key = (model_name, mode, access, Transaction().user)
accesses = cls._get_access_cache.get(key)
if accesses is None:
cursor.execute('SELECT f.name, '
'MAX(CASE WHEN a.perm_%s THEN 1 ELSE 0 END) '
'FROM "%s" AS a '
'JOIN "%s" AS f '
'ON (a.field = f.id) '
'JOIN "%s" AS m '
'ON (f.model = m.id) '
'LEFT JOIN "%s" AS gu '
'ON (gu."group" = a."group") '
'WHERE m.model = %%s '
'AND (gu."user" = %%s OR a."group" IS NULL) '
'GROUP BY f.name'
% (mode, cls._table, ModelField._table,
Model._table, UserGroup._table), (model_name,
Transaction().user))
accesses = dict(cursor.fetchall())
cls._get_access_cache.set(key, accesses)
accesses = dict((f, a[mode])
for f, a in cls.get_access([model_name])[model_name].iteritems())
if access:
return accesses
for field in fields:
+6 -9
View File
@@ -451,12 +451,7 @@ class Model(WarningErrorMixin, URLMixin):
encoder = PYSONEncoder()
fwrite_accesses = FieldAccess.check(cls.__name__, fields_names or
cls._fields.keys(), 'write', access=True)
fcreate_accesses = FieldAccess.check(cls.__name__, fields_names or
cls._fields.keys(), 'create', access=True)
fdelete_accesses = FieldAccess.check(cls.__name__, fields_names or
cls._fields.keys(), 'delete', access=True)
accesses = FieldAccess.get_access([cls.__name__])[cls.__name__]
for field in (x for x in cls._fields.keys()
if ((not fields_names) or x in fields_names)):
res[field] = {
@@ -484,7 +479,7 @@ class Model(WarningErrorMixin, URLMixin):
if getattr(cls._fields[field], arg, None) is not None:
res[field][arg] = copy.copy(getattr(cls._fields[field],
arg))
if not fwrite_accesses.get(field, True):
if not accesses.get(field, {}).get('read', True):
res[field]['readonly'] = True
if res[field].get('states') and \
'readonly' in res[field]['states']:
@@ -554,8 +549,10 @@ class Model(WarningErrorMixin, URLMixin):
res[field]['relation'] = relation
res[field]['domain'] = copy.copy(cls._fields[field].domain)
res[field]['context'] = copy.copy(cls._fields[field].context)
res[field]['create'] = fcreate_accesses.get(field, True)
res[field]['delete'] = fdelete_accesses.get(field, True)
res[field]['create'] = accesses.get(field, {}).get('create',
True)
res[field]['delete'] = accesses.get(field, {}).get('delete',
True)
if res[field]['type'] == 'one2many' \
and hasattr(cls._fields[field], 'field'):
res[field]['relation_field'] = copy.copy(
+6
View File
@@ -101,6 +101,7 @@ class ModelAccessTestCase(unittest.TestCase):
self.test_access.read([test.id])
transaction.cursor.rollback()
self.model_access._get_access_cache.clear()
def test0020perm_write(self):
'''
@@ -182,6 +183,7 @@ class ModelAccessTestCase(unittest.TestCase):
self.test_access.write([test], {})
transaction.cursor.rollback()
self.model_access._get_access_cache.clear()
def test0030perm_create(self):
'''
@@ -262,6 +264,7 @@ class ModelAccessTestCase(unittest.TestCase):
self.test_access.create({})
transaction.cursor.rollback()
self.model_access._get_access_cache.clear()
def test0040perm_delete(self):
'''
@@ -347,6 +350,7 @@ class ModelAccessTestCase(unittest.TestCase):
self.test_access.delete([tests.pop()])
transaction.cursor.rollback()
self.model_access._get_access_cache.clear()
class ModelFieldAccessTestCase(unittest.TestCase):
@@ -571,6 +575,7 @@ class ModelFieldAccessTestCase(unittest.TestCase):
test = self.test_access(test.id)
transaction.cursor.rollback()
self.field_access._get_access_cache.clear()
def test0010perm_write(self):
'''
@@ -778,6 +783,7 @@ class ModelFieldAccessTestCase(unittest.TestCase):
})
transaction.cursor.rollback()
self.field_access._get_access_cache.clear()
def suite():