[FIX] mail: prevent use of private addresses for followers, recipients,...

- Connect with Admin
- Go to Contacts, edit himself by adding a Private Address
- Create an Internal User without "Access to Private Addresses" right (i.e. User X)
- Go to any app implementing chatter (i.e. Sales)
- Create a SO
- Add the created Private Address as follower
- Make sure User X can access the record (i.e. Sales: Administrator)
- Connect with User X and open the SO
An Access Error is raised while trying to fetch data about the followers.

This commit prevents to:
- add a private address as follower of a record
- add a private address as Recipient in full composer
- propose private addresses when adding a mention to a partner

opw-2428936

closes odoo/odoo#68493

Task-id: 2463622
X-original-commit: 20536e1bbeb641539c0de44364f8376e7cef651b
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
Signed-off-by: Anh Thao PHAM <kitan191@users.noreply.github.com>
This commit is contained in:
Anh Thao Pham (pta)
2021-03-30 07:45:02 +00:00
parent 3816601819
commit 0d528d7007
6 changed files with 23 additions and 6 deletions
+1 -1
View File
@@ -29,7 +29,7 @@ class Followers(models.Model):
res_id = fields.Many2oneReference(
'Related Document ID', index=True, help='Id of the followed resource', model_field='res_model')
partner_id = fields.Many2one(
'res.partner', string='Related Partner', index=True, ondelete='cascade', required=True)
'res.partner', string='Related Partner', index=True, ondelete='cascade', required=True, domain=[('type', '!=', 'private')])
subtype_ids = fields.Many2many(
'mail.message.subtype', string='Subtype',
help="Message subtypes followed, meaning subtypes that will be pushed onto the user's Wall.")
+2 -2
View File
@@ -2560,9 +2560,9 @@ class MailThread(models.AbstractModel):
self.check_access_rights('write')
self.check_access_rule('write')
# filter inactive
# filter inactive and private addresses
if partner_ids and not adding_current:
partner_ids = self.env['res.partner'].sudo().search([('id', 'in', partner_ids), ('active', '=', True)]).ids
partner_ids = self.env['res.partner'].sudo().search([('id', 'in', partner_ids), ('active', '=', True), ('type', '!=', 'private')]).ids
return self._message_subscribe(partner_ids, subtype_ids, customer_ids=customer_ids)
+1 -1
View File
@@ -133,7 +133,7 @@ class Partner(models.Model):
The return format is a list of partner data (as per returned by `mail_partner_format()`).
"""
search_dom = expression.OR([[('name', 'ilike', search)], [('email', 'ilike', search)]])
search_dom = expression.AND([[('active', '=', True)], search_dom])
search_dom = expression.AND([[('active', '=', True), ('type', '!=', 'private')], search_dom])
if channel_id:
search_dom = expression.AND([[('channel_ids', 'in', channel_id)], search_dom])
+2 -1
View File
@@ -39,7 +39,8 @@ class Invite(models.TransientModel):
res_model = fields.Char('Related Document Model', required=True, index=True, help='Model of the followed resource')
res_id = fields.Integer('Related Document ID', index=True, help='Id of the followed resource')
partner_ids = fields.Many2many('res.partner', string='Recipients', help="List of partners that will be added as follower of the current document.")
partner_ids = fields.Many2many('res.partner', string='Recipients', help="List of partners that will be added as follower of the current document.",
domain=[('type', '!=', 'private')])
message = fields.Html('Message')
send_mail = fields.Boolean('Send Email', default=True, help="If checked, the partners will receive an email warning they have been added in the document's followers.")
+2 -1
View File
@@ -131,7 +131,8 @@ class MailComposer(models.TransientModel):
help='Whether the message is an internal note (comment mode only)')
partner_ids = fields.Many2many(
'res.partner', 'mail_compose_message_res_partner_rel',
'wizard_id', 'partner_id', 'Additional Contacts')
'wizard_id', 'partner_id', 'Additional Contacts',
domain=[('type', '!=', 'private')])
# mass mode options
notify = fields.Boolean('Notify followers', help='Notify followers of the document (mass post only)')
auto_delete = fields.Boolean('Delete Emails',
@@ -147,6 +147,21 @@ class BaseFollowersTest(TestMailCommon):
self.assertEqual(document.message_partner_ids, self.partner_portal, 'No active test: customer not visible')
self.assertEqual(document.message_follower_ids.partner_id, self.partner_portal | customer)
@users('employee')
def test_followers_private_address(self):
""" Test standard API does not subscribe private addresses """
private_address = self.env['res.partner'].sudo().create({
'name': 'Private Address',
'type': 'private',
})
document = self.env['mail.test.simple'].browse(self.test_record.id)
document.message_subscribe(partner_ids=(self.partner_portal | private_address).ids)
self.assertEqual(document.message_follower_ids.partner_id, self.partner_portal)
# works through low-level API
document._message_subscribe(partner_ids=(self.partner_portal | private_address).ids)
self.assertEqual(document.message_follower_ids.partner_id, self.partner_portal | private_address)
@tagged('mail_followers')
class AdvancedFollowersTest(TestMailCommon):