diff --git a/addons/payment/models/account_move.py b/addons/payment/models/account_move.py index 85c46e9f181..4809263217d 100644 --- a/addons/payment/models/account_move.py +++ b/addons/payment/models/account_move.py @@ -2,6 +2,8 @@ from odoo import api, fields, models +from odoo.addons.payment import utils as payment_utils + class AccountMove(models.Model): _inherit = 'account.move' @@ -26,10 +28,16 @@ class AccountMove(models.Model): return self.with_context(active_test=False).transaction_ids._get_last() def payment_action_capture(self): - self.authorized_transaction_ids.action_capture() + """ Capture all transactions linked to this invoice. """ + payment_utils.check_rights_on_recordset(self) + # In sudo mode because we need to be able to read on acquirer fields. + self.authorized_transaction_ids.sudo().action_capture() def payment_action_void(self): - self.authorized_transaction_ids.action_void() + """ Void all transactions linked to this invoice. """ + payment_utils.check_rights_on_recordset(self) + # In sudo mode because we need to be able to read on acquirer fields. + self.authorized_transaction_ids.sudo().action_void() def action_view_payment_transactions(self): action = self.env['ir.actions.act_window']._for_xml_id('payment.action_payment_transaction') diff --git a/addons/payment/models/payment_transaction.py b/addons/payment/models/payment_transaction.py index 593352a59b9..44d96686073 100644 --- a/addons/payment/models/payment_transaction.py +++ b/addons/payment/models/payment_transaction.py @@ -298,16 +298,20 @@ class PaymentTransaction(models.Model): if any(tx.state != 'authorized' for tx in self): raise ValidationError(_("Only authorized transactions can be captured.")) + payment_utils.check_rights_on_recordset(self) for tx in self: - tx._send_capture_request() + # In sudo mode because we need to be able to read on acquirer fields. + tx.sudo()._send_capture_request() def action_void(self): """ Check the state of the transaction and request to have them voided. """ if any(tx.state != 'authorized' for tx in self): raise ValidationError(_("Only authorized transactions can be voided.")) + payment_utils.check_rights_on_recordset(self) for tx in self: - tx._send_void_request() + # In sudo mode because we need to be able to read on acquirer fields. + tx.sudo()._send_void_request() def action_refund(self, amount_to_refund=None): """ Check the state of the transactions and request their refund. diff --git a/addons/payment/utils.py b/addons/payment/utils.py index 2dcb6392597..a812ca4c7f1 100644 --- a/addons/payment/utils.py +++ b/addons/payment/utils.py @@ -156,3 +156,16 @@ def split_partner_name(partner_name): def get_customer_ip_address(): return request and request.httprequest.remote_addr or '' + + +def check_rights_on_recordset(recordset): + """ Ensure that the user has the rights to write on the record. + + Call this method to check the access rules and rights before doing any operation that is + callable by RPC and that requires to be executed in sudo mode. + + :param recordset: The recordset for which the rights should be checked. + :return: None + """ + recordset.check_access_rights('write') + recordset.check_access_rule('write') diff --git a/addons/sale/models/sale_order.py b/addons/sale/models/sale_order.py index 96e24eae6a0..736acdb9464 100644 --- a/addons/sale/models/sale_order.py +++ b/addons/sale/models/sale_order.py @@ -12,6 +12,8 @@ from odoo.exceptions import AccessError, UserError, ValidationError from odoo.osv import expression from odoo.tools import float_is_zero, format_amount, format_date, html_keep_url, is_html_empty +from odoo.addons.payment import utils as payment_utils + READONLY_FIELD_STATES = { state: [('readonly', True)] for state in {'sale', 'done', 'cancel'} @@ -1200,10 +1202,16 @@ class SaleOrder(models.Model): line.qty_to_invoice = 0 def payment_action_capture(self): - self.authorized_transaction_ids.action_capture() + """ Capture all transactions linked to this sale order. """ + payment_utils.check_rights_on_recordset(self) + # In sudo mode because we need to be able to read on acquirer fields. + self.authorized_transaction_ids.sudo().action_capture() def payment_action_void(self): - self.authorized_transaction_ids.action_void() + """ Void all transactions linked to this sale order. """ + payment_utils.check_rights_on_recordset(self) + # In sudo mode because we need to be able to read on acquirer fields. + self.authorized_transaction_ids.sudo().action_void() def get_portal_last_transaction(self): self.ensure_one()