[IMP] osv_memory: disabled regular ir_model_access access rights and switched to per-user access only. also did some cleanup
bzr revid: odo@openerp.com-20100624155602-noiat5i91uyeyy5t
This commit is contained in:
parent
ef40f49056
commit
09297baccf
|
@ -33,8 +33,6 @@ import pooler
|
|||
|
||||
|
||||
import netsvc
|
||||
from osv import fields
|
||||
import addons
|
||||
|
||||
import zipfile
|
||||
import release
|
||||
|
@ -303,7 +301,7 @@ def load_information_from_description_file(module):
|
|||
:param module: The name of the module (sale, purchase, ...)
|
||||
"""
|
||||
for filename in ['__openerp__.py', '__terp__.py']:
|
||||
description_file = addons.get_module_resource(module, filename)
|
||||
description_file = get_module_resource(module, filename)
|
||||
if os.path.isfile(description_file):
|
||||
return eval(tools.file_open(description_file).read())
|
||||
|
||||
|
@ -823,7 +821,7 @@ def load_modules(db, force_demo=False, status=None, update_module=False):
|
|||
while True:
|
||||
loop_guardrail += 1
|
||||
if loop_guardrail > 100:
|
||||
raise ProgrammingError()
|
||||
raise ValueError('Possible recursive module tree detected, aborting.')
|
||||
cr.execute("SELECT name from ir_module_module WHERE state IN %s" ,(tuple(STATES_TO_LOAD),))
|
||||
|
||||
module_list = [name for (name,) in cr.fetchall() if name not in graph]
|
||||
|
@ -840,9 +838,19 @@ def load_modules(db, force_demo=False, status=None, update_module=False):
|
|||
has_updates = has_updates or r
|
||||
|
||||
if has_updates:
|
||||
cr.execute("""select model,name from ir_model where id NOT IN (select model_id from ir_model_access)""")
|
||||
cr.execute("""select model,name from ir_model where id NOT IN (select distinct model_id from ir_model_access)""")
|
||||
for (model, name) in cr.fetchall():
|
||||
logger.notifyChannel('init', netsvc.LOG_WARNING, 'object %s (%s) has no access rules!' % (model, name))
|
||||
model_obj = pool.get(model)
|
||||
if not isinstance(model_obj, osv.osv.osv_memory):
|
||||
logger.notifyChannel('init', netsvc.LOG_WARNING, 'object %s (%s) has no access rules!' % (model, name))
|
||||
|
||||
# Temporary warning while we remove access rights on osv_memory objects, as they have
|
||||
# been replaced by owner-only access rights
|
||||
cr.execute("""select distinct mod.model, mod.name from ir_model_access acc, ir_model mod where acc.model_id = mod.id""")
|
||||
for (model, name) in cr.fetchall():
|
||||
model_obj = pool.get(model)
|
||||
if isinstance(model_obj, osv.osv.osv_memory):
|
||||
logger.notifyChannel('init', netsvc.LOG_WARNING, 'In-memory object %s (%s) should not have explicit access rules!' % (model, name))
|
||||
|
||||
cr.execute("SELECT model from ir_model")
|
||||
for (model,) in cr.fetchall():
|
||||
|
|
|
@ -814,6 +814,7 @@
|
|||
<page string="Object">
|
||||
<field name="name" select="1"/>
|
||||
<field name="model" select="1"/>
|
||||
<field name="osv_memory" select="1"/>
|
||||
<separator colspan="4" string="Fields"/>
|
||||
<field colspan="4" context="{'manual':True}" name="field_id" nolabel="1">
|
||||
<tree string="Fields Description">
|
||||
|
|
|
@ -44,6 +44,25 @@ class ir_model(osv.osv):
|
|||
_name = 'ir.model'
|
||||
_description = "Objects"
|
||||
_rec_name = 'name'
|
||||
|
||||
def _is_osv_memory(self, cr, uid, ids, field_name, arg, context=None):
|
||||
models = self.browse(cr, uid, ids, context=context)
|
||||
res = dict.fromkeys(ids)
|
||||
for model in models:
|
||||
res[model.id] = isinstance(self.pool.get(model.model), osv.osv_memory)
|
||||
return res
|
||||
|
||||
def _search_osv_memory(self, cr, uid, model, name, domain, context=None):
|
||||
if not domain:
|
||||
return []
|
||||
field, operator, value = domain[0]
|
||||
if operator not in ['=', '!=']:
|
||||
raise osv.except_osv('Invalid search criterions','The osv_memory field can only be compared with = and != operator.')
|
||||
value = bool(value) if operator == '=' else not bool(value)
|
||||
all_model_ids = self.search(cr, uid, [], context=context)
|
||||
is_osv_mem = self._is_osv_memory(cr, uid, all_model_ids, 'osv_memory', arg=None, context=context)
|
||||
return [('id', 'in', [id for id in is_osv_mem if bool(is_osv_mem[id]) == value])]
|
||||
|
||||
_columns = {
|
||||
'name': fields.char('Object Name', size=64, translate=True, required=True),
|
||||
'model': fields.char('Object', size=64, required=True, select=1),
|
||||
|
@ -51,6 +70,9 @@ class ir_model(osv.osv):
|
|||
'field_id': fields.one2many('ir.model.fields', 'model_id', 'Fields', required=True),
|
||||
'state': fields.selection([('manual','Custom Object'),('base','Base Object')],'Manually Created',readonly=True),
|
||||
'access_ids': fields.one2many('ir.model.access', 'model_id', 'Access'),
|
||||
'osv_memory': fields.function(_is_osv_memory, method=True, string='In-memory model', type='boolean',
|
||||
fnct_search=_search_osv_memory,
|
||||
help="Indicates whether this object model lives in memory only, i.e. is not persisted (osv.osv_memory)")
|
||||
}
|
||||
_defaults = {
|
||||
'model': lambda *a: 'x_',
|
||||
|
@ -81,7 +103,7 @@ class ir_model(osv.osv):
|
|||
|
||||
def unlink(self, cr, user, ids, context=None):
|
||||
for model in self.browse(cr, user, ids, context):
|
||||
if model.state <> 'manual':
|
||||
if model.state != 'manual':
|
||||
raise except_orm(_('Error'), _("You can not remove the model '%s' !") %(model.name,))
|
||||
res = super(ir_model, self).unlink(cr, user, ids, context)
|
||||
pooler.restart_pool(cr.dbname)
|
||||
|
@ -300,7 +322,7 @@ class ir_model_access(osv.osv):
|
|||
_name = 'ir.model.access'
|
||||
_columns = {
|
||||
'name': fields.char('Name', size=64, required=True),
|
||||
'model_id': fields.many2one('ir.model', 'Object', required=True),
|
||||
'model_id': fields.many2one('ir.model', 'Object', required=True, domain=[('osv_memory','=', False)]),
|
||||
'group_id': fields.many2one('res.groups', 'Group', ondelete='cascade'),
|
||||
'perm_read': fields.boolean('Read Access'),
|
||||
'perm_write': fields.boolean('Write Access'),
|
||||
|
|
|
@ -76,6 +76,9 @@ class expression(object):
|
|||
self.__main_table = None # 'root' table. set by parse()
|
||||
self.__DUMMY_LEAF = (1, '=', 1) # a dummy leaf that must not be parsed or sql generated
|
||||
|
||||
@property
|
||||
def exp(self):
|
||||
return self.__exp[:]
|
||||
|
||||
def parse(self, cr, uid, table, context):
|
||||
""" transform the leafs of the expression """
|
||||
|
|
|
@ -1754,6 +1754,10 @@ class orm_memory(orm_template):
|
|||
self.check_id = 0
|
||||
cr.execute('delete from wkf_instance where res_type=%s', (self._name,))
|
||||
|
||||
def _check_access(self, uid, object_id, mode):
|
||||
if uid != 1 and self.datas[object_id]['internal.create_uid'] != uid:
|
||||
raise except_orm(_('AccessError'), '%s access is only allowed on your own records for osv_memory objects' % mode.capitalize())
|
||||
|
||||
def vaccum(self, cr, uid):
|
||||
self.check_id += 1
|
||||
if self.check_id % self._check_time:
|
||||
|
@ -1774,7 +1778,6 @@ class orm_memory(orm_template):
|
|||
def read(self, cr, user, ids, fields_to_read=None, context=None, load='_classic_read'):
|
||||
if not context:
|
||||
context = {}
|
||||
self.pool.get('ir.model.access').check(cr, user, self._name, 'read', context=context)
|
||||
if not fields_to_read:
|
||||
fields_to_read = self._columns.keys()
|
||||
result = []
|
||||
|
@ -1785,8 +1788,10 @@ class orm_memory(orm_template):
|
|||
for id in ids:
|
||||
r = {'id': id}
|
||||
for f in fields_to_read:
|
||||
if id in self.datas:
|
||||
r[f] = self.datas[id].get(f, False)
|
||||
record = self.datas.get(id)
|
||||
if record:
|
||||
self._check_access(user, id, 'read')
|
||||
r[f] = record.get(f, False)
|
||||
if r[f] and isinstance(self._columns[f], fields.binary) and context.get('bin_size', False):
|
||||
r[f] = len(r[f])
|
||||
result.append(r)
|
||||
|
@ -1804,7 +1809,6 @@ class orm_memory(orm_template):
|
|||
def write(self, cr, user, ids, vals, context=None):
|
||||
if not ids:
|
||||
return True
|
||||
self.pool.get('ir.model.access').check(cr, user, self._name, 'write', context=context)
|
||||
vals2 = {}
|
||||
upd_todo = []
|
||||
for field in vals:
|
||||
|
@ -1812,18 +1816,18 @@ class orm_memory(orm_template):
|
|||
vals2[field] = vals[field]
|
||||
else:
|
||||
upd_todo.append(field)
|
||||
for id_new in ids:
|
||||
self.datas[id_new].update(vals2)
|
||||
self.datas[id_new]['internal.date_access'] = time.time()
|
||||
for object_id in ids:
|
||||
self._check_access(user, object_id, mode='write')
|
||||
self.datas[object_id].update(vals2)
|
||||
self.datas[object_id]['internal.date_access'] = time.time()
|
||||
for field in upd_todo:
|
||||
self._columns[field].set_memory(cr, self, id_new, field, vals[field], user, context)
|
||||
self._validate(cr, user, [id_new], context)
|
||||
self._columns[field].set_memory(cr, self, object_id, field, vals[field], user, context)
|
||||
self._validate(cr, user, [object_id], context)
|
||||
wf_service = netsvc.LocalService("workflow")
|
||||
wf_service.trg_write(user, self._name, id_new, cr)
|
||||
return id_new
|
||||
wf_service.trg_write(user, self._name, object_id, cr)
|
||||
return object_id
|
||||
|
||||
def create(self, cr, user, vals, context=None):
|
||||
self.pool.get('ir.model.access').check(cr, user, self._name, 'create', context=context)
|
||||
self.vaccum(cr, user)
|
||||
self.next_id += 1
|
||||
id_new = self.next_id
|
||||
|
@ -1842,6 +1846,7 @@ class orm_memory(orm_template):
|
|||
upd_todo.append(field)
|
||||
self.datas[id_new] = vals2
|
||||
self.datas[id_new]['internal.date_access'] = time.time()
|
||||
self.datas[id_new]['internal.create_uid'] = user
|
||||
|
||||
for field in upd_todo:
|
||||
self._columns[field].set_memory(cr, self, id_new, field, vals[field], user, context)
|
||||
|
@ -1936,13 +1941,19 @@ class orm_memory(orm_template):
|
|||
import expression
|
||||
e = expression.expression(args)
|
||||
e.parse(cr, user, self, context)
|
||||
res=e.__dict__['_expression__exp']
|
||||
res = e.exp
|
||||
return res or []
|
||||
|
||||
def search(self, cr, user, args, offset=0, limit=None, order=None,
|
||||
context=None, count=False):
|
||||
if not context:
|
||||
context = {}
|
||||
|
||||
# implicit filter on current user
|
||||
if not args:
|
||||
args = []
|
||||
args.insert(0, ('internal.create_uid', '=', user))
|
||||
|
||||
result = self._where_calc(cr, user, args, context=context)
|
||||
if result==[]:
|
||||
return self.datas.keys()
|
||||
|
@ -1954,25 +1965,20 @@ class orm_memory(orm_template):
|
|||
if result:
|
||||
for id, data in self.datas.items():
|
||||
counter=counter+1
|
||||
data['id'] = id
|
||||
if limit and (counter >int(limit)):
|
||||
data['id'] = id
|
||||
if limit and (counter > int(limit)):
|
||||
break
|
||||
f = True
|
||||
for arg in result:
|
||||
if arg[1] =='=':
|
||||
val =eval('data[arg[0]]'+'==' +' arg[2]', locals())
|
||||
elif arg[1] in ['<','>','in','not in','<=','>=','<>']:
|
||||
val =eval('data[arg[0]]'+arg[1] +' arg[2]', locals())
|
||||
elif arg[1] in ['ilike']:
|
||||
if str(data[arg[0]]).find(str(arg[2]))!=-1:
|
||||
val= True
|
||||
else:
|
||||
val=False
|
||||
if arg[1] == '=':
|
||||
val = eval('data[arg[0]]'+'==' +' arg[2]', locals())
|
||||
elif arg[1] in ['<','>','in','not in','<=','>=','<>']:
|
||||
val = eval('data[arg[0]]'+arg[1] +' arg[2]', locals())
|
||||
elif arg[1] in ['ilike']:
|
||||
val = (str(data[arg[0]]).find(str(arg[2]))!=-1)
|
||||
|
||||
f = f and val
|
||||
|
||||
if f and val:
|
||||
f = True
|
||||
else:
|
||||
f = False
|
||||
if f:
|
||||
res.append(id)
|
||||
if count:
|
||||
|
@ -1980,20 +1986,22 @@ class orm_memory(orm_template):
|
|||
return res or []
|
||||
|
||||
def unlink(self, cr, uid, ids, context=None):
|
||||
self.pool.get('ir.model.access').check(cr, uid, self._name, 'unlink', context=context)
|
||||
for id in ids:
|
||||
if id in self.datas:
|
||||
del self.datas[id]
|
||||
self._check_access(uid, id, 'unlink')
|
||||
self.datas.pop(id, None)
|
||||
if len(ids):
|
||||
cr.execute('delete from wkf_instance where res_type=%s and res_id IN %s', (self._name, tuple(ids)))
|
||||
return True
|
||||
|
||||
def perm_read(self, cr, user, ids, context=None, details=True):
|
||||
result = []
|
||||
credentials = self.pool.get('res.users').name_get(cr, user, [user])[0]
|
||||
create_date = time.strftime('%Y-%m-%d %H:%M:%S')
|
||||
for id in ids:
|
||||
self._check_access(user, id, 'read')
|
||||
result.append({
|
||||
'create_uid': (user, 'Root'),
|
||||
'create_date': time.strftime('%Y-%m-%d %H:%M:%S'),
|
||||
'create_uid': credentials,
|
||||
'create_date': create_date,
|
||||
'write_uid': False,
|
||||
'write_date': False,
|
||||
'id': id
|
||||
|
|
Loading…
Reference in New Issue