Mercurial > prosody-hg
comparison plugins/muc/muc.lib.lua @ 6119:c13f5d6b9b16
plugins/muc/muc.lib: Use `get_occupant_jid` method instead of indexing _jid_nick
| author | daurnimator <quae@daurnimator.com> |
|---|---|
| date | Wed, 19 Mar 2014 15:00:53 -0400 |
| parents | aae3d6daa50d |
| children | 4520439227fc |
comparison
equal
deleted
inserted
replaced
| 6118:aae3d6daa50d | 6119:c13f5d6b9b16 |
|---|---|
| 67 | 67 |
| 68 function room_mt:__tostring() | 68 function room_mt:__tostring() |
| 69 return "MUC room ("..self.jid..")"; | 69 return "MUC room ("..self.jid..")"; |
| 70 end | 70 end |
| 71 | 71 |
| 72 function room_mt:get_occupant_jid(real_jid) | |
| 73 return self._jid_nick[real_jid] | |
| 74 end | |
| 75 | |
| 72 function room_mt:get_default_role(affiliation) | 76 function room_mt:get_default_role(affiliation) |
| 73 if affiliation == "owner" or affiliation == "admin" then | 77 if affiliation == "owner" or affiliation == "admin" then |
| 74 return "moderator"; | 78 return "moderator"; |
| 75 elseif affiliation == "member" then | 79 elseif affiliation == "member" then |
| 76 return "participant"; | 80 return "participant"; |
| 132 end | 136 end |
| 133 end | 137 end |
| 134 end | 138 end |
| 135 | 139 |
| 136 function room_mt:send_occupant_list(to) | 140 function room_mt:send_occupant_list(to) |
| 137 local current_nick = self._jid_nick[to]; | 141 local current_nick = self:get_occupant_jid(to); |
| 138 for occupant, o_data in pairs(self._occupants) do | 142 for occupant, o_data in pairs(self._occupants) do |
| 139 if occupant ~= current_nick then | 143 if occupant ~= current_nick then |
| 140 local pres = get_filtered_presence(o_data.sessions[o_data.jid]); | 144 local pres = get_filtered_presence(o_data.sessions[o_data.jid]); |
| 141 pres.attr.to, pres.attr.from = to, occupant; | 145 pres.attr.to, pres.attr.from = to, occupant; |
| 142 pres:tag("x", {xmlns='http://jabber.org/protocol/muc#user'}) | 146 pres:tag("x", {xmlns='http://jabber.org/protocol/muc#user'}) |
| 381 return self._data.whois; | 385 return self._data.whois; |
| 382 end | 386 end |
| 383 | 387 |
| 384 function room_mt:handle_unavailable_to_occupant(origin, stanza) | 388 function room_mt:handle_unavailable_to_occupant(origin, stanza) |
| 385 local from = stanza.attr.from; | 389 local from = stanza.attr.from; |
| 386 local current_nick = self._jid_nick[from]; | 390 local current_nick = self:get_occupant_jid(from); |
| 387 if not current_nick then | 391 if not current_nick then |
| 388 return true; -- discard | 392 return true; -- discard |
| 389 end | 393 end |
| 390 local pr = get_filtered_presence(stanza); | 394 local pr = get_filtered_presence(stanza); |
| 391 pr.attr.from = current_nick; | 395 pr.attr.from = current_nick; |
| 512 end | 516 end |
| 513 end | 517 end |
| 514 | 518 |
| 515 function room_mt:handle_available_to_occupant(origin, stanza) | 519 function room_mt:handle_available_to_occupant(origin, stanza) |
| 516 local from, to = stanza.attr.from, stanza.attr.to; | 520 local from, to = stanza.attr.from, stanza.attr.to; |
| 517 local current_nick = self._jid_nick[from]; | 521 local current_nick = self:get_occupant_jid(from); |
| 518 if current_nick then | 522 if current_nick then |
| 519 --if #pr == #stanza or current_nick ~= to then -- commented because google keeps resending directed presence | 523 --if #pr == #stanza or current_nick ~= to then -- commented because google keeps resending directed presence |
| 520 if current_nick == to then -- simple presence | 524 if current_nick == to then -- simple presence |
| 521 return self:handle_occupant_presence(origin, stanza) | 525 return self:handle_occupant_presence(origin, stanza) |
| 522 else -- change nick | 526 else -- change nick |
| 574 | 578 |
| 575 function room_mt:handle_iq_to_occupant(origin, stanza) | 579 function room_mt:handle_iq_to_occupant(origin, stanza) |
| 576 local from, to = stanza.attr.from, stanza.attr.to; | 580 local from, to = stanza.attr.from, stanza.attr.to; |
| 577 local type = stanza.attr.type; | 581 local type = stanza.attr.type; |
| 578 local id = stanza.attr.id; | 582 local id = stanza.attr.id; |
| 579 local current_nick = self._jid_nick[from]; | 583 local current_nick = self:get_occupant_jid(from); |
| 580 local o_data = self._occupants[to]; | 584 local o_data = self._occupants[to]; |
| 581 if (type == "error" or type == "result") then | 585 if (type == "error" or type == "result") then |
| 582 do -- deconstruct_stanza_id | 586 do -- deconstruct_stanza_id |
| 583 if not current_nick or not o_data then return nil; end | 587 if not current_nick or not o_data then return nil; end |
| 584 local from_jid, id, to_jid_hash = (base64.decode(stanza.attr.id) or ""):match("^(.+)%z(.*)%z(.+)$"); | 588 local from_jid, id, to_jid_hash = (base64.decode(stanza.attr.id) or ""):match("^(.+)%z(.*)%z(.+)$"); |
| 620 end | 624 end |
| 621 end | 625 end |
| 622 | 626 |
| 623 function room_mt:handle_message_to_occupant(origin, stanza) | 627 function room_mt:handle_message_to_occupant(origin, stanza) |
| 624 local from, to = stanza.attr.from, stanza.attr.to; | 628 local from, to = stanza.attr.from, stanza.attr.to; |
| 625 local current_nick = self._jid_nick[from]; | 629 local current_nick = self:get_occupant_jid(from); |
| 626 local type = stanza.attr.type; | 630 local type = stanza.attr.type; |
| 627 if not current_nick then -- not in room | 631 if not current_nick then -- not in room |
| 628 if type ~= "error" then | 632 if type ~= "error" then |
| 629 origin.send(st.error_reply(stanza, "cancel", "not-acceptable")); | 633 origin.send(st.error_reply(stanza, "cancel", "not-acceptable")); |
| 630 end | 634 end |
| 834 end | 838 end |
| 835 if not item.attr.jid and item.attr.nick then -- COMPAT Workaround for Miranda sending 'nick' instead of 'jid' when changing affiliation | 839 if not item.attr.jid and item.attr.nick then -- COMPAT Workaround for Miranda sending 'nick' instead of 'jid' when changing affiliation |
| 836 local occupant = self._occupants[self.jid.."/"..item.attr.nick]; | 840 local occupant = self._occupants[self.jid.."/"..item.attr.nick]; |
| 837 if occupant then item.attr.jid = occupant.jid; end | 841 if occupant then item.attr.jid = occupant.jid; end |
| 838 elseif not item.attr.nick and item.attr.jid then | 842 elseif not item.attr.nick and item.attr.jid then |
| 839 local nick = self._jid_nick[item.attr.jid]; | 843 local nick = self:get_occupant_jid(item.attr.jid); |
| 840 if nick then item.attr.nick = select(3, jid_split(nick)); end | 844 if nick then item.attr.nick = select(3, jid_split(nick)); end |
| 841 end | 845 end |
| 842 local actor = stanza.attr.from; | 846 local actor = stanza.attr.from; |
| 843 local callback = function() origin.send(st.reply(stanza)); end | 847 local callback = function() origin.send(st.reply(stanza)); end |
| 844 local reason = item:get_child_text("reason"); | 848 local reason = item:get_child_text("reason"); |
| 857 end | 861 end |
| 858 | 862 |
| 859 function room_mt:handle_admin_item_get_command(origin, stanza) | 863 function room_mt:handle_admin_item_get_command(origin, stanza) |
| 860 local actor = stanza.attr.from; | 864 local actor = stanza.attr.from; |
| 861 local affiliation = self:get_affiliation(actor); | 865 local affiliation = self:get_affiliation(actor); |
| 862 local current_nick = self._jid_nick[actor]; | 866 local current_nick = self:get_occupant_jid(actor); |
| 863 local role = current_nick and self._occupants[current_nick].role or self:get_default_role(affiliation); | 867 local role = current_nick and self._occupants[current_nick].role or self:get_default_role(affiliation); |
| 864 local item = stanza.tags[1].tags[1]; | 868 local item = stanza.tags[1].tags[1]; |
| 865 local _aff = item.attr.affiliation; | 869 local _aff = item.attr.affiliation; |
| 866 local _rol = item.attr.role; | 870 local _rol = item.attr.role; |
| 867 if _aff and not _rol then | 871 if _aff and not _rol then |
| 937 end | 941 end |
| 938 end | 942 end |
| 939 | 943 |
| 940 function room_mt:handle_groupchat_to_room(origin, stanza) | 944 function room_mt:handle_groupchat_to_room(origin, stanza) |
| 941 local from = stanza.attr.from; | 945 local from = stanza.attr.from; |
| 942 local current_nick = self._jid_nick[from]; | 946 local current_nick = self:get_occupant_jid(from); |
| 943 local occupant = self._occupants[current_nick]; | 947 local occupant = self._occupants[current_nick]; |
| 944 if not occupant then -- not in room | 948 if not occupant then -- not in room |
| 945 origin.send(st.error_reply(stanza, "cancel", "not-acceptable")); | 949 origin.send(st.error_reply(stanza, "cancel", "not-acceptable")); |
| 946 return true; | 950 return true; |
| 947 elseif occupant.role == "visitor" then | 951 elseif occupant.role == "visitor" then |
| 967 end | 971 end |
| 968 end | 972 end |
| 969 | 973 |
| 970 -- hack - some buggy clients send presence updates to the room rather than their nick | 974 -- hack - some buggy clients send presence updates to the room rather than their nick |
| 971 function room_mt:handle_presence_to_room(origin, stanza) | 975 function room_mt:handle_presence_to_room(origin, stanza) |
| 972 local current_nick = self._jid_nick[stanza.attr.from]; | 976 local current_nick = self:get_occupant_jid(stanza.attr.from); |
| 973 local handled | 977 local handled |
| 974 if current_nick then | 978 if current_nick then |
| 975 local to = stanza.attr.to; | 979 local to = stanza.attr.to; |
| 976 stanza.attr.to = current_nick; | 980 stanza.attr.to = current_nick; |
| 977 handled = self:handle_presence_to_occupant(origin, stanza); | 981 handled = self:handle_presence_to_occupant(origin, stanza); |
| 980 return handled; | 984 return handled; |
| 981 end | 985 end |
| 982 | 986 |
| 983 function room_mt:handle_mediated_invite(origin, stanza, payload) | 987 function room_mt:handle_mediated_invite(origin, stanza, payload) |
| 984 local _from, _to = stanza.attr.from, stanza.attr.to; | 988 local _from, _to = stanza.attr.from, stanza.attr.to; |
| 985 if not self._jid_nick[_from] then -- Should be in room to send invite TODO: allow admins to send at any time | 989 local current_nick = self:get_occupant_jid(_from) |
| 990 if not current_nick then -- Should be in room to send invite TODO: allow admins to send at any time | |
| 986 origin.send(st.error_reply(stanza, "auth", "forbidden")); | 991 origin.send(st.error_reply(stanza, "auth", "forbidden")); |
| 987 return true; | 992 return true; |
| 988 end | 993 end |
| 989 local _invitee = jid_prep(payload.attr.to); | 994 local _invitee = jid_prep(payload.attr.to); |
| 990 if _invitee then | 995 if _invitee then |
| 1005 :tag('body') -- Add a plain message for clients which don't support invites | 1010 :tag('body') -- Add a plain message for clients which don't support invites |
| 1006 :text(_from..' invited you to the room '.._to..(_reason and (' ('.._reason..')') or "")) | 1011 :text(_from..' invited you to the room '.._to..(_reason and (' ('.._reason..')') or "")) |
| 1007 :up(); | 1012 :up(); |
| 1008 if self:get_members_only() and not self:get_affiliation(_invitee) then | 1013 if self:get_members_only() and not self:get_affiliation(_invitee) then |
| 1009 log("debug", "%s invited %s into members only room %s, granting membership", _from, _invitee, _to); | 1014 log("debug", "%s invited %s into members only room %s, granting membership", _from, _invitee, _to); |
| 1010 self:set_affiliation(_from, _invitee, "member", nil, "Invited by " .. self._jid_nick[_from]) | 1015 self:set_affiliation(_from, _invitee, "member", nil, "Invited by " .. current_nick) |
| 1011 end | 1016 end |
| 1012 self:_route_stanza(invite); | 1017 self:_route_stanza(invite); |
| 1013 return true; | 1018 return true; |
| 1014 else | 1019 else |
| 1015 origin.send(st.error_reply(stanza, "cancel", "jid-malformed")); | 1020 origin.send(st.error_reply(stanza, "cancel", "jid-malformed")); |
| 1155 local occupant = self._occupants[occupant_jid]; | 1160 local occupant = self._occupants[occupant_jid]; |
| 1156 if not occupant or not actor_jid then return nil, "modify", "not-acceptable"; end | 1161 if not occupant or not actor_jid then return nil, "modify", "not-acceptable"; end |
| 1157 | 1162 |
| 1158 if actor_jid == true then return true; end | 1163 if actor_jid == true then return true; end |
| 1159 | 1164 |
| 1160 local actor = self._occupants[self._jid_nick[actor_jid]]; | 1165 local actor = self._occupants[self:get_occupant_jid(actor_jid)]; |
| 1161 if actor.role == "moderator" then | 1166 if actor.role == "moderator" then |
| 1162 if occupant.affiliation ~= "owner" and occupant.affiliation ~= "admin" then | 1167 if occupant.affiliation ~= "owner" and occupant.affiliation ~= "admin" then |
| 1163 if actor.affiliation == "owner" or actor.affiliation == "admin" then | 1168 if actor.affiliation == "owner" or actor.affiliation == "admin" then |
| 1164 return true; | 1169 return true; |
| 1165 elseif occupant.role ~= "moderator" and role ~= "moderator" then | 1170 elseif occupant.role ~= "moderator" and role ~= "moderator" then |
| 1210 end | 1215 end |
| 1211 | 1216 |
| 1212 function room_mt:_route_stanza(stanza) | 1217 function room_mt:_route_stanza(stanza) |
| 1213 local muc_child; | 1218 local muc_child; |
| 1214 if stanza.name == "presence" then | 1219 if stanza.name == "presence" then |
| 1215 local to_occupant = self._occupants[self._jid_nick[stanza.attr.to]]; | 1220 local to_occupant = self._occupants[self:get_occupant_jid(stanza.attr.to)]; |
| 1216 local from_occupant = self._occupants[stanza.attr.from]; | 1221 local from_occupant = self._occupants[stanza.attr.from]; |
| 1217 if to_occupant and from_occupant then | 1222 if to_occupant and from_occupant then |
| 1218 if self:get_whois() == 'anyone' then | 1223 if self:get_whois() == 'anyone' then |
| 1219 muc_child = stanza:get_child("x", "http://jabber.org/protocol/muc#user"); | 1224 muc_child = stanza:get_child("x", "http://jabber.org/protocol/muc#user"); |
| 1220 else | 1225 else |
