equal
deleted
inserted
replaced
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 |