[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:
parent
cbba7eb4da
commit
f13dd8cee7
|
@ -27,7 +27,6 @@ from openerp.addons.web.http import request
|
||||||
from openerp.tools.misc import DEFAULT_SERVER_DATETIME_FORMAT
|
from openerp.tools.misc import DEFAULT_SERVER_DATETIME_FORMAT
|
||||||
import datetime
|
import datetime
|
||||||
from openerp.osv import osv, fields, expression
|
from openerp.osv import osv, fields, expression
|
||||||
import time
|
|
||||||
import logging
|
import logging
|
||||||
import json
|
import json
|
||||||
import select
|
import select
|
||||||
|
@ -202,7 +201,7 @@ class im_session(osv.osv):
|
||||||
return res
|
return res
|
||||||
|
|
||||||
_columns = {
|
_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'),
|
"name": fields.function(_calc_name, string="Name", type='char'),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,6 +224,9 @@ class im_session(osv.osv):
|
||||||
}, context=context)
|
}, context=context)
|
||||||
return self.read(cr, uid, session_id, 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):
|
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)
|
my_id = self.pool.get("im.user").get_my_id(cr, uid, uuid, context=context)
|
||||||
session = self.read(cr, uid, session_id, 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))]
|
return ['&', ('im_last_status', '=', True), ('im_last_status_update', '>', (current - delta).strftime(DEFAULT_SERVER_DATETIME_FORMAT))]
|
||||||
else:
|
else:
|
||||||
return ['|', ('im_last_status', '=', False), ('im_last_status_update', '<=', (current - delta).strftime(DEFAULT_SERVER_DATETIME_FORMAT))]
|
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):
|
def search_users(self, cr, uid, text_search, fields, limit, context=None):
|
||||||
my_id = self.get_my_id(cr, uid, None, context)
|
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]
|
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:
|
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]],
|
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)
|
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']))
|
users.sort(key=lambda obj: found.index(obj['id']))
|
||||||
return users
|
return users
|
||||||
|
|
||||||
|
@ -319,6 +321,9 @@ class im_user(osv.osv):
|
||||||
continue
|
continue
|
||||||
return res
|
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 = {
|
_columns = {
|
||||||
'name': fields.function(_get_name, type='char', size=200, string="Name", store=True, readonly=True),
|
'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),
|
'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.'),
|
('user_uniq', 'unique (user_id)', 'Only one chat user per OpenERP user.'),
|
||||||
('uuid_uniq', 'unique (uuid)', 'Chat identifier already used.'),
|
('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"),
|
||||||
|
}
|
||||||
|
|
|
@ -2,10 +2,10 @@
|
||||||
<openerp>
|
<openerp>
|
||||||
<data>
|
<data>
|
||||||
<record id="message_rule_1" model="ir.rule">
|
<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="model_id" ref="model_im_message"/>
|
||||||
<field name="groups" eval="[(6,0,[ref('base.group_user')])]"/>
|
<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_read" eval="1"/>
|
||||||
<field name="perm_write" eval="0"/>
|
<field name="perm_write" eval="0"/>
|
||||||
<field name="perm_create" eval="0"/>
|
<field name="perm_create" eval="0"/>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
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_user,im.user,model_im_user,,1,1,1,0
|
||||||
access_im_session,im.session,model_im_session,,1,0,0,0
|
access_im_session,im.session,model_im_session,,1,0,0,0
|
|
|
@ -92,6 +92,7 @@
|
||||||
search_changed: function(e) {
|
search_changed: function(e) {
|
||||||
var users = new instance.web.Model("im.user");
|
var users = new instance.web.Model("im.user");
|
||||||
var self = this;
|
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"],
|
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) {
|
USERS_LIMIT], {context:new instance.web.CompoundContext()})).then(function(users) {
|
||||||
var logged_users = _.filter(users, function(u) { return !!u.im_status; });
|
var logged_users = _.filter(users, function(u) { return !!u.im_status; });
|
||||||
|
|
|
@ -145,7 +145,7 @@ function declare($, _, openerp) {
|
||||||
if (_.size(no_cache) === 0)
|
if (_.size(no_cache) === 0)
|
||||||
def = $.when();
|
def = $.when();
|
||||||
else
|
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);
|
self.add_to_user_cache(users);
|
||||||
});
|
});
|
||||||
return def.then(function() {
|
return def.then(function() {
|
||||||
|
@ -230,7 +230,8 @@ function declare($, _, openerp) {
|
||||||
return self.chat_with_users(users);
|
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 conv = _.find(this.conversations, function(conv) {return conv.session_id == session_id;});
|
||||||
var def = $.when();
|
var def = $.when();
|
||||||
if (! conv) {
|
if (! conv) {
|
||||||
|
@ -244,6 +245,9 @@ function declare($, _, openerp) {
|
||||||
this.calc_positions();
|
this.calc_positions();
|
||||||
this.trigger("new_conversation", conv);
|
this.trigger("new_conversation", conv);
|
||||||
}, this));
|
}, this));
|
||||||
|
def = def.then(function(){
|
||||||
|
return self.load_history(conv, message);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if (focus) {
|
if (focus) {
|
||||||
def = def.then(function() {
|
def = def.then(function() {
|
||||||
|
@ -252,13 +256,32 @@ function declare($, _, openerp) {
|
||||||
}
|
}
|
||||||
return def.then(function() {return conv});
|
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 self = this;
|
||||||
var defs = [];
|
var defs = [];
|
||||||
var received = false;
|
var received = false;
|
||||||
|
if (_.isUndefined(seen)){
|
||||||
|
seen = false;
|
||||||
|
}
|
||||||
_.each(messages, function(message) {
|
_.each(messages, function(message) {
|
||||||
if (! message.technical) {
|
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];
|
received = self.my_id !== message.from_id[0];
|
||||||
return conv.received_message(message);
|
return conv.received_message(message);
|
||||||
}));
|
}));
|
||||||
|
@ -269,7 +292,7 @@ function declare($, _, openerp) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return $.when.apply($, defs).then(function(){
|
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.set("waiting_messages", self.get("waiting_messages") + messages.length);
|
||||||
self.ting.play();
|
self.ting.play();
|
||||||
self.create_ting();
|
self.create_ting();
|
||||||
|
@ -368,7 +391,7 @@ function declare($, _, openerp) {
|
||||||
refresh_users: function() {
|
refresh_users: function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
var user_ids;
|
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"));
|
user_ids = _.without(session.user_ids, self.c_manager.me.get("id"));
|
||||||
return self.c_manager.ensure_users(user_ids);
|
return self.c_manager.ensure_users(user_ids);
|
||||||
}).then(function(users) {
|
}).then(function(users) {
|
||||||
|
@ -449,7 +472,7 @@ function declare($, _, openerp) {
|
||||||
date = "" + zpad(date.getHours(), 2) + ":" + zpad(date.getMinutes(), 2);
|
date = "" + zpad(date.getHours(), 2) + ":" + zpad(date.getMinutes(), 2);
|
||||||
var to_show = _.map(items, im_common.escape_keep_url);
|
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.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();
|
this._go_bottom();
|
||||||
},
|
},
|
||||||
_go_bottom: function() {
|
_go_bottom: function() {
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
All users are offline. They will receive your messages on their next connection.
|
All users are offline. They will receive your messages on their next connection.
|
||||||
</div>
|
</div>
|
||||||
<div class="oe_im_chatview_content">
|
<div class="oe_im_chatview_content">
|
||||||
<div></div>
|
<div class="oe_im_chatview_conversation"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="oe_im_chatview_footer">
|
<div class="oe_im_chatview_footer">
|
||||||
<input class="oe_im_chatview_input" t-att-placeholder="widget.inputPlaceholder" />
|
<input class="oe_im_chatview_input" t-att-placeholder="widget.inputPlaceholder" />
|
||||||
|
|
|
@ -170,8 +170,8 @@ class im_livechat_channel(osv.osv):
|
||||||
return users
|
return users
|
||||||
|
|
||||||
def get_session(self, cr, uid, channel_id, uuid, context=None):
|
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)
|
self.pool.get("im.user").get_my_id(cr, uid, uuid, context=context)
|
||||||
users = self.get_available_users(cr, uid, channel_id, context=context)
|
users = self.get_available_users(cr, openerp.SUPERUSER_ID, channel_id, context=context)
|
||||||
if len(users) == 0:
|
if len(users) == 0:
|
||||||
return False
|
return False
|
||||||
user_id = random.choice(users).id
|
user_id = random.choice(users).id
|
||||||
|
|
|
@ -125,6 +125,7 @@
|
||||||
<field name="res_model">im.message</field>
|
<field name="res_model">im.message</field>
|
||||||
<field name="view_mode">list</field>
|
<field name="view_mode">list</field>
|
||||||
<field name="domain">[('session_id.channel_id', '!=', None)]</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>
|
</record>
|
||||||
<menuitem name="History" parent="im_livechat" id="history" action="action_history" groups="group_im_livechat_manager"/>
|
<menuitem name="History" parent="im_livechat" id="history" action="action_history" groups="group_im_livechat_manager"/>
|
||||||
|
|
||||||
|
@ -141,5 +142,21 @@
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</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>
|
</data>
|
||||||
</openerp>
|
</openerp>
|
||||||
|
|
|
@ -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_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_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_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_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
|
access_im_user,im_livechat.im.user,im.model_im_user,portal.group_anonymous,1,0,0,0
|
|
|
@ -107,11 +107,14 @@ define(["openerp", "im_common", "underscore", "require", "jquery",
|
||||||
}
|
}
|
||||||
self.manager.activate_session(session_id, true).then(function(conv) {
|
self.manager.activate_session(session_id, true).then(function(conv) {
|
||||||
if (self.options.defaultMessage) {
|
if (self.options.defaultMessage) {
|
||||||
conv.received_message({
|
setTimeout(function(){
|
||||||
message: self.options.defaultMessage,
|
conv.received_message({
|
||||||
date: openerp.datetime_to_str(new Date()),
|
message: self.options.defaultMessage,
|
||||||
from_id: [conv.get("users")[0].get("id"), "Unknown"]
|
date: openerp.datetime_to_str(new Date()),
|
||||||
});
|
from_id: [conv.get("users")[0].get("id"), "Unknown"]
|
||||||
|
});
|
||||||
|
},
|
||||||
|
2500);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue