[FIX] mail: allow regular users to create mail non-dynamic templates
closes odoo/odoo#90896 X-original-commit: 96770827e42615c43b70bdae6529fb76ac66c518 Signed-off-by: Denis Ledoux (dle) <dle@odoo.com>
This commit is contained in:
@@ -4856,6 +4856,7 @@ msgstr ""
|
||||
#. module: mail
|
||||
#: code:addons/mail/models/mail_render_mixin.py:0
|
||||
#: code:addons/mail/models/mail_render_mixin.py:0
|
||||
#: code:addons/mail/models/mail_render_mixin.py:0
|
||||
#, python-format
|
||||
msgid "Only users belonging to the \"%s\" group can modify dynamic templates."
|
||||
msgstr ""
|
||||
|
||||
@@ -127,6 +127,23 @@ class MailRenderMixin(models.AbstractModel):
|
||||
# allow specifying rendering options directly from field when using the render mixin
|
||||
return name in ['render_engine', 'render_options'] or super()._valid_field_parameter(field, name)
|
||||
|
||||
@api.model_create_multi
|
||||
def create(self, values_list):
|
||||
record = super().create(values_list)
|
||||
if self._unrestricted_rendering:
|
||||
# If the rendering is unrestricted (e.g. mail.template),
|
||||
# check the user is part of the mail editor group to create a new template if the template is dynamic
|
||||
record._check_access_right_dynamic_template()
|
||||
return record
|
||||
|
||||
def write(self, vals):
|
||||
super().write(vals)
|
||||
if self._unrestricted_rendering:
|
||||
# If the rendering is unrestricted (e.g. mail.template),
|
||||
# check the user is part of the mail editor group to modify a template if the template is dynamic
|
||||
self._check_access_right_dynamic_template()
|
||||
return True
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# TOOLS
|
||||
# ------------------------------------------------------------
|
||||
@@ -214,6 +231,48 @@ class MailRenderMixin(models.AbstractModel):
|
||||
""").format(preview_markup)
|
||||
return tools.prepend_html_content(html, html_preview)
|
||||
return html
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# SECURITY
|
||||
# ------------------------------------------------------------
|
||||
|
||||
def _is_dynamic(self):
|
||||
for template in self:
|
||||
for fname, field in template._fields.items():
|
||||
engine = getattr(field, 'render_engine', 'inline_template')
|
||||
if engine in ('qweb', 'qweb_view'):
|
||||
if self._is_dynamic_template_qweb(template[fname]):
|
||||
return True
|
||||
else:
|
||||
if self._is_dynamic_template_inline_template(template[fname]):
|
||||
return True
|
||||
return False
|
||||
|
||||
@api.model
|
||||
def _is_dynamic_template_qweb(self, template_src):
|
||||
if template_src:
|
||||
try:
|
||||
node = html.fragment_fromstring(template_src, create_parent='div')
|
||||
self.env["ir.qweb"].with_context(raise_on_code=True)._compile(node)
|
||||
except QWebException as e:
|
||||
if isinstance(e.__cause__, PermissionError):
|
||||
return True
|
||||
raise
|
||||
return False
|
||||
|
||||
@api.model
|
||||
def _is_dynamic_template_inline_template(self, template_txt):
|
||||
if template_txt:
|
||||
template_instructions = parse_inline_template(str(template_txt))
|
||||
if len(template_instructions) > 1 or template_instructions[0][1]:
|
||||
return True
|
||||
return False
|
||||
|
||||
def _check_access_right_dynamic_template(self):
|
||||
if not self.env.su and not self.env.user.has_group('mail.group_mail_template_editor') and self._is_dynamic():
|
||||
group = self.env.ref('mail.group_mail_template_editor')
|
||||
raise AccessError(_('Only users belonging to the "%s" group can modify dynamic templates.', group.name))
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# RENDERING
|
||||
# ------------------------------------------------------------
|
||||
|
||||
@@ -31,7 +31,7 @@ access_mail_tracking_value_portal,mail.tracking.value.portal,model_mail_tracking
|
||||
access_mail_tracking_value_user,mail.tracking.value.user,model_mail_tracking_value,base.group_user,0,0,0,0
|
||||
access_mail_tracking_value_system,mail.tracking.value.system,model_mail_tracking_value,base.group_system,1,1,1,1
|
||||
access_publisher_warranty_contract_all,publisher.warranty.contract.all,model_publisher_warranty_contract,,1,1,1,1
|
||||
access_mail_template,mail.template,model_mail_template,base.group_user,1,0,0,0
|
||||
access_mail_template,mail.template,model_mail_template,base.group_user,1,1,1,1
|
||||
access_mail_template_editor,mail.template_editor,model_mail_template,mail.group_mail_template_editor,1,1,1,1
|
||||
access_mail_template_system,mail.template_system,model_mail_template,base.group_system,1,1,1,1
|
||||
access_mail_shortcode,mail.shortcode,model_mail_shortcode,base.group_user,1,1,1,1
|
||||
|
||||
|
@@ -65,6 +65,28 @@
|
||||
<field name="perm_unlink" eval="False"/>
|
||||
</record>
|
||||
|
||||
<record id="mail_template_employee_rule" model="ir.rule">
|
||||
<field name="name">Employees can only change their own templates</field>
|
||||
<field name="model_id" ref="model_mail_template"/>
|
||||
<field name="domain_force">[('create_uid', '=', user.id)]</field>
|
||||
<field name="groups" eval="[Command.link(ref('base.group_user'))]"/>
|
||||
<field name="perm_create" eval="True"/>
|
||||
<field name="perm_read" eval="False"/>
|
||||
<field name="perm_write" eval="True"/>
|
||||
<field name="perm_unlink" eval="True"/>
|
||||
</record>
|
||||
|
||||
<record id="mail_template_editor_rule" model="ir.rule">
|
||||
<field name="name">Mail Template Editors - Edit All Templates</field>
|
||||
<field name="model_id" ref="model_mail_template"/>
|
||||
<field name="domain_force">[(1, '=', 1)]</field>
|
||||
<field name="groups" eval="[Command.link(ref('group_mail_template_editor')), Command.link(ref('base.group_system'))]"/>
|
||||
<field name="perm_create" eval="True"/>
|
||||
<field name="perm_read" eval="False"/>
|
||||
<field name="perm_write" eval="True"/>
|
||||
<field name="perm_unlink" eval="True"/>
|
||||
</record>
|
||||
|
||||
<record id="res_users_settings_rule_admin" model="ir.rule">
|
||||
<field name="name">Administrators can access all User Settings.</field>
|
||||
<field name="model_id" ref="model_res_users_settings"/>
|
||||
|
||||
@@ -57,9 +57,25 @@ class TestMailTemplate(MailCommon):
|
||||
mail_template.with_user(self.user_admin).name = 'New name'
|
||||
self.assertEqual(mail_template.name, 'New name')
|
||||
|
||||
# Standard employee can not
|
||||
# Standard employee can create and edit non-dynamic templates
|
||||
employee_template = self.env['mail.template'].with_user(self.user_employee).create({'body_html': '<p>foo</p>'})
|
||||
|
||||
employee_template.with_user(self.user_employee).body_html = '<p>bar</p>'
|
||||
|
||||
employee_template = self.env['mail.template'].with_user(self.user_employee).create({'email_to': 'foo@bar.com'})
|
||||
|
||||
employee_template.with_user(self.user_employee).email_to = 'bar@foo.com'
|
||||
|
||||
# Standard employee cannot create and edit templates with dynamic qweb
|
||||
with self.assertRaises(AccessError):
|
||||
self.env['mail.template'].with_user(self.user_employee).create({})
|
||||
self.env['mail.template'].with_user(self.user_employee).create({'body_html': '<p t-esc="\'foo\'"></p>'})
|
||||
|
||||
with self.assertRaises(AccessError):
|
||||
mail_template.with_user(self.user_employee).name = 'Test write'
|
||||
mail_template.with_user(self.user_employee).body_html = '<p t-esc="\'foo\'"></p>'
|
||||
|
||||
# Standard employee cannot create and edit templates with dynamic inline fields
|
||||
with self.assertRaises(AccessError):
|
||||
self.env['mail.template'].with_user(self.user_employee).create({'email_to': '{{ object.partner_id.email }}'})
|
||||
|
||||
with self.assertRaises(AccessError):
|
||||
mail_template.with_user(self.user_employee).email_to = '{{ object.partner_id.email }}'
|
||||
|
||||
@@ -66,8 +66,9 @@
|
||||
<button string="Send" attrs="{'invisible': [('is_log', '=', True)]}" name="action_send_mail" type="object" class="btn-primary o_mail_send" data-hotkey="q"/>
|
||||
<button string="Log" attrs="{'invisible': [('is_log', '=', False)]}" name="action_send_mail" type="object" class="btn-primary" data-hotkey="q"/>
|
||||
<button string="Cancel" class="btn-secondary" special="cancel" data-hotkey="z" />
|
||||
<button icon="fa-lg fa-save" type="object" groups="mail.group_mail_template_editor"
|
||||
<button icon="fa-lg fa-save" type="object"
|
||||
name="action_save_as_template" string="Save as new template"
|
||||
attrs="{'invisible': [('can_edit_body', '=', False)]}"
|
||||
class="float-right btn-secondary" help="Save as a new template" data-hotkey="w"/>
|
||||
</footer>
|
||||
</form>
|
||||
|
||||
Reference in New Issue
Block a user