[FIX][ADD] im, im_livechat: fix security rules and add history when opening a conversation

bzr revid: dle@openerp.com-20140128162649-aptjndl85ocmem8a
This commit is contained in:
Denis Ledoux 2014-01-28 17:26:49 +01:00
parent cbba7eb4da
commit f13dd8cee7
10 changed files with 84 additions and 24 deletions

View File

@ -27,7 +27,6 @@ from openerp.addons.web.http import request
from openerp.tools.misc import DEFAULT_SERVER_DATETIME_FORMAT
import datetime
from openerp.osv import osv, fields, expression
import time
import logging
import json
import select
@ -202,7 +201,7 @@ class im_session(osv.osv):
return res
_columns = {
'user_ids': fields.many2many('im.user'),
'user_ids': fields.many2many('im.user', 'im_session_im_user_rel', 'im_session_id', 'im_user_id', 'Users'),
"name": fields.function(_calc_name, string="Name", type='char'),
}
@ -225,6 +224,9 @@ class im_session(osv.osv):
}, context=context)
return self.read(cr, uid, session_id, context=context)
def get_session_users(self, cr, uid, session_id, context=None):
return self.read(cr, openerp.SUPERUSER_ID, session_id, ['user_ids'], context=context)
def add_to_session(self, cr, uid, session_id, user_id, uuid=None, context=None):
my_id = self.pool.get("im.user").get_my_id(cr, uid, uuid, context=context)
session = self.read(cr, uid, session_id, context=context)
@ -259,7 +261,7 @@ class im_user(osv.osv):
return ['&', ('im_last_status', '=', True), ('im_last_status_update', '>', (current - delta).strftime(DEFAULT_SERVER_DATETIME_FORMAT))]
else:
return ['|', ('im_last_status', '=', False), ('im_last_status_update', '<=', (current - delta).strftime(DEFAULT_SERVER_DATETIME_FORMAT))]
# TODO: Remove fields arg in trunk. Also in im.js.
def search_users(self, cr, uid, text_search, fields, limit, context=None):
my_id = self.get_my_id(cr, uid, None, context)
group_employee = self.pool['ir.model.data'].get_object_reference(cr, uid, 'base', 'group_user')[1]
@ -271,7 +273,7 @@ class im_user(osv.osv):
if len(found) < limit:
found += self.search(cr, uid, [["name", "ilike", text_search], ["id", "<>", my_id], ["uuid", "=", False], ["im_status", "=", False], ["id", "not in", found]],
order="name asc", limit=limit-len(found), context=context)
users = self.read(cr, uid, found, fields, context=context)
users = self.read(cr,openerp.SUPERUSER_ID, found, ["name", "user_id", "uuid", "im_status"], context=context)
users.sort(key=lambda obj: found.index(obj['id']))
return users
@ -319,6 +321,9 @@ class im_user(osv.osv):
continue
return res
def get_users(self, cr, uid, ids, context=None):
return self.read(cr,openerp.SUPERUSER_ID, ids, ["name", "im_status", "uuid"], context=context)
_columns = {
'name': fields.function(_get_name, type='char', size=200, string="Name", store=True, readonly=True),
'assigned_name': fields.char(string="Assigned Name", size=200, required=False),
@ -341,3 +346,16 @@ class im_user(osv.osv):
('user_uniq', 'unique (user_id)', 'Only one chat user per OpenERP user.'),
('uuid_uniq', 'unique (uuid)', 'Chat identifier already used.'),
]
class res_users(osv.osv):
_inherit = "res.users"
def _get_im_user(self, cr, uid, ids, field_name, arg, context=None):
result = dict.fromkeys(ids, False)
for index, im_user in enumerate(self.pool['im.user'].search_read(cr, uid, domain=[('user_id', 'in', ids)], fields=['name', 'user_id'], context=context)):
result[ids[index]] = im_user.get('user_id') and (im_user['user_id'][0], im_user['name']) or False
return result
_columns = {
'im_user_id' : fields.function(_get_im_user, type='many2one', string="IM User", relation="im.user"),
}

View File

@ -2,10 +2,10 @@
<openerp>
<data>
<record id="message_rule_1" model="ir.rule">
<field name="name">Can only read messages that you sent or messages sent to you</field>
<field name="name">Can only read messages from a session where user is</field>
<field name="model_id" ref="model_im_message"/>
<field name="groups" eval="[(6,0,[ref('base.group_user')])]"/>
<field name="domain_force">["|", ('to_id.user_id', 'in', [user.id]), ('from_id.user_id', '=', user.id)]</field>
<field name="domain_force">[('session_id.user_ids', 'in', user.im_user_id)]</field>
<field name="perm_read" eval="1"/>
<field name="perm_write" eval="0"/>
<field name="perm_create" eval="0"/>

