From 3ca6e48142f0bc86663864d0e86e62bc02f0512b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20Gonz=C3=A1lez?= Date: Tue, 25 Jan 2022 19:01:53 +0000 Subject: [PATCH] [FIX] website_livechat: access error when retrieving chatter info MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) --- addons/mail/controllers/discuss.py | 2 +- .../website_livechat/models/mail_channel.py | 7 +++++-- addons/website_livechat/tests/common.py | 7 +++++++ .../tests/test_livechat_basic_flow.py | 19 +++++++++++++++++++ 4 files changed, 32 insertions(+), 3 deletions(-) diff --git a/addons/mail/controllers/discuss.py b/addons/mail/controllers/discuss.py index 6a067ee3854..692b55c8f64 100644 --- a/addons/mail/controllers/discuss.py +++ b/addons/mail/controllers/discuss.py @@ -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() diff --git a/addons/website_livechat/models/mail_channel.py b/addons/website_livechat/models/mail_channel.py index 55c2de88724..25586b1ae5a 100644 --- a/addons/website_livechat/models/mail_channel.py +++ b/addons/website_livechat/models/mail_channel.py @@ -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): diff --git a/addons/website_livechat/tests/common.py b/addons/website_livechat/tests/common.py index d1e4abdf36a..4345fbde022 100644 --- a/addons/website_livechat/tests/common.py +++ b/addons/website_livechat/tests/common.py @@ -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 diff --git a/addons/website_livechat/tests/test_livechat_basic_flow.py b/addons/website_livechat/tests/test_livechat_basic_flow.py index febf1287aa0..5b6182c56c7 100644 --- a/addons/website_livechat/tests/test_livechat_basic_flow.py +++ b/addons/website_livechat/tests/test_livechat_basic_flow.py @@ -83,6 +83,25 @@ class TestLivechatBasicFlowHttpCase(tests.HttpCase, TestLivechatCommon): self.assertEqual(channel.message_ids[0].body, "

%s has left the conversation.

" % 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)