diff options
Diffstat (limited to 'openerp/addons/base/ir/ir_translation.py')
| -rw-r--r-- | openerp/addons/base/ir/ir_translation.py | 60 |
1 files changed, 48 insertions, 12 deletions
diff --git a/openerp/addons/base/ir/ir_translation.py b/openerp/addons/base/ir/ir_translation.py index 2ce4570329b..92bfd049b81 100644 --- a/openerp/addons/base/ir/ir_translation.py +++ b/openerp/addons/base/ir/ir_translation.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. +from collections import defaultdict from difflib import get_close_matches import logging @@ -192,7 +193,9 @@ class ir_translation(osv.osv): model = self.pool.get(model_name) if model is None: continue - field = model._fields[field_name] + field = model._fields.get(field_name) + if field is None: + continue if not callable(field.translate): # Pass context without lang, need to read real stored field, not translation context_no_lang = dict(context, lang=None) @@ -496,6 +499,40 @@ class ir_translation(osv.osv): fields = self.env['ir.model.fields'].search([('model', '=', model_name)]) return {field.name: field.help for field in fields} + @api.multi + def check(self, mode): + """ Check access rights of operation ``mode`` on ``self`` for the + current user. Raise an AccessError in case conditions are not met. + """ + if self.env.user._is_admin(): + return + + # collect translated field records (model_ids) and other translations + trans_ids = [] + model_ids = defaultdict(list) + model_fields = defaultdict(list) + for trans in self: + if trans.type == 'model': + mname, fname = trans.name.split(',') + model_ids[mname].append(trans.res_id) + model_fields[mname].append(fname) + else: + trans_ids.append(trans.id) + + # check for regular access rights on other translations + if trans_ids: + records = self.browse(trans_ids) + records.check_access_rights(mode) + records.check_access_rule(mode) + + # check for read/write access on translated field records + fmode = 'read' if mode == 'read' else 'write' + for mname, ids in model_ids.iteritems(): + records = self.env[mname].browse(ids) + records.check_access_rights(fmode) + records.check_field_access_rights(fmode, model_fields[mname]) + records.check_access_rule(fmode) + @api.model def create(self, vals): if vals.get('type') == 'model' and vals.get('value'): @@ -503,7 +540,8 @@ class ir_translation(osv.osv): mname, fname = vals['name'].split(',') field = self.env[mname]._fields[fname] vals['value'] = field.check_trans_value(vals['value']) - record = super(ir_translation, self).create(vals) + record = super(ir_translation, self.sudo()).create(vals).with_env(self.env) + record.check('create') self.clear_caches() return record @@ -520,19 +558,17 @@ class ir_translation(osv.osv): vals['value'] = field.check_trans_value(vals['value']) elif vals.get('src') or not vals.get('value', True): vals.setdefault('state', 'to_translate') - result = super(ir_translation, self).write(vals) + self.check('write') + result = super(ir_translation, self.sudo()).write(vals) + self.check('write') self.clear_caches() return result - def unlink(self, cursor, user, ids, context=None): - if context is None: - context = {} - if isinstance(ids, (int, long)): - ids = [ids] - + @api.multi + def unlink(self): + self.check('unlink') self.clear_caches() - result = super(ir_translation, self).unlink(cursor, user, ids, context=context) - return result + return super(ir_translation, self.sudo()).unlink() @api.model def insert_missing(self, field, records): @@ -566,7 +602,7 @@ class ir_translation(osv.osv): FROM res_lang l WHERE l.active AND l.code != 'en_US' AND NOT EXISTS ( SELECT 1 FROM ir_translation - WHERE lang=l.code AND type='model' AND name=%(name)s AND res_id=%(res_id)s AND module=%(module)s + WHERE lang=l.code AND type='model' AND name=%(name)s AND res_id=%(res_id)s ); UPDATE ir_translation SET src=%(src)s WHERE type='model' AND name=%(name)s AND res_id=%(res_id)s AND module=%(module)s; |
