[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:
Luis González
2022-02-17 16:42:04 +00:00
committed by Sébastien Theys
parent 3ed97cb8bb
commit 3ca6e48142
4 changed files with 32 additions and 3 deletions
+1 -1
View File
@@ -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):
+7
View File
@@ -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)