Add ModelFieldAccess.get_access
review598002
This commit is contained in:
1 parent
db7a805991
commit
cf0636e095
3 files changed
+61
-36
No files matched your search
+49
-27
@@ -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:
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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():
|
||||
|
||||
Reference in new issue
Block a user