[IMP] payment: only give access to tokens when required by the flow

Until this point the access to tokens was somehow arbitrary and
illogical.
After this commit we will uniformize the tokens access rule where by
default an user can only access its own tokens by default and in
function of the use case then relax the rules.

Task - 2832561

closes odoo/odoo#104808

Related: odoo/enterprise#33541
Signed-off-by: Antoine Vandevenne (anv) <anv@odoo.com>
This commit is contained in:
Horacio Tellez
2023-02-17 13:06:53 +01:00
parent d75339f1d3
commit 0f2de18849
5 changed files with 24 additions and 36 deletions
@@ -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)
@@ -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)
+3 -3
View File
@@ -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
+5 -3
View File
@@ -27,10 +27,12 @@
<!-- Tokens -->
<record id="payment_token_user_rule" model="ir.rule">
<field name="name">Access only tokens belonging to commercial partner</field>
<field name="name">Users can access only their own tokens</field>
<field name="model_id" ref="payment.model_payment_token"/>
<field name="domain_force">[('partner_id', 'child_of', user.partner_id.commercial_partner_id.id)]</field>
<field name="groups" eval="[(4, ref('base.group_user')), (4, ref('base.group_portal')), (4, ref('base.group_public'))]"/>
<field name="domain_force">[('partner_id', '=', user.partner_id.id)]</field>
<field name="groups" eval="[(4, ref('base.group_user')),
(4, ref('base.group_portal')),
(4, ref('base.group_public'))]"/>
</record>
<record id="payment_token_company_rule" model="ir.rule">
+10 -1
View File
@@ -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)