View File

@ -1,4 +1,4 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_im_message,im.message,model_im_message,base.group_user,1,0,1,0
access_im_message,im.message,model_im_message,,1,0,1,0
access_im_user,im.user,model_im_user,,1,1,1,0
access_im_session,im.session,model_im_session,,1,0,0,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_im_message im.message model_im_message base.group_user 1 0 1 0
3 access_im_user im.user model_im_user 1 1 1 0
4 access_im_session im.session model_im_session 1 0 0 0

View File

@ -92,6 +92,7 @@
search_changed: function(e) {
var users = new instance.web.Model("im.user");
var self = this;
// TODO: Remove fields arg in trunk. Also in im.js.
return this.user_search_dm.add(users.call("search_users", [this.get("current_search"), ["name", "user_id", "uuid", "im_status"],
USERS_LIMIT], {context:new instance.web.CompoundContext()})).then(function(users) {
var logged_users = _.filter(users, function(u) { return !!u.im_status; });

View File

@ -145,7 +145,7 @@ function declare($, _, openerp) {
if (_.size(no_cache) === 0)
def = $.when();
else
def = im_common.connection.model("im.user").call("read", [_.values(no_cache), []]).then(function(users) {
def = im_common.connection.model("im.user").call("get_users", [_.values(no_cache)]).then(function(users) {
self.add_to_user_cache(users);
});
return def.then(function() {
@ -230,7 +230,8 @@ function declare($, _, openerp) {
return self.chat_with_users(users);
});
},
activate_session: function(session_id, focus) {
activate_session: function(session_id, focus, message) {
var self = this;
var conv = _.find(this.conversations, function(conv) {return conv.session_id == session_id;});
var def = $.when();
if (! conv) {
@ -244,6 +245,9 @@ function declare($, _, openerp) {
this.calc_positions();
this.trigger("new_conversation", conv);
}, this));
def = def.then(function(){
return self.load_history(conv, message);
});
}
if (focus) {
def = def.then(function() {
@ -252,13 +256,32 @@ function declare($, _, openerp) {
}
return def.then(function() {return conv});
},
received_messages: function(messages) {
load_history: function(conv, message){
var self = this;
var domain = [["session_id", "=", conv.session_id]];
if (!_.isUndefined(message)){
domain.push(["date", "<", message.date]);
}
return im_common.connection.model("im.message").call("search_read", [domain, [], 0, 10]).then(function(messages){
messages.reverse();
var users = _.unique(_.map(messages, function(message){
return message.from_id[0];
}));
return self.ensure_users(_.without(users, self.me.get("id"))).then(function(){
return self.received_messages(messages, true);
});
});
},
received_messages: function(messages, seen) {
var self = this;
var defs = [];
var received = false;
if (_.isUndefined(seen)){
seen = false;
}
_.each(messages, function(message) {
if (! message.technical) {
defs.push(self.activate_session(message.session_id[0]).then(function(conv) {
defs.push(self.activate_session(message.session_id[0], false, message).then(function(conv) {
received = self.my_id !== message.from_id[0];
return conv.received_message(message);
}));
@ -269,7 +292,7 @@ function declare($, _, openerp) {
}
});
return $.when.apply($, defs).then(function(){
if (! self.get("window_focus") && received) {
if (! self.get("window_focus") && received && !seen) {
self.set("waiting_messages", self.get("waiting_messages") + messages.length);
self.ting.play();
self.create_ting();
@ -368,7 +391,7 @@ function declare($, _, openerp) {
refresh_users: function() {
var self = this;
var user_ids;
return im_common.connection.model("im.session").call("read", [self.session_id]).then(function(session) {
return im_common.connection.model("im.session").call("get_session_users", [self.session_id]).then(function(session) {
user_ids = _.without(session.user_ids, self.c_manager.me.get("id"));
return self.c_manager.ensure_users(user_ids);
}).then(function(users) {
@ -449,7 +472,7 @@ function declare($, _, openerp) {
date = "" + zpad(date.getHours(), 2) + ":" + zpad(date.getMinutes(), 2);
var to_show = _.map(items, im_common.escape_keep_url);
this.last_bubble = $(openerp.qweb.render("im_common.conversation_bubble", {"items": to_show, "user": user, "time": date}));
$(this.$(".oe_im_chatview_content").children()[0]).append(this.last_bubble);
$(this.$(".oe_im_chatview_conversation")).append(this.last_bubble);
this._go_bottom();
},
_go_bottom: function() {

View File

@ -11,7 +11,7 @@
All users are offline. They will receive your messages on their next connection.
</div>
<div class="oe_im_chatview_content">
<div></div>
<div class="oe_im_chatview_conversation"></div>
</div>
<div class="oe_im_chatview_footer">
<input class="oe_im_chatview_input" t-att-placeholder="widget.inputPlaceholder" />

View File

@ -170,8 +170,8 @@ class im_livechat_channel(osv.osv):
return users
def get_session(self, cr, uid, channel_id, uuid, context=None):
my_id = self.pool.get("im.user").get_my_id(cr, uid, uuid, context=context)
users = self.get_available_users(cr, uid, channel_id, context=context)
self.pool.get("im.user").get_my_id(cr, uid, uuid, context=context)
users = self.get_available_users(cr, openerp.SUPERUSER_ID, channel_id, context=context)
if len(users) == 0:
return False
user_id = random.choice(users).id

View File

@ -125,6 +125,7 @@
<field name="res_model">im.message</field>
<field name="view_mode">list</field>
<field name="domain">[('session_id.channel_id', '!=', None)]</field>
<field name="context">{'search_default_group_by_session_id': 1, 'search_default_group_by_date': 1, 'search_default_session_id': 1}</field>
</record>
<menuitem name="History" parent="im_livechat" id="history" action="action_history" groups="group_im_livechat_manager"/>
@ -141,5 +142,21 @@
</field>
</record>
<record id="im_message_search" model="ir.ui.view">
<field name="name">im.message.search</field>
<field name="model">im.message</field>
<field name="arch" type="xml">
<search string="Search history">
<filter name="session_id" string="My Sessions" domain="[('session_id.user_ids','in', uid)]"/>
<field name="from_id"/>
<field name="to_id"/>
<group expand="0" string="Group By...">
<filter name="group_by_session_id" string="Session" domain="[]" context="{'group_by':'session_id'}"/>
<filter name="group_by_date" string="Date" domain="[]" context="{'group_by':'date'}"/>
</group>
</search>
</field>
</record>
</data>
</openerp>

View File

@ -2,7 +2,5 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_ls_chann1,im_livechat.channel,model_im_livechat_channel,,1,0,0,0
access_ls_chann2,im_livechat.channel,model_im_livechat_channel,group_im_livechat,1,1,1,0
access_ls_chann3,im_livechat.channel,model_im_livechat_channel,group_im_livechat_manager,1,1,1,1
access_ls_message_portal,im_livechat.im.message.portal,im.model_im_message,portal.group_portal,0,0,0,0
access_im_user_portal,im_livechat.im.user.portal,im.model_im_user,portal.group_portal,1,0,0,0
access_ls_message,im_livechat.im.message,im.model_im_message,portal.group_anonymous,0,0,0,0
access_im_user,im_livechat.im.user,im.model_im_user,portal.group_anonymous,1,0,0,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_ls_chann1 im_livechat.channel model_im_livechat_channel 1 0 0 0
3 access_ls_chann2 im_livechat.channel model_im_livechat_channel group_im_livechat 1 1 1 0
4 access_ls_chann3 im_livechat.channel model_im_livechat_channel group_im_livechat_manager 1 1 1 1
access_ls_message_portal im_livechat.im.message.portal im.model_im_message portal.group_portal 0 0 0 0
5 access_im_user_portal im_livechat.im.user.portal im.model_im_user portal.group_portal 1 0 0 0
access_ls_message im_livechat.im.message im.model_im_message portal.group_anonymous 0 0 0 0
6 access_im_user im_livechat.im.user im.model_im_user portal.group_anonymous 1 0 0 0

View File

@ -107,11 +107,14 @@ define(["openerp", "im_common", "underscore", "require", "jquery",
}
self.manager.activate_session(session_id, true).then(function(conv) {
if (self.options.defaultMessage) {
conv.received_message({
message: self.options.defaultMessage,
date: openerp.datetime_to_str(new Date()),
from_id: [conv.get("users")[0].get("id"), "Unknown"]
});
setTimeout(function(){
conv.received_message({
message: self.options.defaultMessage,
date: openerp.datetime_to_str(new Date()),
from_id: [conv.get("users")[0].get("id"), "Unknown"]
});
},
2500);
}
});
});