diff --git a/addons/account_payment/models/account_payment.py b/addons/account_payment/models/account_payment.py
index d20871cc52b..e858ed27347 100644
--- a/addons/account_payment/models/account_payment.py
+++ b/addons/account_payment/models/account_payment.py
@@ -62,17 +62,11 @@ class AccountPayment(models.Model):
@api.depends('payment_method_line_id')
def _compute_suitable_payment_token_ids(self):
for payment in self:
- related_partner_ids = (
- payment.partner_id
- | payment.partner_id.commercial_partner_id
- | payment.partner_id.commercial_partner_id.child_ids
- )._origin
-
if payment.use_electronic_payment_method:
payment.suitable_payment_token_ids = self.env['payment.token'].sudo().search([
('company_id', '=', payment.company_id.id),
('provider_id.capture_manually', '=', False),
- ('partner_id', 'in', related_partner_ids.ids),
+ ('partner_id', '=', payment.partner_id.id),
('provider_id', '=', payment.payment_method_line_id.payment_provider_id.id),
])
else:
@@ -108,15 +102,9 @@ class AccountPayment(models.Model):
self.payment_token_id = False
return
- related_partner_ids = (
- self.partner_id
- | self.partner_id.commercial_partner_id
- | self.partner_id.commercial_partner_id.child_ids
- )._origin
-
- self.payment_token_id = self.env['payment.token'].sudo().search([
+ self.payment_token_id = self.env['payment.token'].search([
('company_id', '=', self.company_id.id),
- ('partner_id', 'in', related_partner_ids.ids),
+ ('partner_id', '=', self.partner_id.id),
('provider_id.capture_manually', '=', False),
('provider_id', '=', self.payment_method_line_id.payment_provider_id.id),
], limit=1)
diff --git a/addons/account_payment/wizards/account_payment_register.py b/addons/account_payment/wizards/account_payment_register.py
index 243a5d8dd10..4c0e9e2c6d6 100644
--- a/addons/account_payment/wizards/account_payment_register.py
+++ b/addons/account_payment/wizards/account_payment_register.py
@@ -36,16 +36,10 @@ class AccountPaymentRegister(models.TransientModel):
def _compute_suitable_payment_token_ids(self):
for wizard in self:
if wizard.can_edit_wizard and wizard.use_electronic_payment_method:
- related_partner_ids = (
- wizard.partner_id
- | wizard.partner_id.commercial_partner_id
- | wizard.partner_id.commercial_partner_id.child_ids
- )._origin
-
wizard.suitable_payment_token_ids = self.env['payment.token'].sudo().search([
('company_id', '=', wizard.company_id.id),
('provider_id.capture_manually', '=', False),
- ('partner_id', 'in', related_partner_ids.ids),
+ ('partner_id', '=', wizard.partner_id.id),
('provider_id', '=', wizard.payment_method_line_id.payment_provider_id.id),
])
else:
@@ -63,19 +57,14 @@ class AccountPaymentRegister(models.TransientModel):
def _compute_payment_token_id(self):
codes = [key for key in dict(self.env['payment.provider']._fields['code']._description_selection(self.env))]
for wizard in self:
- related_partner_ids = (
- wizard.partner_id
- | wizard.partner_id.commercial_partner_id
- | wizard.partner_id.commercial_partner_id.child_ids
- )._origin
if wizard.can_edit_wizard \
and wizard.payment_method_line_id.code in codes \
and wizard.journal_id \
- and related_partner_ids:
+ and wizard.partner_id:
wizard.payment_token_id = self.env['payment.token'].sudo().search([
('company_id', '=', wizard.company_id.id),
- ('partner_id', 'in', related_partner_ids.ids),
+ ('partner_id', '=', wizard.partner_id.id),
('provider_id.capture_manually', '=', False),
('provider_id', '=', wizard.payment_method_line_id.payment_provider_id.id),
], limit=1)
diff --git a/addons/payment/controllers/portal.py b/addons/payment/controllers/portal.py
index e2587bad825..e7f14cbde91 100644
--- a/addons/payment/controllers/portal.py
+++ b/addons/payment/controllers/portal.py
@@ -112,9 +112,9 @@ class PaymentPortal(portal.CustomerPortal):
) # In sudo mode to read the fields of providers and partner (if not logged in)
if provider_id in providers_sudo.ids: # Only keep the desired provider if it's suitable
providers_sudo = providers_sudo.browse(provider_id)
- payment_tokens = request.env['payment.token']._get_available_tokens(
+ tokens_sudo = request.env['payment.token'].sudo()._get_available_tokens(
providers_sudo.ids, partner_id=partner_sudo.id, logged_in=logged_in
- )
+ ) # In sudo mode to be able to read tokens of other partners.
# Make sure that the partner's company matches the company passed as parameter.
company_mismatch = not PaymentPortal._can_partner_pay_in_company(partner_sudo, company)
@@ -135,7 +135,7 @@ class PaymentPortal(portal.CustomerPortal):
}
payment_form_values = {
'providers': providers_sudo,
- 'tokens': payment_tokens,
+ 'tokens': tokens_sudo,
'fees_by_provider': fees_by_provider,
'show_tokenize_input': self._compute_show_tokenize_input_mapping(
providers_sudo, logged_in=logged_in, **kwargs
diff --git a/addons/payment/security/payment_security.xml b/addons/payment/security/payment_security.xml
index fc0b23f4339..efeb7ebf9f2 100644
--- a/addons/payment/security/payment_security.xml
+++ b/addons/payment/security/payment_security.xml
@@ -27,10 +27,12 @@
- Access only tokens belonging to commercial partner
+ Users can access only their own tokens
- [('partner_id', 'child_of', user.partner_id.commercial_partner_id.id)]
-
+ [('partner_id', '=', user.partner_id.id)]
+
diff --git a/addons/payment/tests/test_payment_token.py b/addons/payment/tests/test_payment_token.py
index 2e3428ac4b1..cb653dad9cd 100644
--- a/addons/payment/tests/test_payment_token.py
+++ b/addons/payment/tests/test_payment_token.py
@@ -2,8 +2,9 @@
from datetime import date
-from odoo.exceptions import UserError
+from odoo.exceptions import AccessError, UserError
from odoo.tests import tagged
+from odoo.tools import mute_logger
from odoo.addons.payment.tests.common import PaymentCommon
@@ -11,6 +12,14 @@ from odoo.addons.payment.tests.common import PaymentCommon
@tagged('-at_install', 'post_install')
class TestPaymentToken(PaymentCommon):
+ @mute_logger('odoo.addons.base.models.ir_rule')
+ def test_users_have_no_access_to_other_users_tokens(self):
+ users = [self.public_user, self.portal_user, self.internal_user]
+ token = self._create_token(partner_id=self.admin_partner.id)
+ for user in users:
+ with self.assertRaises(AccessError):
+ token.with_user(user).read()
+
def test_token_cannot_be_unarchived(self):
""" Test that unarchiving disabled tokens is forbidden. """
token = self._create_token(active=False)