[IMP] ir_translation: make access rights depend on translated record

A translation of a field value for a given record can only be created/updated/
deleted if the current user has access rights for updating the record.

Access rights on translations are restricted to the group "Employee".  Those
still need create/write/delete access, in order to be able to edit records in
the user interface.  Other users (portal, etc.) simply have no explicit access
rights at all on translations.
This commit is contained in:
Raphael Collet
2015-12-02 10:12:16 +01:00
parent 1e9ce28f7b
commit 2d6fd5ea65
2 changed files with 45 additions and 11 deletions
+44 -10
View File
@@ -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
@@ -496,6 +497,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 +538,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 +556,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):
@@ -28,7 +28,7 @@
"access_ir_sequence_group_system","ir_sequence group_system","model_ir_sequence","group_system",1,1,1,1
"access_ir_sequence_date_range_group_user","ir_sequence_date_range group_user","model_ir_sequence_date_range","group_user",1,0,0,0
"access_ir_sequence_date_range_group_system","ir_sequence_date_range group_system","model_ir_sequence_date_range","group_system",1,1,1,1
"access_ir_translation_all","ir_translation all","model_ir_translation",,1,1,1,1
"access_ir_translation_all","ir_translation all","model_ir_translation","group_user",1,1,1,1
"access_ir_translation_group_system","ir_translation group_system","model_ir_translation","group_system",1,1,1,1
"access_ir_ui_menu_group_user","ir_ui_menu group_user","model_ir_ui_menu",base.group_user,1,0,0,0
"access_ir_ui_menu_group_system","ir_ui_menu group_system","model_ir_ui_menu","group_system",1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
28 access_ir_sequence_group_system ir_sequence group_system model_ir_sequence group_system 1 1 1 1
29 access_ir_sequence_date_range_group_user ir_sequence_date_range group_user model_ir_sequence_date_range group_user 1 0 0 0
30 access_ir_sequence_date_range_group_system ir_sequence_date_range group_system model_ir_sequence_date_range group_system 1 1 1 1
31 access_ir_translation_all ir_translation all model_ir_translation group_user 1 1 1 1
32 access_ir_translation_group_system ir_translation group_system model_ir_translation group_system 1 1 1 1
33 access_ir_ui_menu_group_user ir_ui_menu group_user model_ir_ui_menu base.group_user 1 0 0 0
34 access_ir_ui_menu_group_system ir_ui_menu group_system model_ir_ui_menu group_system 1 1 1 1