Commit 50b6d987 authored by Cédric Krier's avatar Cédric Krier
Browse files

Raise error message with record name and field in check_xml_record

Closes #11867
parent 013e449f7970
Pipeline #60251 passed with stages
in 15 seconds
......@@ -87,7 +87,7 @@
@classmethod
def check_xml_record(cls, records, values):
return True
pass
@classmethod
def search_global(cls, text):
......@@ -287,7 +287,7 @@
@classmethod
def check_xml_record(cls, records, values):
return True
pass
def get_rec_name(self, name):
return str(self.date)
......
......@@ -121,7 +121,7 @@
@classmethod
def check_xml_record(cls, records, values):
return True
pass
class ConfigurationLang(_ConfigurationValue, ModelSQL, ValueMixin):
......
......@@ -74,7 +74,7 @@
@classmethod
def check_xml_record(cls, records, values):
return True
pass
@staticmethod
def default_rate():
......
......@@ -334,7 +334,7 @@
@classmethod
def check_xml_record(cls, records, values):
return True
pass
def get_warehouse(self, name):
# Order by descending left to get the first one in the tree
......
* Raise error message with record name and field in check_xml_record
* Cache RPC call for class method selection
Version 6.6.0 - 2022-10-31
......
......@@ -442,5 +442,7 @@
.. classmethod:: ModelStorage.check_xml_record(records, values)
Verify if the records are originating from XML data.
Raise an :exc:`~trytond.model.exceptions.AccessError` if the records can not
be modified because they originate from XML data.
``values`` is a dictionary of written values or ``None`` for deletion.
......@@ -446,5 +448,6 @@
It is used to prevent modification of data coming from XML files.
It is used by :meth:`~ModelStorage.write` and :meth:`~ModelStorage.delete`
to prevent modification of data coming from XML files.
.. note::
This method must be overiden to change this behavior.
......
......@@ -105,9 +105,9 @@
def get_timezone(self, name):
return tz.SERVER.key
@staticmethod
def check_xml_record(crons, values):
return True
@classmethod
def check_xml_record(cls, crons, values):
pass
@classmethod
def view_attributes(cls):
......
......@@ -307,9 +307,9 @@
gettext('ir.msg_language_default_translatable',
language=lang.rec_name))
@staticmethod
def check_xml_record(langs, values):
return True
@classmethod
def check_xml_record(cls, langs, values):
pass
@classmethod
def get_translatable_languages(cls):
......
......@@ -137,6 +137,6 @@
<field name="text">ID must be positive.</field>
</record>
<record model="ir.message" id="msg_write_xml_record">
<field name="text">You are not allowed to modify this record.</field>
<field name="text">You are not allowed to modify the field "%(field)s" in "%(record)s" of "%(model)s".</field>
</record>
<record model="ir.message" id="msg_delete_xml_record">
......@@ -141,6 +141,6 @@
</record>
<record model="ir.message" id="msg_delete_xml_record">
<field name="text">You are not allowed to delete this record.</field>
<field name="text">You are not allowed to delete the record "%(record)s" of "%(model)s".</field>
</record>
<record model="ir.message" id="msg_base_config_record">
<field name="text">This record is part of the base configuration.</field>
......
......@@ -492,9 +492,9 @@
'get_access': RPC(),
})
@staticmethod
def check_xml_record(accesses, values):
return True
@classmethod
def check_xml_record(cls, accesses, values):
pass
@staticmethod
def default_perm_read():
......@@ -701,9 +701,9 @@
description = fields.Text('Description')
_get_access_cache = Cache('ir_model_field_access.check', context=False)
@staticmethod
def check_xml_record(field_accesses, values):
return True
@classmethod
def check_xml_record(cls, field_accesses, values):
pass
@staticmethod
def default_perm_read():
......
......@@ -236,10 +236,7 @@
all_records = []
all_fields = set()
for records, values in zip(actions, actions):
if not cls.check_xml_record(records, values):
raise AccessError(
gettext('ir.msg_write_xml_record'),
gettext('ir.msg_base_config_record'))
cls.check_xml_record(records, values)
all_records += records
all_fields.update(values.keys())
......@@ -303,10 +300,7 @@
ModelData = pool.get('ir.model.data')
ModelAccess.check(cls.__name__, 'delete')
if not cls.check_xml_record(records, None):
raise AccessError(
gettext('ir.msg_delete_xml_record'),
gettext('ir.msg_base_config_record'))
cls.check_xml_record(records, None)
if ModelData.has_model(cls.__name__):
with Transaction().set_context(_check_access=False):
data = []
......@@ -1124,17 +1118,7 @@
@classmethod
def check_xml_record(cls, records, values):
"""
Check if a list of records and their corresponding fields are
originating from xml data. This is used by write and delete
functions: if the return value is True the records can be
written/deleted, False otherwise. The default behaviour is to
forbid any modification on records/fields originating from
xml. Values is the dictionary of written values. If values is
equal to None, no field by field check is performed, False is
returned as soon as one of the record comes from the xml.
"""
ModelData = Pool().get('ir.model.data')
# Allow root user to update/delete
if (Transaction().user == 0
or not ModelData.has_model(cls.__name__)):
......@@ -1137,8 +1121,9 @@
ModelData = Pool().get('ir.model.data')
# Allow root user to update/delete
if (Transaction().user == 0
or not ModelData.has_model(cls.__name__)):
return True
return
id2record = {r.id: r for r in records}
with Transaction().set_context(_check_access=False):
models_data = ModelData.search([
('model', '=', cls.__name__),
......@@ -1142,6 +1127,6 @@
with Transaction().set_context(_check_access=False):
models_data = ModelData.search([
('model', '=', cls.__name__),
('db_id', 'in', list(map(int, records))),
('db_id', 'in', list(id2record.keys())),
])
if not models_data:
......@@ -1146,4 +1131,4 @@
])
if not models_data:
return True
return
for model_data in models_data:
......@@ -1149,3 +1134,4 @@
for model_data in models_data:
record = id2record[model_data.db_id]
if values is None:
if not model_data.noupdate:
......@@ -1150,9 +1136,13 @@
if values is None:
if not model_data.noupdate:
return False
raise AccessError(
gettext(
'ir.msg_delete_xml_record',
**cls.__names__(record=record)),
gettext('ir.msg_base_config_record'))
else:
if not model_data.values or model_data.noupdate:
continue
xml_values = ModelData.load_values(model_data.values)
for key, val in values.items():
if key in xml_values and val != xml_values[key]:
......@@ -1153,11 +1143,14 @@
else:
if not model_data.values or model_data.noupdate:
continue
xml_values = ModelData.load_values(model_data.values)
for key, val in values.items():
if key in xml_values and val != xml_values[key]:
return False
return True
raise AccessError(
gettext(
'ir.msg_write_xml_record',
**cls.__names__(field=key, record=record)),
gettext('ir.msg_base_config_record'))
@classmethod
def validate(cls, records):
......
......@@ -515,9 +515,7 @@
Model = pool.get('test.modelstorage')
record, = Model.create([{}])
result = Model.check_xml_record([record], {'name': "Test"})
self.assertTrue(result)
Model.check_xml_record([record], {'name': "Test"})
@with_transaction()
def test_check_xml_record_with_record_no_matching_values(self):
......@@ -535,9 +533,7 @@
'noupdate': False,
}])
result = Model.check_xml_record([record], {'name': "Test"})
self.assertTrue(result)
Model.check_xml_record([record], {'name': "Test"})
@with_transaction()
def test_check_xml_record_with_record_matching_values(self):
......@@ -555,9 +551,8 @@
'noupdate': False,
}])
result = Model.check_xml_record([record], {'name': "Bar"})
self.assertFalse(result)
with self.assertRaises(AccessError):
Model.check_xml_record([record], {'name': "Bar"})
@with_transaction()
def test_check_xml_record_with_record_matching_values_noupdate(self):
......@@ -575,9 +570,7 @@
'noupdate': True,
}])
result = Model.check_xml_record([record], {'name': "Bar"})
self.assertTrue(result)
Model.check_xml_record([record], {'name': "Bar"})
@with_transaction(user=0)
def test_check_xml_record_with_record_matching_values_root(self):
......@@ -595,9 +588,7 @@
'noupdate': False,
}])
result = Model.check_xml_record([record], {'name': "Bar"})
self.assertTrue(result)
Model.check_xml_record([record], {'name': "Bar"})
@with_transaction()
def test_check_xml_record_with_record_no_values(self):
......@@ -615,9 +606,8 @@
'noupdate': False,
}])
result = Model.check_xml_record([record], None)
self.assertFalse(result)
with self.assertRaises(AccessError):
Model.check_xml_record([record], None)
@with_transaction()
def test_check_xml_record_with_record_no_values_noupdate(self):
......@@ -635,9 +625,7 @@
'noupdate': True,
}])
result = Model.check_xml_record([record], None)
self.assertTrue(result)
Model.check_xml_record([record], None)
@with_transaction()
def test_delete_clear_db_id_model_data_noupdate(self):
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment