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 |