[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) <vfe@odoo.com>
This commit is contained in:
Victor Feyens
2024-01-05 10:34:45 +00:00
parent 5022f68a42
commit 6d99cf3eb6
+11 -1
View File
@@ -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