diff --git a/addons/website_mail/controllers/main.py b/addons/website_mail/controllers/main.py
index d87bdec7ca1..7a12f471c23 100644
--- a/addons/website_mail/controllers/main.py
+++ b/addons/website_mail/controllers/main.py
@@ -1,11 +1,74 @@
# -*- 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 openerp import SUPERUSER_ID
from openerp.addons.web import http
from openerp.addons.web.http import request
+def object_shasign(record=False, res_model='', res_id=None, **kw):
+ """ Generate a sha signature using the current time, database secret and the
+ record object or the res_model and res_id parameters
+ Return the sha signature and the time of generation in a tuple"""
+ secret = request.env['ir.config_parameter'].sudo().get_param('database.secret')
+ shasign = False
+ timestamp = int(time())
+ if record:
+ shasign = sha1('%s%s%s%s' % (record._model, record.id, secret, timestamp)).hexdigest()
+ elif res_model and res_id:
+ shasign = sha1('%s%s%s%s' % (res_model, res_id, secret, timestamp)).hexdigest()
+ return (shasign, timestamp)
+
+
+def _message_post_helper(res_model='', res_id=None, message='', token='', token_field='token', sha_in='', sha_time=None, nosubscribe=True, **kw):
+ """ Generic chatter function, allowing to write on *any* object that inherits mail.thread.
+ If a token or a shasign is specified, all logged in users will be able to write a message regardless
+ of access rights; if the user is the public user, the message will be posted under the name
+ of the partner_id of the object (or the public user if there is no partner_id on the object).
+
+ :param string res_model: model name of the object
+ :param int res_id: id of the object
+ :param string message: content of the message
+
+ optional keywords arguments:
+ :param string token: access token if the object's model uses some kind of public access
+ using tokens (usually a uuid4) to bypass access rules
+ :param string token_field: name of the field that contains the token on the object (defaults to 'token')
+ :param string sha_in: sha1 hash of the string composed of res_model, res_id and the dabase secret in ir.config_parameter
+ if you wish to allow public users to write on the object with some security but you don't want
+ to add a token field on the object, the sha-sign prevents public users from writing to any other
+ object that the one specified by res_model and res_id
+ to generate the shasign, you can import the function object_shasign from this file in your controller
+ :param str sha_time: timestamp of sha signature generation (signatures are valid for 24h)
+ :param bool nosubscribe: set False if you want the partner to be set as follower of the object when posting (default to True)
+
+ The rest of the kwargs are passed on to message_post()
+ """
+ res = request.env[res_model].browse(res_id)
+ author_id = request.env.user.partner_id.id
+ if token and res and token == getattr(res.sudo(), token_field, None):
+ res = res.sudo()
+ if request.env.user == request.env['ir.model.data'].xmlid_to_object('base.public_user'):
+ author_id = (res.partner_id and res.partner_id.id) if hasattr(res, 'partner_id') else author_id
+ else:
+ raise NotFound()
+ elif sha_in:
+ timestamp = int(sha_time)
+ secret = request.env['ir.config_parameter'].sudo().get_param('database.secret')
+ shasign = sha1('%s%s%s%s' % (res_model, res_id, secret, timestamp))
+ if sha_in == shasign.hexdigest() and int(time()) < timestamp + 3600 * 24:
+ res = res.sudo()
+ else:
+ raise NotFound()
+ return res.with_context({'mail_create_nosubscribe': nosubscribe}).message_post(body=message,
+ message_type=kw.pop('message_type', False) or "comment",
+ subtype=kw.pop('subtype', False) or "mt_comment",
+ author_id=author_id,
+ **kw)
+
class WebsiteMail(http.Controller):
@http.route(['/website_mail/follow'], type='json', auth="public", website=True)
@@ -79,3 +142,24 @@ class WebsiteMail(http.Controller):
('partner_id', '=', partner_id.id)
], context=context)) == 1
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):
+ res_id = int(res_id)
+ try:
+ msg = _message_post_helper(res_model, res_id, message, **kw)
+ data = {
+ 'body': msg.body,
+ 'date': msg.date,
+ 'author': msg.author_id.name,
+ 'image_url': request.website.image_url(msg.author_id, 'image_small')
+ }
+ return data
+ except Exception:
+ return False
+
+ @http.route(['/website_mail/post/post'], type='http', method=['POST'], auth='public', website=True)
+ def chatter_post(self, res_model='', res_id=None, message='', redirect=None, **kw):
+ res_id = int(res_id)
+ _message_post_helper(res_model, res_id, message, **kw)
+ return request.redirect(request.httprequest.referrer)
diff --git a/addons/website_mail/static/src/js/message_post.js b/addons/website_mail/static/src/js/message_post.js
new file mode 100644
index 00000000000..177101bcce1
--- /dev/null
+++ b/addons/website_mail/static/src/js/message_post.js
@@ -0,0 +1,49 @@
+odoo.define('website_mail_post', function(require) {
+ 'use strict';
+ require('website.website');
+ var qweb = require('qweb');
+ var ajax = require('web.ajax');
+ ajax.loadXML('/website_mail/static/src/xml/chatter_message.xml', qweb);
+
+ if(!$('.o_website_chatter_json').length) {
+ return $.Deferred().reject("DOM doesn't contain '.o_website_chatter_json'");
+ }
+
+ $('.o_website_chatter_json').on('click', function(ev) {
+ ev.preventDefault();
+ var $button = $(this);
+ var $form = $(this).parents().find('.o_website_chatter_form');
+ var action = $form.attr('action');
+ var data = getFormData($form);
+ data.message = data.message.replace(/\n/g," ");
+ if (data.message) {
+ $button.attr('disabled', true);
+ var button_bk = $button.html();
+ $button.prepend(' ');
+ ajax.jsonRpc(action, 'call', data).then(function (result) {
+ if (result) {
+ $('.o_website_chatter_error').fadeOut();
+ var msg = qweb.render('website_mail.thread_message', result);
+ var elem = $(msg).hide().prependTo($('.o_website_comments'));
+ elem.slideToggle();
+ $form.find('textarea').val('');
+ } else {
+ $('o_website_chatter_error').fadeIn();
+ }
+ $button.html(button_bk);
+ $button.attr('disabled', false);
+ });
+ }
+
+ function getFormData($form){
+ var unindexed_array = $form.serializeArray();
+ var indexed_array = {};
+
+ $.map(unindexed_array, function(n, i){
+ indexed_array[n.name] = n.value;
+ });
+
+ return indexed_array;
+ }
+ });
+});
diff --git a/addons/website_mail/static/src/xml/chatter_message.xml b/addons/website_mail/static/src/xml/chatter_message.xml
new file mode 100644
index 00000000000..dec459c0f18
--- /dev/null
+++ b/addons/website_mail/static/src/xml/chatter_message.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+ just now
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/addons/website_mail/views/website_mail.xml b/addons/website_mail/views/website_mail.xml
index 5a5d102908e..5dabf414968 100644
--- a/addons/website_mail/views/website_mail.xml
+++ b/addons/website_mail/views/website_mail.xml
@@ -1,30 +1,83 @@
-
-
+
+
+