158 lines
7.6 KiB
Python
158 lines
7.6 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
|
|
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.
|
|
If a token 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 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()
|
|
"""
|
|
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_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:
|
|
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"),
|
|
subtype=kw.pop('subtype', "mt_comment"),
|
|
author_id=author_id,
|
|
**kw)
|
|
|
|
|
|
class WebsiteMail(http.Controller):
|
|
|
|
@http.route(['/website_mail/follow'], type='json', auth="public", website=True)
|
|
def website_message_subscribe(self, id=0, object=None, message_is_follower="on", email=False, **post):
|
|
# TDE FIXME: check this method with new followers
|
|
res_id = int(id)
|
|
is_follower = message_is_follower == 'on'
|
|
record = request.env[object].browse(res_id)
|
|
|
|
# search partner_id
|
|
if request.env.user != request.website.user_id:
|
|
partner_ids = request.env.user.partner_id.ids
|
|
else:
|
|
# mail_thread method
|
|
partner_ids = record.sudo()._find_partner_from_emails([email], check_followers=True)
|
|
if not partner_ids or not partner_ids[0]:
|
|
name = email.split('@')[0]
|
|
partner_ids = request.env['res.partner'].sudo().create({'name': name, 'email': email}).ids
|
|
# add or remove follower
|
|
if is_follower:
|
|
record.check_access_rule('read')
|
|
record.sudo().message_unsubscribe(partner_ids)
|
|
return False
|
|
else:
|
|
record.check_access_rule('read')
|
|
# add partner to session
|
|
request.session['partner_id'] = partner_ids[0]
|
|
record.sudo().message_subscribe(partner_ids)
|
|
return True
|
|
|
|
@http.route(['/website_mail/is_follower'], type='json', auth="public", website=True)
|
|
def is_follower(self, model, res_id, **post):
|
|
user = request.env.user
|
|
partner = None
|
|
public_user = request.website.user_id
|
|
if user != public_user:
|
|
partner = request.env.user.partner_id
|
|
elif request.session.get('partner_id'):
|
|
partner = request.env['res.partner'].sudo().browse(request.session.get('partner_id'))
|
|
|
|
values = {
|
|
'is_user': user != public_user,
|
|
'email': partner.email if partner else "",
|
|
'is_follower': False,
|
|
'alias_name': False,
|
|
}
|
|
|
|
record = request.env[model].sudo().browse(int(res_id))
|
|
if record and partner:
|
|
values['is_follower'] = bool(request.env['mail.followers'].search_count([
|
|
('res_model', '=', model),
|
|
('res_id', '=', record.id),
|
|
('partner_id', '=', partner.id)
|
|
]))
|
|
return values
|
|
|
|
@http.route(['/website_mail/post/post'], type='http', methods=['POST'], auth='public', website=True)
|
|
def website_chatter_post(self, res_model, res_id, message, **kw):
|
|
url = request.httprequest.referrer
|
|
if message:
|
|
_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)]
|
|
# 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)
|
|
}
|