diff --git a/addons/im_livechat/tests/test_get_mail_channel.py b/addons/im_livechat/tests/test_get_mail_channel.py
index 9d3571b478d..87f23bc1ba7 100644
--- a/addons/im_livechat/tests/test_get_mail_channel.py
+++ b/addons/im_livechat/tests/test_get_mail_channel.py
@@ -129,10 +129,10 @@ class TestGetMailChannel(TransactionCase):
'email': 'michel@example.com',
'livechat_username': 'Michel at your service',
})
- channel_info = self.livechat_channel.with_user(public_user)._open_livechat_mail_channel(anonymous_name='whatever')
+ channel_info = self.livechat_channel.with_user(public_user).sudo()._open_livechat_mail_channel(anonymous_name='whatever')
channel = self.env['mail.channel'].browse(channel_info['id'])
channel.with_user(operator).message_post(body='Hello', message_type='comment', subtype_xmlid='mail.mt_comment')
- message_formats = channel.with_user(public_user)._channel_fetch_message()
+ message_formats = channel.with_user(public_user).sudo()._channel_fetch_message()
self.assertEqual(len(message_formats), 1)
self.assertEqual(message_formats[0]['author_id'][0], operator.partner_id.id)
self.assertEqual(message_formats[0]['author_id'][1], operator.livechat_username)
diff --git a/addons/mail/models/mail_channel.py b/addons/mail/models/mail_channel.py
index 581c1ebb084..c119460cb7c 100644
--- a/addons/mail/models/mail_channel.py
+++ b/addons/mail/models/mail_channel.py
@@ -73,7 +73,7 @@ class Channel(models.Model):
'mail.channel.partner', 'channel_id', string='Last Seen',
groups='base.group_user')
rtc_session_ids = fields.One2many('mail.channel.rtc.session', 'channel_id', groups="base.group_system")
- is_member = fields.Boolean('Is Member', compute='_compute_is_member', compute_sudo=True)
+ is_member = fields.Boolean('Is Member', compute='_compute_is_member', search='_search_is_member')
member_count = fields.Integer(string="Member Count", compute='_compute_member_count', compute_sudo=True, help="Excluding guests from count.")
group_ids = fields.Many2many(
'res.groups', string='Auto Subscription',
@@ -166,10 +166,38 @@ class Channel(models.Model):
])
)]
- @api.depends('channel_partner_ids')
+ @api.depends_context('uid', 'guest')
+ @api.depends('channel_last_seen_partner_ids')
def _compute_is_member(self):
+ if not self:
+ return
+ if self.env.user._is_public():
+ guest = self.env['mail.guest']._get_guest_from_context()
+ if not guest:
+ self.is_member = False
+ return
+ user_domain = [('guest_id', '=', guest.id)]
+ else:
+ user_domain = [('partner_id', '=', self.env.user.partner_id.id)]
+ members = self.env['mail.channel.partner'].sudo().search(expression.AND([[('channel_id', 'in', self.ids)], user_domain]))
+ is_member_channels = {member.channel_id for member in members}
for channel in self:
- channel.is_member = self.env.user.partner_id in channel.channel_partner_ids
+ channel.is_member = channel in is_member_channels
+
+ def _search_is_member(self, operator, operand):
+ is_in = (operator == '=' and operand) or (operator == '!=' and not operand)
+ if self.env.user._is_public():
+ guest = self.env['mail.guest']._get_guest_from_context()
+ if not guest:
+ return expression.FALSE_DOMAIN if is_in else expression.TRUE_DOMAIN
+ user_domain = [('guest_id', '=', guest.id)]
+ else:
+ user_domain = [('partner_id', '=', self.env.user.partner_id.id)]
+ return [(
+ 'channel_last_seen_partner_ids',
+ 'in' if is_in else 'not in',
+ self.env['mail.channel.partner'].sudo()._search(user_domain)
+ )]
@api.depends('channel_partner_ids')
def _compute_member_count(self):
diff --git a/addons/mail/models/mail_guest.py b/addons/mail/models/mail_guest.py
index c30420a19ef..c1ba4b95779 100644
--- a/addons/mail/models/mail_guest.py
+++ b/addons/mail/models/mail_guest.py
@@ -29,6 +29,13 @@ class MailGuest(models.Model):
timezone = fields.Selection(string="Timezone", selection=_tz_get)
channel_ids = fields.Many2many(string="Channels", comodel_name='mail.channel', relation='mail_channel_partner', column1='guest_id', column2='channel_id', copy=False)
+ def _get_guest_from_context(self):
+ """Returns the current guest record from the context, if applicable."""
+ guest = self.env.context.get('guest')
+ if isinstance(guest, self.pool['mail.guest']):
+ return guest
+ return self.env['mail.guest']
+
def _get_guest_from_request(self, request):
parts = request.httprequest.cookies.get(self._cookie_name, '').split(self._cookie_separator)
if len(parts) != 2:
diff --git a/addons/mail/security/mail_security.xml b/addons/mail/security/mail_security.xml
index 5741befbd94..31a7b11a9db 100644
--- a/addons/mail/security/mail_security.xml
+++ b/addons/mail/security/mail_security.xml
@@ -8,7 +8,7 @@
['|', '|',
('public', '=', 'public'),
-'&', ('public', '=', 'private'), ('channel_partner_ids', 'in', [user.partner_id.id]),
+'&', ('public', '=', 'private'), ('is_member', '=', True),
'&', ('public', '=', 'groups'), ('group_public_id', 'in', [g.id for g in user.groups_id])]
@@ -19,7 +19,7 @@
['|', '|',
('channel_id.public', '=', 'public'),
-'&', ('channel_id.public', '=', 'private'), ('channel_id.channel_partner_ids', 'in', [user.partner_id.id]),
+'&', ('channel_id.public', '=', 'private'), ('channel_id.is_member', '=', True),
'&', ('channel_id.public', '=', 'groups'), ('channel_id.group_public_id', 'in', [g.id for g in user.groups_id])]
diff --git a/addons/mail/tests/test_mail_channel.py b/addons/mail/tests/test_mail_channel.py
index 2b6338f38a7..22021b5e36a 100644
--- a/addons/mail/tests/test_mail_channel.py
+++ b/addons/mail/tests/test_mail_channel.py
@@ -43,7 +43,7 @@ class TestChannelAccessRights(MailCommon):
'public': 'private'})
@mute_logger('odoo.addons.base.models.ir_rule', 'odoo.addons.base.models.ir_model', 'odoo.models')
- @users('user_public')
+ @users('user_portal')
def test_access_public(self):
# Read public group -> ok
self.env['mail.channel'].browse(self.group_public.id).read()
@@ -56,7 +56,7 @@ class TestChannelAccessRights(MailCommon):
self.env['mail.channel'].browse(self.group_private.id).read()
# Read a private group when being a member: ok
- self.group_private.write({'channel_partner_ids': [(4, self.user_public.partner_id.id)]})
+ self.group_private.write({'channel_partner_ids': [(4, self.user_portal.partner_id.id)]})
self.env['mail.channel'].browse(self.group_private.id).read()
# Create group: ko, no access rights