[FIX] portal: check model is valid when entering mail redirect controller

When mail_action_view() calls this function, the model may not be a valid
one or even be missing. So we check if the model exists before checking its
type.

We also correctly add kwargs parameters propagation.

Add tests.

Task-3025143

X-original-commit: b5d9f42ddc2dfde21714544add72023004069815
Part-of: odoo/odoo#103378
Co-authored-by: Krzysztof Magusiak <kmagusiak>
This commit is contained in:
Thibault Delavallée
2022-10-18 13:17:31 +02:00
co-authored by Krzysztof Magusiak <kmagusiak>
parent 78703dd803
commit 28ed4eddea
2 changed files with 76 additions and 16 deletions
+5 -1
View File
@@ -238,6 +238,10 @@ class MailController(mail.MailController):
If so, those two parameters are used to authentify the recipient in the chatter, if any.
:return:
"""
# no model / res_id, meaning no possible record -> direct skip to super
if not model or not res_id or model not in request.env:
return super(MailController, cls)._redirect_to_record(model, res_id, access_token=access_token, **kwargs)
if issubclass(type(request.env[model]), request.env.registry['portal.mixin']):
uid = request.session.uid or request.env.ref('base.public_user').id
record_sudo = request.env[model].sudo().browse(res_id).exists()
@@ -257,4 +261,4 @@ class MailController(mail.MailController):
url_params.update([("pid", pid), ("hash", hash)])
url = url.replace(query=urls.url_encode(url_params)).to_url()
return request.redirect(url)
return super(MailController, cls)._redirect_to_record(model, res_id, access_token=access_token)
return super(MailController, cls)._redirect_to_record(model, res_id, access_token=access_token, **kwargs)
+71 -15
View File
@@ -1,6 +1,8 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from werkzeug.urls import url_parse, url_decode
import json
from odoo import http
@@ -23,6 +25,56 @@ class TestPortal(HttpCase, TestMailFullCommon, TestSMSRecipients):
self.record_portal._portal_ensure_token()
@tagged('-at_install', 'post_install', 'portal')
class TestPortalControllers(TestPortal):
def test_redirect_to_records(self):
""" Test redirection of portal-enabled records """
# Test Case 0: as anonymous, cannot access, redirect to web/login
response = self.url_open('/mail/view?model=%s&res_id=%s' % (
self.record_portal._name,
self.record_portal.id), timeout=15)
path = url_parse(response.url).path
self.assertEqual(path, '/web/login')
# Test Case 1: as admin, can access record
self.authenticate(self.user_admin.login, self.user_admin.login)
response = self.url_open('/mail/view?model=%s&res_id=%s' % (
self.record_portal._name,
self.record_portal.id), timeout=15)
self.assertEqual(response.status_code, 200)
fragment = url_parse(response.url).fragment
params = url_decode(fragment)
self.assertEqual(params['cids'], '%s' % self.user_admin.company_id.id)
self.assertEqual(params['id'], '%s' % self.record_portal.id)
self.assertEqual(params['model'], self.record_portal._name)
def test_redirect_to_records_norecord(self):
""" Check specific use case of missing model, should directly redirect
to login page. """
for model, res_id in [
(False, self.record_portal.id),
('', self.record_portal.id),
(self.record_portal._name, False),
(self.record_portal._name, ''),
(False, False),
('wrong.model', self.record_portal.id),
(self.record_portal._name, -4),
]:
response = self.url_open(
'/mail/view?model=%s&res_id=%s' % (model, res_id),
timeout=15
)
path = url_parse(response.url).path
self.assertEqual(
path, '/web/login',
'Failed with %s - %s' % (model, res_id)
)
def test_portal_message_fetch(self):
"""Test retrieving chatter messages through the portal controller"""
self.authenticate(None, None)
@@ -65,21 +117,6 @@ class TestPortal(HttpCase, TestMailFullCommon, TestSMSRecipients):
# Empty messages should be ignored
self.assertEqual(get_chatter_message_count(), 5)
@users('employee')
def test_portal_mixin(self):
""" Test internals of portal mixin """
customer = self.partner_1.with_env(self.env)
record_portal = self.env['mail.test.portal'].create({
'partner_id': customer.id,
'name': 'Test Portal Record',
})
self.assertFalse(record_portal.access_token)
self.assertEqual(record_portal.access_url, '/my/test_portal/%s' % record_portal.id)
record_portal._portal_ensure_token()
self.assertTrue(record_portal.access_token)
def test_portal_share_comment(self):
""" Test posting through portal controller allowing to use a hash to
post wihtout access rights. """
@@ -106,3 +143,22 @@ class TestPortal(HttpCase, TestMailFullCommon, TestSMSRecipients):
self.assertIn('Test', message.body)
self.assertEqual(message.author_id, self.partner_2)
@tagged('portal')
class TestPortalMixin(TestPortal):
@users('employee')
def test_portal_mixin(self):
""" Test internals of portal mixin """
customer = self.partner_1.with_env(self.env)
record_portal = self.env['mail.test.portal'].create({
'partner_id': customer.id,
'name': 'Test Portal Record',
})
self.assertFalse(record_portal.access_token)
self.assertEqual(record_portal.access_url, '/my/test_portal/%s' % record_portal.id)
record_portal._portal_ensure_token()
self.assertTrue(record_portal.access_token)