[FIX] payment: allow the user to archive the tokens he sees

Expected behavior :
User should be able to archive the tokens he sees

Current behavior :
User sees his tokens but cannot archive a token from another company

Steps to reproduce :
- Install Sales & Contacts
- Create a 2nd Company
- Enable `Online Payments`
- Setup a Payment Acquirer (Test Mode for current company) *Be sure to have `Allow Saving Payment Methods` checked*
- Create a new contact and grant him portal access

*With new contact*
- Get the link and set a password
- Create a new payment method in `Manage payment methods`

*With admin again*
- Replace `Allowed Companies` and `Default Company` for the new contact by the company created before

*With new contact*
- Go back in `Manage payment methods` and try to delete the token

Reason :
Before, the `write` method from the model was called but returned an AccessError because the token was linked to another company.
Now a custom route is called, it checks if the token is linked to the user and archives it with the necessary rights

OPW-2660186

closes odoo/odoo#82405

X-original-commit: 19f8c4e26291740edecd0c101c3d331deef2758d
Signed-off-by: Claude Thibault (thcl) <thcl@odoo.com>
Signed-off-by: Antoine Vandevenne (anv) <anv@odoo.com>
This commit is contained in:
thcl-odoo
2022-01-14 15:44:48 +00:00
parent 449f8f3220
commit d826b0ac7a
3 changed files with 46 additions and 13 deletions
+16
View File
@@ -376,6 +376,22 @@ class PaymentPortal(portal.CustomerPortal):
# Display the portal homepage to the user
return request.redirect('/my/home')
@http.route('/payment/archive_token', type='json', auth='user')
def archive_token(self, token_id):
""" Check that a user has write access on a token and archive the token if so.
:param int token_id: The token to archive, as a `payment.token` id
:return: None
"""
partner_sudo = request.env.user.partner_id
token_sudo = request.env['payment.token'].sudo().search([
('id', '=', token_id),
# Check that the user owns the token before letting them archive anything
('partner_id', 'in', [partner_sudo.id, partner_sudo.commercial_partner_id.id])
])
if token_sudo:
token_sudo.active = False
@staticmethod
def cast_as_int(str_value):
""" Cast a string as an `int` and return it.
+12 -13
View File
@@ -80,19 +80,18 @@ odoo.define('payment.manage_form', require => {
_deleteToken: function (tokenId) {
const execute = () => {
this._rpc({
model: 'payment.token',
method: 'write',
args: [[tokenId], {active: false}],
}).then(result => {
if (result === true) { // Token successfully deleted, remove it from the view
const $tokenCard = this.$(
`input[name="o_payment_radio"][data-payment-option-id="${tokenId}"]` +
`[data-payment-option-type="token"]`
).closest('div[name="o_payment_option_card"]');
$tokenCard.siblings(`#o_payment_token_inline_form_${tokenId}`).remove();
$tokenCard.remove();
this._disableButton(false);
}
route: '/payment/archive_token',
params: {
'token_id': tokenId,
},
}).then(() => {
const $tokenCard = this.$(
`input[name="o_payment_radio"][data-payment-option-id="${tokenId}"]` +
`[data-payment-option-type="token"]`
).closest('div[name="o_payment_option_card"]');
$tokenCard.siblings(`#o_payment_token_inline_form_${tokenId}`).remove();
$tokenCard.remove();
this._disableButton(false);
}).guardedCatch(error => {
error.event.preventDefault();
this._displayError(
@@ -86,3 +86,21 @@ class TestMultiCompanyFlows(PaymentMultiCompanyCommon, PaymentHttpCommon):
self.assertEqual(manage_context['acquirer_ids'], self.acquirer.ids)
self.assertIn(token.id, manage_context['token_ids'])
self.assertIn(token_company_b.id, manage_context['token_ids'])
def test_archive_token_logged_in_another_company(self):
"""User archives his token from another company."""
# get user's token from company A
token = self.create_token(partner_id=self.portal_partner.id)
# assign user to another company
company_b = self.env['res.company'].create({'name': 'Company B'})
self.portal_user.write({'company_ids': [company_b.id], 'company_id': company_b.id})
# Log in as portal user
self.authenticate(self.portal_user.login, self.portal_user.login)
# Archive token in company A
url = self._build_url('/payment/archive_token')
self._make_json_request(url, {'token_id': token.id})
self.assertFalse(token.active)