Comparison

plugins/muc/muc.lib.lua @ 5061:186f34d88073

MUC: Fix private IQ and message routing. - All private IQ results are now routed to the resource that send the original request - Private messages are now routed to all of the user's sessions - Much cleaner code
author Waqas Hussain <waqas20@gmail.com>
date Wed, 01 Aug 2012 01:36:19 +0500
parent 4999:d5a3c5c1873c
child 5063:4bc202a7b351
comparison
equal deleted inserted replaced
5060:b0e36777f715 5061:186f34d88073
342 length = math.min(tonumber(length) or default_history_length, self._data_max_history_length or math.huge); 342 length = math.min(tonumber(length) or default_history_length, self._data_max_history_length or math.huge);
343 if length == default_history_length then 343 if length == default_history_length then
344 length = nil; 344 length = nil;
345 end 345 end
346 self._data.history_length = length; 346 self._data.history_length = length;
347 end
348
349
350 local function construct_stanza_id(room, stanza)
351 local from_jid, to_nick = stanza.attr.from, stanza.attr.to;
352 local from_nick = room._jid_nick[from_jid];
353 local occupant = room._occupants[to_nick];
354 local to_jid = occupant.jid;
355
356 return from_nick, to_jid, base64.encode(to_jid.."\0"..stanza.attr.id.."\0"..md5(from_jid));
357 end
358 local function deconstruct_stanza_id(room, stanza)
359 local from_jid_possiblybare, to_nick = stanza.attr.from, stanza.attr.to;
360 local from_jid, id, to_jid_hash = (base64.decode(stanza.attr.id) or ""):match("^(.+)%z(.*)%z(.+)$");
361 local from_nick = room._jid_nick[from_jid];
362
363 if not(from_nick) then return; end
364 if not(from_jid_possiblybare == from_jid or from_jid_possiblybare == jid_bare(from_jid)) then return; end
365
366 local occupant = room._occupants[to_nick];
367 for to_jid in pairs(occupant and occupant.sessions or {}) do
368 if md5(to_jid) == to_jid_hash then
369 return from_nick, to_jid, id;
370 end
371 end
347 end 372 end
348 373
349 374
350 function room_mt:handle_to_occupant(origin, stanza) -- PM, vCards, etc 375 function room_mt:handle_to_occupant(origin, stanza) -- PM, vCards, etc
351 local from, to = stanza.attr.from, stanza.attr.to; 376 local from, to = stanza.attr.from, stanza.attr.to;
495 if type ~= 'visible' and type ~= 'invisible' then -- COMPAT ejabberd can broadcast or forward XEP-0018 presences 520 if type ~= 'visible' and type ~= 'invisible' then -- COMPAT ejabberd can broadcast or forward XEP-0018 presences
496 origin.send(st.error_reply(stanza, "modify", "bad-request")); -- FIXME correct error? 521 origin.send(st.error_reply(stanza, "modify", "bad-request")); -- FIXME correct error?
497 end 522 end
498 end 523 end
499 elseif not current_nick then -- not in room 524 elseif not current_nick then -- not in room
500 if type == "error" or type == "result" then 525 if type == "error" or type == "result" and stanza.name == "iq" then
501 local id = stanza.name == "iq" and stanza.attr.id and base64.decode(stanza.attr.id); 526 local id = stanza.attr.id;
502 local _nick, _id, _hash = (id or ""):match("^(.+)%z(.*)%z(.+)$"); 527 stanza.attr.from, stanza.attr.to, stanza.attr.id = deconstruct_stanza_id(self, stanza);
503 local occupant = self._occupants[stanza.attr.to]; 528 self:_route_stanza(stanza);
504 if occupant and _nick and self._jid_nick[_nick] and _id and _hash then 529 stanza.attr.from, stanza.attr.to, stanza.attr.id = from, to, id;
505 local id, _to = stanza.attr.id;
506 for jid in pairs(occupant.sessions) do
507 if md5(jid) == _hash then
508 _to = jid;
509 break;
510 end
511 end
512 if _to then
513 stanza.attr.to, stanza.attr.from, stanza.attr.id = _to, self._jid_nick[_nick], _id;
514 self:_route_stanza(stanza);
515 stanza.attr.to, stanza.attr.from, stanza.attr.id = to, from, id;
516 end
517 end
518 else 530 else
519 origin.send(st.error_reply(stanza, "cancel", "not-acceptable")); 531 origin.send(st.error_reply(stanza, "cancel", "not-acceptable"));
520 end 532 end
521 elseif stanza.name == "message" and type == "groupchat" then -- groupchat messages not allowed in PM 533 elseif stanza.name == "message" and type == "groupchat" then -- groupchat messages not allowed in PM
522 origin.send(st.error_reply(stanza, "modify", "bad-request")); 534 origin.send(st.error_reply(stanza, "modify", "bad-request"));
525 self:handle_to_occupant(origin, build_unavailable_presence_from_error(stanza)); -- send unavailable 537 self:handle_to_occupant(origin, build_unavailable_presence_from_error(stanza)); -- send unavailable
526 else -- private stanza 538 else -- private stanza
527 local o_data = self._occupants[to]; 539 local o_data = self._occupants[to];
528 if o_data then 540 if o_data then
529 log("debug", "%s sent private stanza to %s (%s)", from, to, o_data.jid); 541 log("debug", "%s sent private stanza to %s (%s)", from, to, o_data.jid);
530 local jid = o_data.jid; 542 if stanza.name == "iq" then
531 local bare = jid_bare(jid); 543 local id = stanza.attr.id;
532 stanza.attr.to, stanza.attr.from = jid, current_nick; 544 stanza.attr.from, stanza.attr.to, stanza.attr.id = construct_stanza_id(self, stanza);
533 local id = stanza.attr.id; 545 if type == 'get' and stanza.tags[1].attr.xmlns == 'vcard-temp' then
534 if stanza.name=='iq' and type=='get' and stanza.tags[1].attr.xmlns == 'vcard-temp' and bare ~= jid then 546 stanza.attr.to = jid_bare(stanza.attr.to);
535 stanza.attr.to = bare; 547 end
536 stanza.attr.id = base64.encode(jid.."\0"..id.."\0"..md5(from)); 548 self:_route_stanza(stanza);
537 end 549 stanza.attr.from, stanza.attr.to, stanza.attr.id = from, to, id;
538 self:_route_stanza(stanza); 550 else -- message
539 stanza.attr.to, stanza.attr.from, stanza.attr.id = to, from, id; 551 stanza.attr.from = current_nick;
552 for jid in pairs(o_data.sessions) do
553 stanza.attr.to = jid;
554 self:_route_stanza(stanza);
555 end
556 stanza.attr.from, stanza.attr.to = from, to;
557 end
540 elseif type ~= "error" and type ~= "result" then -- recipient not in room 558 elseif type ~= "error" and type ~= "result" then -- recipient not in room
541 origin.send(st.error_reply(stanza, "cancel", "item-not-found", "Recipient not in room")); 559 origin.send(st.error_reply(stanza, "cancel", "item-not-found", "Recipient not in room"));
542 end 560 end
543 end 561 end
544 end 562 end