[FIX] website_livechat: access error when retrieving chatter info
When chatter information is retrieved but current user has no access to website visitors, an access error is raised and chatter messages are not displayed. To replicate: - Enable livechat for current website - Set user A as member of the livechat - Log-in with user B, who doesn't have access to website visitors - Visit any page that automatically opens the livechat with user B (no need to input anything, as a livechat is created when the chat window pops up) - Go to backend with user B To solve the above, visitor information is included only if current user has enough right to access it. closes odoo/odoo#84823 X-original-commit: 7fb23842ef2e2950466f44b18005d27443d292f9 Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
This commit is contained in:
committed by
Sébastien Theys
parent
3ed97cb8bb
commit
3ca6e48142
@@ -168,7 +168,7 @@ class DiscussController(http.Controller):
|
||||
@http.route('/mail/init_messaging', methods=['POST'], type='json', auth='public')
|
||||
def mail_init_messaging(self, **kwargs):
|
||||
if not request.env.user.sudo()._is_public():
|
||||
return request.env.user._init_messaging()
|
||||
return request.env.user.sudo(False)._init_messaging()
|
||||
guest = request.env['mail.guest']._get_guest_from_request(request)
|
||||
if guest:
|
||||
return guest.sudo()._init_messaging()
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.exceptions import AccessError
|
||||
|
||||
|
||||
class MailChannel(models.Model):
|
||||
@@ -29,9 +30,9 @@ class MailChannel(models.Model):
|
||||
"""
|
||||
channel_infos = super().channel_info()
|
||||
channel_infos_dict = dict((c['id'], c) for c in channel_infos)
|
||||
for channel in self:
|
||||
for channel in self.filtered('livechat_visitor_id'):
|
||||
visitor = channel.livechat_visitor_id
|
||||
if visitor:
|
||||
try:
|
||||
channel_infos_dict[channel.id]['visitor'] = {
|
||||
'display_name': visitor.display_name,
|
||||
'country_code': visitor.country_id.code.lower() if visitor.country_id else False,
|
||||
@@ -43,6 +44,8 @@ class MailChannel(models.Model):
|
||||
'lang_name': visitor.lang_id.name,
|
||||
'partner_id': visitor.partner_id.id,
|
||||
}
|
||||
except AccessError:
|
||||
pass
|
||||
return list(channel_infos_dict.values())
|
||||
|
||||
def _get_visitor_history(self, visitor):
|
||||
|
||||
@@ -9,12 +9,18 @@ class TestLivechatCommon(tests.TransactionCase):
|
||||
super(TestLivechatCommon, self).setUp()
|
||||
self.base_datetime = fields.Datetime.from_string("2019-11-11 21:30:00")
|
||||
|
||||
self.group_user = self.env.ref('base.group_user')
|
||||
self.group_livechat_user = self.env.ref('im_livechat.im_livechat_group_user')
|
||||
self.operator = self.env['res.users'].create({
|
||||
'name': 'Operator Michel',
|
||||
'login': 'operator',
|
||||
'email': 'operator@example.com',
|
||||
'password': "ideboulonate",
|
||||
'livechat_username': 'El Deboulonnator',
|
||||
'groups_id': [(6, 0, [
|
||||
self.group_user.id,
|
||||
self.group_livechat_user.id,
|
||||
])],
|
||||
})
|
||||
|
||||
self.livechat_channel = self.env['im_livechat.channel'].create({
|
||||
@@ -46,6 +52,7 @@ class TestLivechatCommon(tests.TransactionCase):
|
||||
|
||||
self.send_feedback_url = base_url + "/im_livechat/feedback"
|
||||
self.leave_session_url = base_url + "/im_livechat/visitor_leave_session"
|
||||
self.message_info_url = base_url + "/mail/init_messaging"
|
||||
|
||||
# override the get_available_users to return only Michel as available
|
||||
operators = self.operator
|
||||
|
||||
@@ -83,6 +83,25 @@ class TestLivechatBasicFlowHttpCase(tests.HttpCase, TestLivechatCommon):
|
||||
self.assertEqual(channel.message_ids[0].body, "<p>%s has left the conversation.</p>" % self.visitor.display_name)
|
||||
self.assertEqual(channel.livechat_active, False, "The livechat session must be inactive since visitor has left the conversation.")
|
||||
|
||||
def test_visitor_info_access_rights(self):
|
||||
channel = self._common_basic_flow()
|
||||
self.authenticate(self.operator.login, 'ideboulonate')
|
||||
|
||||
# Retrieve channels information, visitor info should be there
|
||||
res = self.opener.post(self.message_info_url, json={})
|
||||
self.assertEqual(res.status_code, 200)
|
||||
messages_info = res.json().get('result', {})
|
||||
livechat_info = next(c for c in messages_info['channels'] if c['id'] == channel.id)
|
||||
self.assertIn('visitor', livechat_info)
|
||||
|
||||
# Remove access to visitors and try again, visitors info shouldn't be included
|
||||
self.operator.groups_id -= self.group_livechat_user
|
||||
res = self.opener.post(self.message_info_url, json={})
|
||||
self.assertEqual(res.status_code, 200)
|
||||
messages_info = res.json().get('result', {})
|
||||
livechat_info = next(c for c in messages_info['channels'] if c['id'] == channel.id)
|
||||
self.assertNotIn('visitor', livechat_info)
|
||||
|
||||
def _common_basic_flow(self):
|
||||
# Open a new live chat
|
||||
res = self.opener.post(url=self.open_chat_url, json=self.open_chat_params)
|
||||
|
||||
Reference in New Issue
Block a user