From 6d99cf3eb6741e9837508c6ffd64c5747155f81c Mon Sep 17 00:00:00 2001 From: Victor Feyens Date: Thu, 21 Dec 2023 16:57:42 +0100 Subject: [PATCH] [FIX] sale: access error on first pending payment Steps to reproduce: 1) Install and enable the "Onsite" payment provider; 2) As a public user, add product(s) to your cart; 3) Try to pay with the "Onsite" provider. -> Internal Server Error Cause of the issue: In the log, the cause of the issue is an AccessError, specifying that we tried to read the field `transaction_ids` on a `sale.order` without having the necessary access rights. This shouldn't happen, since the payment & ecommerce flows are executed in sudo mode, after making sure that the cart belongs to the customer. After investigation, pending payment transactions trigger 1) the sending of a mail to the customer 2) the first mail generation will request the report assets 3) the generation of the report assets will create an attachment and commit the transaction 4) committing the transaction will trigger a global flush of the environment, forcing the computation of pending mail wizard fields, with a different environment than the sudoed one initiating the sending of the mail. This will lead to security errors as we try to access `sale.order` fields content without having the rights for it. Standard fields being already in the cache, it will be noticed when trying to read the `transaction_ids` field. Solution: Manually prefetch the `transaction_ids` content with the sudoed environment, since the records cache is shared between the environments (until a more global fix is found and deployed). Introduced by #121376 opw-3628753 closes odoo/odoo#148199 X-original-commit: 511fe642b9860bd9d2f6b7ed728e7d3e6af48748 Signed-off-by: Victor Feyens (vfe) --- addons/sale/models/payment_transaction.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/addons/sale/models/payment_transaction.py b/addons/sale/models/payment_transaction.py index b3fcf8cf56a..f0b3c94456f 100644 --- a/addons/sale/models/payment_transaction.py +++ b/addons/sale/models/payment_transaction.py @@ -52,7 +52,17 @@ class PaymentTransaction(models.Model): if tx.provider_id.code == 'custom': for so in tx.sale_order_ids: so.reference = tx._compute_sale_order_reference(so) - # send payment status mail. + + # Send the payment status email. + # The transactions are manually cached while in a sudoed environment to prevent an + # AccessError: In some circumstances, sending the mail would generate the report assets + # during the rendering of the mail body, causing a cursor commit, a flush, and forcing + # the re-computation of the pending computed fields of the `mail.compose.message`, + # including part of the template. Since that template reads the order's transactions and + # the re-computation of the field is not done with the same environment, reading fields + # that were not already available in the cache could trigger an AccessError (e.g., if + # the payment was initiated by a public user). + sales_orders.mapped('transaction_ids') sales_orders._send_payment_succeeded_for_order_mail() return txs_to_process