[FIX] portal: use correct author for comments on shared records
Steps to reproduce ------------------ 1. Create two partners A and B. 2. Create a shareable record, e.g. a sales order, and set A as the customer. 3. Share the record with B. 4. Use the share link sent to B and comment on the record. 5. Your comments will be sent with A as the author. Expected behavior ----------------- Share links sent to a customer should make you comment as that customer. Task-2883044 X-original-commit: df162acc589b74b0e3c1e9687ce6a1980233f5f1 Part-of: odoo/odoo#94695
This commit is contained in:
committed by
Thibault Delavallée
parent
b2c8932db1
commit
7a2650760d
@@ -15,11 +15,11 @@ from odoo.exceptions import AccessError, MissingError, UserError
|
||||
|
||||
def _check_special_access(res_model, res_id, token='', _hash='', pid=False):
|
||||
record = request.env[res_model].browse(res_id).sudo()
|
||||
if token: # Token Case: token is the global one of the document
|
||||
if _hash and pid: # Signed Token Case: hash implies token is signed by partner pid
|
||||
return consteq(_hash, record._sign_token(pid))
|
||||
elif token: # Token Case: token is the global one of the document
|
||||
token_field = request.env[res_model]._mail_post_token_field
|
||||
return (token and record and consteq(record[token_field], token))
|
||||
elif _hash and pid: # Signed Token Case: hash implies token is signed by partner pid
|
||||
return consteq(_hash, record._sign_token(pid))
|
||||
else:
|
||||
raise Forbidden()
|
||||
|
||||
@@ -64,8 +64,11 @@ def _message_post_helper(res_model, res_id, message, token='', _hash=False, pid=
|
||||
# deduce author of message
|
||||
author_id = request.env.user.partner_id.id if request.env.user.partner_id else False
|
||||
|
||||
# Signed Token Case: author_id is forced
|
||||
if _hash and pid:
|
||||
author_id = pid
|
||||
# Token Case: author is document customer (if not logged) or itself even if user has not the access
|
||||
if token:
|
||||
elif token:
|
||||
if request.env.user._is_public():
|
||||
# TODO : After adding the pid and sign_token in access_url when send invoice by email, remove this line
|
||||
# TODO : Author must be Public User (to rename to 'Anonymous')
|
||||
@@ -73,9 +76,6 @@ def _message_post_helper(res_model, res_id, message, token='', _hash=False, pid=
|
||||
else:
|
||||
if not author_id:
|
||||
raise NotFound()
|
||||
# Signed Token Case: author_id is forced
|
||||
elif _hash and pid:
|
||||
author_id = pid
|
||||
|
||||
email_from = None
|
||||
if author_id and 'email_from' not in kw:
|
||||
@@ -101,7 +101,7 @@ def _message_post_helper(res_model, res_id, message, token='', _hash=False, pid=
|
||||
class PortalChatter(http.Controller):
|
||||
|
||||
def _portal_post_filter_params(self):
|
||||
return ['token', 'hash', 'pid']
|
||||
return ['token', 'pid']
|
||||
|
||||
def _portal_post_check_attachments(self, attachment_ids, attachment_tokens):
|
||||
if len(attachment_tokens) != len(attachment_ids):
|
||||
@@ -145,6 +145,7 @@ class PortalChatter(http.Controller):
|
||||
'attachment_ids': False, # will be added afterward
|
||||
}
|
||||
post_values.update((fname, kw.get(fname)) for fname in self._portal_post_filter_params())
|
||||
post_values['_hash'] = kw.get('hash')
|
||||
message = _message_post_helper(**post_values)
|
||||
result.update({'default_message_id': message.id})
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ real applications. """,
|
||||
'rating',
|
||||
# 'snailmail',
|
||||
'mass_mailing',
|
||||
'mass_mailing_sms',
|
||||
'mass_mailing_sms', # adds portal
|
||||
'phone_validation',
|
||||
'sms',
|
||||
],
|
||||
|
||||
@@ -4,6 +4,25 @@
|
||||
from odoo import api, fields, models
|
||||
|
||||
|
||||
class MailTestPortal(models.Model):
|
||||
""" A model intheriting from mail.thread with some fields used for portal
|
||||
sharing, like a partner, ..."""
|
||||
_description = 'Chatter Model for Portal'
|
||||
_name = 'mail.test.portal'
|
||||
_inherit = [
|
||||
'mail.thread',
|
||||
'portal.mixin',
|
||||
]
|
||||
|
||||
name = fields.Char()
|
||||
partner_id = fields.Many2one('res.partner', 'Customer')
|
||||
|
||||
def _compute_access_url(self):
|
||||
self.access_url = False
|
||||
for record in self.filtered('id'):
|
||||
record.access_url = '/my/test_portal/%s' % self.id
|
||||
|
||||
|
||||
class MailTestRating(models.Model):
|
||||
""" A model inheriting from mail.thread with some fields used for SMS
|
||||
gateway, like a partner, a specific mobile phone, ... """
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
access_mail_test_portal_all,mail.test.portal.all,model_mail_test_portal,,1,0,0,0
|
||||
access_mail_test_portal_user,mail.test.portal.user,model_mail_test_portal,base.group_user,1,1,1,1
|
||||
access_mail_test_rating_all,mail.test.rating.all,model_mail_test_rating,,0,0,0,0
|
||||
access_mail_test_rating_portal,mail.test.rating.portal,model_mail_test_rating,base.group_portal,1,0,0,0
|
||||
access_mail_test_rating_user,mail.test.rating.user,model_mail_test_rating,base.group_user,1,1,1,1
|
||||
|
||||
|
@@ -7,6 +7,7 @@ from . import test_phone_blacklist
|
||||
from . import test_mass_mailing
|
||||
from . import test_mass_mailing_statistics
|
||||
from . import test_mass_sms
|
||||
from . import test_portal
|
||||
from . import test_rating
|
||||
from . import test_sms_composer
|
||||
from . import test_sms_management
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import http
|
||||
from odoo.addons.test_mail_full.tests.common import TestMailFullCommon, TestMailFullRecipients
|
||||
from odoo.tests import tagged, users
|
||||
from odoo.tests.common import HttpCase
|
||||
|
||||
|
||||
@tagged('portal')
|
||||
class TestPortal(HttpCase, TestMailFullCommon, TestMailFullRecipients):
|
||||
|
||||
def setUp(self):
|
||||
super(TestPortal, self).setUp()
|
||||
|
||||
self.record_portal = self.env['mail.test.portal'].create({
|
||||
'partner_id': self.partner_1.id,
|
||||
'name': 'Test Portal Record',
|
||||
})
|
||||
|
||||
self.record_portal._portal_ensure_token()
|
||||
|
||||
@users('employee')
|
||||
def test_portal_mixin(self):
|
||||
""" Test internals of portal mixin """
|
||||
customer = self.partner_1.with_env(self.env)
|
||||
record_portal = self.env['mail.test.portal'].create({
|
||||
'partner_id': customer.id,
|
||||
'name': 'Test Portal Record',
|
||||
})
|
||||
|
||||
self.assertFalse(record_portal.access_token)
|
||||
self.assertEqual(record_portal.access_url, '/my/test_portal/%s' % record_portal.id)
|
||||
|
||||
record_portal._portal_ensure_token()
|
||||
self.assertTrue(record_portal.access_token)
|
||||
|
||||
def test_portal_share_comment(self):
|
||||
""" Test posting through portal controller allowing to use a hash to
|
||||
post wihtout access rights. """
|
||||
self.authenticate(None, None)
|
||||
post_url = f"{self.record_portal.get_base_url()}/mail/chatter_post"
|
||||
|
||||
# test as not logged
|
||||
self.opener.post(
|
||||
url=post_url,
|
||||
json={
|
||||
'params': {
|
||||
'csrf_token': http.Request.csrf_token(self),
|
||||
'hash': self.record_portal._sign_token(self.partner_2.id),
|
||||
'message': 'Test',
|
||||
'pid': self.partner_2.id,
|
||||
'redirect': '/',
|
||||
'res_model': self.record_portal._name,
|
||||
'res_id': self.record_portal.id,
|
||||
'token': self.record_portal.access_token,
|
||||
},
|
||||
},
|
||||
)
|
||||
message = self.record_portal.message_ids[0]
|
||||
|
||||
self.assertIn('Test', message.body)
|
||||
self.assertEqual(message.author_id, self.partner_2)
|
||||
Reference in New Issue
Block a user