[FIX] base: delete orphan translations without access right errors
Deleting an orphan translation is mostly impossible, since it requires 'write' access on the corresponding records, and checking access rights fails because the records no longer exist! Simply enable operations on orphan translations by ignoring the corresponding records that do not exist. And make sure that the patch does not allow to create orphan translations. closes odoo/odoo#86869 X-original-commit: 454aa2587dcda2582ae58650019669ff0e8baa2c Signed-off-by: Raphael Collet <rco@odoo.com> Co-authored-by: Martin Trigaux <mat@odoo.com>
This commit is contained in:
co-authored by
Martin Trigaux
parent
3c520d70c6
commit
c490f6fef0
@@ -521,9 +521,13 @@ class IrTranslation(models.Model):
|
||||
# check for read/write access on translated field records
|
||||
fmode = 'read' if mode == 'read' else 'write'
|
||||
for mname, ids in model_ids.items():
|
||||
records = self.env[mname].browse(ids)
|
||||
records = self.env[mname].browse(ids).exists()
|
||||
records.check_access_rights(fmode)
|
||||
records.check_field_access_rights(fmode, model_fields[mname])
|
||||
if mode == 'create' and set(records._ids) != set(ids):
|
||||
raise ValidationError(_("Creating translation on non existing records"))
|
||||
if not records:
|
||||
continue
|
||||
records.check_access_rule(fmode)
|
||||
|
||||
@api.constrains('type', 'name', 'value')
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
from odoo.exceptions import AccessError, ValidationError
|
||||
from odoo.tools import mute_logger
|
||||
from odoo.tools.translate import quote, unquote, xml_translate, html_translate
|
||||
from odoo.tests.common import TransactionCase, BaseCase
|
||||
from odoo.tests.common import TransactionCase, BaseCase, new_test_user
|
||||
from psycopg2 import IntegrityError
|
||||
|
||||
|
||||
@@ -570,6 +571,56 @@ class TestTranslationWrite(TransactionCase):
|
||||
"Did not fallback to source when reset"
|
||||
)
|
||||
|
||||
def test_orphan(self):
|
||||
""" What happens with orphan translations. """
|
||||
self.env['res.lang']._activate_lang('fr_FR')
|
||||
|
||||
# create a user with access rights on partner categories
|
||||
user = new_test_user(self.env, 'deleter')
|
||||
group = self.env.ref('base.group_partner_manager')
|
||||
user.groups_id = [(4, group.id)]
|
||||
|
||||
# this access rule triggers a MissingError
|
||||
self.env['ir.rule'].create({
|
||||
'model_id': self.env['ir.model']._get_id('res.partner.category'),
|
||||
'groups': [(4, group.id)],
|
||||
'domain_force': "[('name', 'ilike', 'e')]",
|
||||
})
|
||||
|
||||
# create a translation, and delete the record from the database
|
||||
translation = self.env['ir.translation'].create({
|
||||
'type': 'model',
|
||||
'name': 'res.partner.category,name',
|
||||
'lang': 'fr_FR',
|
||||
'res_id': self.category.id,
|
||||
'src': 'Reblochon',
|
||||
'value': 'Parfum Exquis',
|
||||
'state': 'translated',
|
||||
})
|
||||
translation.flush()
|
||||
translation.invalidate_cache()
|
||||
self.cr.execute("DELETE FROM res_partner_category WHERE id=%s", [self.category.id])
|
||||
|
||||
# deleting the translation should be possible, provided the user has
|
||||
# access rights on the translation's model
|
||||
user0 = new_test_user(self.env, 'cannot modify category')
|
||||
with self.assertRaises(AccessError):
|
||||
translation.with_user(user0).unlink()
|
||||
|
||||
translation.with_user(user).unlink()
|
||||
|
||||
# however, creating orphan translations should not be possible
|
||||
with self.assertRaises(ValidationError):
|
||||
translation.with_user(user).create({
|
||||
'type': 'model',
|
||||
'name': 'res.partner.category,name',
|
||||
'lang': 'fr_FR',
|
||||
'res_id': self.category.id,
|
||||
'src': 'Reblochon',
|
||||
'value': 'Parfum Exquis',
|
||||
'state': 'translated',
|
||||
})
|
||||
|
||||
def test_field_selection(self):
|
||||
""" Test translations of field selections. """
|
||||
field = self.env['ir.model']._fields['state']
|
||||
|
||||
Reference in New Issue
Block a user