Files
odoo_source/addons/mail/controllers/thread.py
T
Thanh Dodeur e8a883ff65 [FIX] mail: prevent crash when deleting a message
Since https://github.com/odoo/odoo/pull/126713, deleting a message
would crash as the `mail/message/update_content` route is called without
passing the `partner_ids` parameter.

This commit fixes the issue by making the parameter optional.

closes odoo/odoo#127284

X-original-commit: 34abd3dc1d159962a376b248134d0cd4977f3dcb
Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
2023-07-05 02:47:42 +02:00

96 lines
4.7 KiB
Python

# Part of Odoo. See LICENSE file for full copyright and licensing details.
from contextlib import suppress
from datetime import datetime
from markupsafe import Markup
from psycopg2 import OperationalError
from werkzeug.exceptions import NotFound
from odoo import http
from odoo.http import request
class ThreadController(http.Controller):
@http.route("/mail/thread/data", methods=["POST"], type="json", auth="user")
def mail_thread_data(self, thread_model, thread_id, request_list):
thread = request.env[thread_model].with_context(active_test=False).search([("id", "=", thread_id)])
return thread._get_mail_thread_data(request_list)
@http.route("/mail/thread/messages", methods=["POST"], type="json", auth="user")
def mail_thread_messages(self, thread_model, thread_id, before=None, after=None, around=None, limit=30):
domain = [
("res_id", "=", int(thread_id)),
("model", "=", thread_model),
("message_type", "!=", "user_notification"),
]
messages = request.env["mail.message"]._message_fetch(domain, before, after, around, limit)
if not request.env.user._is_public():
messages.set_message_done()
return messages.message_format()
@http.route("/mail/read_subscription_data", methods=["POST"], type="json", auth="user")
def read_subscription_data(self, follower_id):
"""Computes:
- message_subtype_data: data about document subtypes: which are
available, which are followed if any"""
request.env["mail.followers"].check_access_rights("read")
follower = request.env["mail.followers"].sudo().browse(follower_id)
follower.ensure_one()
request.env[follower.res_model].check_access_rights("read")
record = request.env[follower.res_model].browse(follower.res_id)
record.check_access_rule("read")
# find current model subtypes, add them to a dictionary
subtypes = record._mail_get_message_subtypes()
followed_subtypes_ids = set(follower.subtype_ids.ids)
subtypes_list = [
{
"name": subtype.name,
"res_model": subtype.res_model,
"sequence": subtype.sequence,
"default": subtype.default,
"internal": subtype.internal,
"followed": subtype.id in followed_subtypes_ids,
"parent_model": subtype.parent_id.res_model,
"id": subtype.id,
}
for subtype in subtypes
]
return sorted(
subtypes_list,
key=lambda it: (it["parent_model"] or "", it["res_model"] or "", it["internal"], it["sequence"]),
)
def _get_allowed_message_post_params(self):
return {"attachment_ids", "body", "message_type", "partner_ids", "subtype_xmlid", "parent_id"}
@http.route("/mail/message/post", methods=["POST"], type="json", auth="public")
def mail_message_post(self, thread_model, thread_id, post_data, context=None):
if context:
request.update_context(**context)
if "canned_response_ids" in post_data:
canned_response_ids = request.env['mail.shortcode'].browse(post_data.pop('canned_response_ids'))
# Ignore concurrency errors when saving last used date
with suppress(OperationalError):
canned_response_ids.write({'last_used': datetime.now()})
thread = request.env[thread_model]._get_from_request_or_raise(request, int(thread_id))
if "body" in post_data:
post_data["body"] = Markup(post_data["body"]) # contains HTML such as @mentions
message_data = thread.message_post(
**{key: value for key, value in post_data.items() if key in self._get_allowed_message_post_params()}
).message_format()[0]
if "temporary_id" in request.context:
message_data["temporary_id"] = request.context["temporary_id"]
return message_data
@http.route("/mail/message/update_content", methods=["POST"], type="json", auth="public")
def mail_message_update_content(self, message_id, body, attachment_ids, partner_ids=None):
guest = request.env["mail.guest"]._get_guest_from_request(request)
message_sudo = guest.env["mail.message"].browse(message_id).sudo().exists()
if not message_sudo.is_current_user_or_guest_author and not guest.env.user._is_admin():
raise NotFound()
if not message_sudo.model or not message_sudo.res_id:
raise NotFound()
request.env[message_sudo.model].browse([message_sudo.res_id])._message_update_content(
message_sudo, body, attachment_ids=attachment_ids, partner_ids=partner_ids
)