import netsvc
-from osv import fields
-import addons
import zipfile
import release
: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())
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]
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():
_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),
'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_',
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)
_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'),
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:
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 = []
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)
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:
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
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)
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()
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 f and val:
- f = True
- else:
- f = 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:
res.append(id)
if count:
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