diff options
author | Waqas Hussain <waqas20@gmail.com> | 2012-08-01 01:36:19 +0500 |
---|---|---|
committer | Waqas Hussain <waqas20@gmail.com> | 2012-08-01 01:36:19 +0500 |
commit | f1f8cf4bafc4e605c3b86d42897bd3f85b1a8080 (patch) | |
tree | a154089fb5fc7b7cf6e4ba3353726628a4e44ec0 /plugins/muc | |
parent | 333dd0e428ab1c7ff75cf6ceba1cc8117d490f17 (diff) | |
download | prosody-f1f8cf4bafc4e605c3b86d42897bd3f85b1a8080.tar.gz prosody-f1f8cf4bafc4e605c3b86d42897bd3f85b1a8080.zip |
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
Diffstat (limited to 'plugins/muc')
-rw-r--r-- | plugins/muc/muc.lib.lua | 72 |
1 files changed, 45 insertions, 27 deletions
diff --git a/plugins/muc/muc.lib.lua b/plugins/muc/muc.lib.lua index a40dc05f..dd7a07f1 100644 --- a/plugins/muc/muc.lib.lua +++ b/plugins/muc/muc.lib.lua @@ -347,6 +347,31 @@ function room_mt:set_historylength(length) end +local function construct_stanza_id(room, stanza) + local from_jid, to_nick = stanza.attr.from, stanza.attr.to; + local from_nick = room._jid_nick[from_jid]; + local occupant = room._occupants[to_nick]; + local to_jid = occupant.jid; + + return from_nick, to_jid, base64.encode(to_jid.."\0"..stanza.attr.id.."\0"..md5(from_jid)); +end +local function deconstruct_stanza_id(room, stanza) + local from_jid_possiblybare, to_nick = stanza.attr.from, stanza.attr.to; + local from_jid, id, to_jid_hash = (base64.decode(stanza.attr.id) or ""):match("^(.+)%z(.*)%z(.+)$"); + local from_nick = room._jid_nick[from_jid]; + + if not(from_nick) then return; end + if not(from_jid_possiblybare == from_jid or from_jid_possiblybare == jid_bare(from_jid)) then return; end + + local occupant = room._occupants[to_nick]; + for to_jid in pairs(occupant and occupant.sessions or {}) do + if md5(to_jid) == to_jid_hash then + return from_nick, to_jid, id; + end + end +end + + function room_mt:handle_to_occupant(origin, stanza) -- PM, vCards, etc local from, to = stanza.attr.from, stanza.attr.to; local room = jid_bare(to); @@ -497,24 +522,11 @@ function room_mt:handle_to_occupant(origin, stanza) -- PM, vCards, etc end end elseif not current_nick then -- not in room - if type == "error" or type == "result" then - local id = stanza.name == "iq" and stanza.attr.id and base64.decode(stanza.attr.id); - local _nick, _id, _hash = (id or ""):match("^(.+)%z(.*)%z(.+)$"); - local occupant = self._occupants[stanza.attr.to]; - if occupant and _nick and self._jid_nick[_nick] and _id and _hash then - local id, _to = stanza.attr.id; - for jid in pairs(occupant.sessions) do - if md5(jid) == _hash then - _to = jid; - break; - end - end - if _to then - stanza.attr.to, stanza.attr.from, stanza.attr.id = _to, self._jid_nick[_nick], _id; - self:_route_stanza(stanza); - stanza.attr.to, stanza.attr.from, stanza.attr.id = to, from, id; - end - end + if type == "error" or type == "result" and stanza.name == "iq" then + local id = stanza.attr.id; + stanza.attr.from, stanza.attr.to, stanza.attr.id = deconstruct_stanza_id(self, stanza); + self:_route_stanza(stanza); + stanza.attr.from, stanza.attr.to, stanza.attr.id = from, to, id; else origin.send(st.error_reply(stanza, "cancel", "not-acceptable")); end @@ -527,16 +539,22 @@ function room_mt:handle_to_occupant(origin, stanza) -- PM, vCards, etc local o_data = self._occupants[to]; if o_data then log("debug", "%s sent private stanza to %s (%s)", from, to, o_data.jid); - local jid = o_data.jid; - local bare = jid_bare(jid); - stanza.attr.to, stanza.attr.from = jid, current_nick; - local id = stanza.attr.id; - if stanza.name=='iq' and type=='get' and stanza.tags[1].attr.xmlns == 'vcard-temp' and bare ~= jid then - stanza.attr.to = bare; - stanza.attr.id = base64.encode(jid.."\0"..id.."\0"..md5(from)); + if stanza.name == "iq" then + local id = stanza.attr.id; + stanza.attr.from, stanza.attr.to, stanza.attr.id = construct_stanza_id(self, stanza); + if type == 'get' and stanza.tags[1].attr.xmlns == 'vcard-temp' then + stanza.attr.to = jid_bare(stanza.attr.to); + end + self:_route_stanza(stanza); + stanza.attr.from, stanza.attr.to, stanza.attr.id = from, to, id; + else -- message + stanza.attr.from = current_nick; + for jid in pairs(o_data.sessions) do + stanza.attr.to = jid; + self:_route_stanza(stanza); + end + stanza.attr.from, stanza.attr.to = from, to; end - self:_route_stanza(stanza); - stanza.attr.to, stanza.attr.from, stanza.attr.id = to, from, id; elseif type ~= "error" and type ~= "result" then -- recipient not in room origin.send(st.error_reply(stanza, "cancel", "item-not-found", "Recipient not in room")); end |