Software /
code /
prosody
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 |