diff options
| author | Jérome Maes <jem@openerp.com> | 2016-12-26 11:32:25 +0100 |
|---|---|---|
| committer | Jérome Maes <jem@openerp.com> | 2017-06-30 11:06:32 +0200 |
| commit | d79678fdd5faccffff65a439653fa5d639a3d3c4 (patch) | |
| tree | 7cb3f4a849289dbae3983daefea02c6cbbd21467 /addons/website_mail/controllers/main.py | |
| parent | 890e665b882b27184003cc5de6ad365f2910815d (diff) | |
[IMP] website_mail: make the frontend chatter lazy
Message are now fetched and display using javascript
to optimize performance.
Also the chatter is completely rewrite : add pager,
filter possiblity, ...
This commit is mainly technical: posting feature does
not change. Only the display with pager is new.
The goal is also to prepare frontend chatter for a
better integration with rating widget.
The mail.thread mixin is extended to manage the field
website_message_ids (display all messages that can be
seen on frontend by user (employee or not).
When fetching or posting message, a check is done to see
if we need to do it as sudo(). website_mail implement posting
messages with token or sha_in (using in website_quote).
The same verification is now done when fetching messages, via
'_special_access_object' method.
Diffstat (limited to 'addons/website_mail/controllers/main.py')
| -rw-r--r-- | addons/website_mail/controllers/main.py | 92 |
1 files changed, 65 insertions, 27 deletions
diff --git a/addons/website_mail/controllers/main.py b/addons/website_mail/controllers/main.py index 546def6890a..c0e8354610d 100644 --- a/addons/website_mail/controllers/main.py +++ b/addons/website_mail/controllers/main.py @@ -1,11 +1,18 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from hashlib import sha1 -from time import time -from werkzeug.exceptions import NotFound + +from werkzeug.exceptions import NotFound, Forbidden from odoo import http from odoo.http import request +from odoo.tools import consteq + + +def _special_access_object(res_model, res_id, token='', token_field=''): + record = request.env[res_model].browse(res_id).sudo() + if token and record and getattr(record, token_field, None) and consteq(getattr(record, token_field), token): + return True + return False def _message_post_helper(res_model='', res_id=None, message='', token='', token_field='token', nosubscribe=True, **kw): """ Generic chatter function, allowing to write on *any* object that inherits mail.thread. @@ -27,13 +34,17 @@ def _message_post_helper(res_model='', res_id=None, message='', token='', token_ """ record = request.env[res_model].browse(res_id) author_id = request.env.user.partner_id.id if request.env.user.partner_id else False - if token and record and token == getattr(record.sudo(), token_field, None): - record = record.sudo() - if request.env.user == request.env.ref('base.public_user'): - author_id = record.partner_id.id if hasattr(record, 'partner_id') else author_id + if token_field and token: + access_as_sudo = _special_access_object(res_model, res_id, token=token, token_field=token_field) + if access_as_sudo: + record = record.sudo() + if request.env.user == request.env.ref('base.public_user'): + author_id = record.partner_id.id if hasattr(record, 'partner_id') else author_id + else: + if not author_id: + raise NotFound() else: - if not author_id: - raise NotFound() + raise Forbidden() kw.pop('csrf_token', None) return record.with_context(mail_create_nosubscribe=nosubscribe).message_post(body=message, message_type=kw.pop('message_type', "comment"), @@ -98,25 +109,52 @@ class WebsiteMail(http.Controller): ])) return values - @http.route(['/website_mail/post/json'], type='json', auth='public', website=True) - def chatter_json(self, res_model='', res_id=None, message='', **kw): - try: - msg = _message_post_helper(res_model, int(res_id), message, **kw) - except Exception: - return False - data = { - 'id': msg.id, - 'body': msg.body, - 'date': msg.date, - 'author': msg.author_id.name, - 'image_url': '/mail/%s/%s/avatar/%s' % (msg.model, msg.res_id, msg.author_id.id) - } - return data - @http.route(['/website_mail/post/post'], type='http', methods=['POST'], auth='public', website=True) - def chatter_post(self, res_model='', res_id=None, message='', redirect=None, **kw): + def website_chatter_post(self, res_model, res_id, message, **kw): url = request.httprequest.referrer if message: - message = _message_post_helper(res_model, int(res_id), message, **kw) - url = url + "#message-%s" % (message.id,) + _message_post_helper(res_model, int(res_id), message, **kw) + url = url + "#discussion" return request.redirect(url) + + @http.route('/website_mail/init', type='json', auth='public', website=True) + def website_chatter_init(self, res_model, res_id, domain=False, limit=False, **kwargs): + is_user_public = bool(request.env.user == request.website.user_id) + message_data = self.website_message_fetch(res_model, res_id, domain=domain, limit=limit, **kwargs) + display_composer = False + if kwargs.get('allow_composer'): + display_composer = kwargs.get('token') or not is_user_public + return { + 'messages': message_data['messages'], + 'options': { + 'message_count': message_data['message_count'], + 'is_user_public': is_user_public, + 'is_user_publisher': request.env.user.has_group('website.group_website_publisher'), + 'display_composer': display_composer, + 'partner_id': request.env.user.partner_id.id + } + } + + @http.route('/website_mail/fetch', type='json', auth='public', website=True) + def website_message_fetch(self, res_model, res_id, domain=False, limit=10, offset=0, **kw): + if not domain: + domain = [] + # Only search into website_message_ids, so apply the same domain to perform only one search + # extract domain from the 'website_message_ids' field + field_domain = request.env[res_model]._fields['website_message_ids'].domain + domain += field_domain(request.env[res_model]) if callable(field_domain) else field_domain + domain += [('res_id', '=', res_id)] + # None published can see only the published messages + if not request.env.user.has_group('website.group_website_publisher'): + domain += [('website_published', '=', True)] + # Check access + Message = request.env['mail.message'] + if kw.get('token'): + access_as_sudo = _special_access_object(res_model, res_id, token=kw.get('token'), token_field=kw.get('token_field')) + if not access_as_sudo: # if token is not correct, raise Forbidden + raise Forbidden() + Message = request.env['mail.message'].sudo() + return { + 'messages': Message.search(domain, limit=limit, offset=offset).website_message_format(), + 'message_count': Message.search_count(domain) + } |
