Software /
code /
prosody
Comparison
plugins/muc/muc.lib.lua @ 6095:7900ebc544ce
plugins/muc/muc.lib: Split out the room iq handler into functions
author | daurnimator <quae@daurnimator.com> |
---|---|
date | Fri, 21 Feb 2014 15:48:26 -0500 |
parent | 6094:db2faeb151b6 |
child | 6096:84f9123637d4 |
comparison
equal
deleted
inserted
replaced
6094:db2faeb151b6 | 6095:7900ebc544ce |
---|---|
852 end | 852 end |
853 self:set_persistent(false); | 853 self:set_persistent(false); |
854 module:fire_event("muc-room-destroyed", { room = self }); | 854 module:fire_event("muc-room-destroyed", { room = self }); |
855 end | 855 end |
856 | 856 |
857 function room_mt:handle_admin_item_set_command(origin, stanza) | |
858 local item = stanza.tags[1].tags[1]; | |
859 if item.attr.jid then -- Validate provided JID | |
860 item.attr.jid = jid_prep(item.attr.jid); | |
861 if not item.attr.jid then | |
862 origin.send(st.error_reply(stanza, "modify", "jid-malformed")); | |
863 return true; | |
864 end | |
865 end | |
866 if not item.attr.jid and item.attr.nick then -- COMPAT Workaround for Miranda sending 'nick' instead of 'jid' when changing affiliation | |
867 local occupant = self._occupants[self.jid.."/"..item.attr.nick]; | |
868 if occupant then item.attr.jid = occupant.jid; end | |
869 elseif not item.attr.nick and item.attr.jid then | |
870 local nick = self._jid_nick[item.attr.jid]; | |
871 if nick then item.attr.nick = select(3, jid_split(nick)); end | |
872 end | |
873 local actor = stanza.attr.from; | |
874 local callback = function() origin.send(st.reply(stanza)); end | |
875 local reason = item.tags[1] and item.tags[1].name == "reason" and #item.tags[1] == 1 and item.tags[1][1]; | |
876 if item.attr.affiliation and item.attr.jid and not item.attr.role then | |
877 local success, errtype, err = self:set_affiliation(actor, item.attr.jid, item.attr.affiliation, callback, reason); | |
878 if not success then origin.send(st.error_reply(stanza, errtype, err)); end | |
879 return true; | |
880 elseif item.attr.role and item.attr.nick and not item.attr.affiliation then | |
881 local success, errtype, err = self:set_role(actor, self.jid.."/"..item.attr.nick, item.attr.role, callback, reason); | |
882 if not success then origin.send(st.error_reply(stanza, errtype, err)); end | |
883 return true; | |
884 else | |
885 origin.send(st.error_reply(stanza, "cancel", "bad-request")); | |
886 return true; | |
887 end | |
888 end | |
889 | |
890 function room_mt:handle_admin_item_get_command(origin, stanza) | |
891 local actor = stanza.attr.from; | |
892 local affiliation = self:get_affiliation(actor); | |
893 local current_nick = self._jid_nick[actor]; | |
894 local role = current_nick and self._occupants[current_nick].role or self:get_default_role(affiliation); | |
895 local item = stanza.tags[1].tags[1]; | |
896 local _aff = item.attr.affiliation; | |
897 local _rol = item.attr.role; | |
898 if _aff and not _rol then | |
899 if affiliation == "owner" or (affiliation == "admin" and _aff ~= "owner" and _aff ~= "admin") then | |
900 local reply = st.reply(stanza):query("http://jabber.org/protocol/muc#admin"); | |
901 for jid, affiliation in pairs(self._affiliations) do | |
902 if affiliation == _aff then | |
903 reply:tag("item", {affiliation = _aff, jid = jid}):up(); | |
904 end | |
905 end | |
906 origin.send(reply); | |
907 return true; | |
908 else | |
909 origin.send(st.error_reply(stanza, "auth", "forbidden")); | |
910 return true; | |
911 end | |
912 elseif _rol and not _aff then | |
913 if role == "moderator" then | |
914 -- TODO allow admins and owners not in room? Provide read-only access to everyone who can see the participants anyway? | |
915 if _rol == "none" then _rol = nil; end | |
916 local reply = st.reply(stanza):query("http://jabber.org/protocol/muc#admin"); | |
917 for occupant_jid, occupant in pairs(self._occupants) do | |
918 if occupant.role == _rol then | |
919 reply:tag("item", { | |
920 nick = select(3, jid_split(occupant_jid)), | |
921 role = _rol or "none", | |
922 affiliation = occupant.affiliation or "none", | |
923 jid = occupant.jid | |
924 }):up(); | |
925 end | |
926 end | |
927 origin.send(reply); | |
928 return true; | |
929 else | |
930 origin.send(st.error_reply(stanza, "auth", "forbidden")); | |
931 return true; | |
932 end | |
933 else | |
934 origin.send(st.error_reply(stanza, "cancel", "bad-request")); | |
935 return true; | |
936 end | |
937 end | |
938 | |
939 function room_mt:handle_owner_query_get_to_room(origin, stanza) | |
940 if self:get_affiliation(stanza.attr.from) ~= "owner" then | |
941 origin.send(st.error_reply(stanza, "auth", "forbidden", "Only owners can configure rooms")); | |
942 return true; | |
943 end | |
944 | |
945 self:send_form(origin, stanza); | |
946 return true; | |
947 end | |
948 function room_mt:handle_owner_query_set_to_room(origin, stanza) | |
949 if self:get_affiliation(stanza.attr.from) ~= "owner" then | |
950 origin.send(st.error_reply(stanza, "auth", "forbidden", "Only owners can configure rooms")); | |
951 return true; | |
952 end | |
953 | |
954 local child = stanza.tags[1].tags[1]; | |
955 if not child then | |
956 origin.send(st.error_reply(stanza, "modify", "bad-request")); | |
957 return true; | |
958 elseif child.name == "destroy" then | |
959 local newjid = child.attr.jid; | |
960 local reason, password; | |
961 for _,tag in ipairs(child.tags) do | |
962 if tag.name == "reason" then | |
963 reason = #tag.tags == 0 and tag[1]; | |
964 elseif tag.name == "password" then | |
965 password = #tag.tags == 0 and tag[1]; | |
966 end | |
967 end | |
968 self:destroy(newjid, reason, password); | |
969 origin.send(st.reply(stanza)); | |
970 return true; | |
971 else | |
972 self:process_form(origin, stanza); | |
973 return true; | |
974 end | |
975 end | |
976 | |
857 function room_mt:handle_iq_to_room(origin, stanza) | 977 function room_mt:handle_iq_to_room(origin, stanza) |
858 local type = stanza.attr.type; | 978 local type = stanza.attr.type; |
859 local xmlns = stanza.tags[1] and stanza.tags[1].attr.xmlns; | 979 local xmlns = stanza.tags[1] and stanza.tags[1].attr.xmlns; |
860 if xmlns == "http://jabber.org/protocol/disco#info" and type == "get" and not stanza.tags[1].attr.node then | 980 if xmlns == "http://jabber.org/protocol/disco#info" and type == "get" and not stanza.tags[1].attr.node then |
861 origin.send(self:get_disco_info(stanza)); | 981 origin.send(self:get_disco_info(stanza)); |
982 return true; | |
862 elseif xmlns == "http://jabber.org/protocol/disco#items" and type == "get" and not stanza.tags[1].attr.node then | 983 elseif xmlns == "http://jabber.org/protocol/disco#items" and type == "get" and not stanza.tags[1].attr.node then |
863 origin.send(self:get_disco_items(stanza)); | 984 origin.send(self:get_disco_items(stanza)); |
985 return true; | |
864 elseif xmlns == "http://jabber.org/protocol/muc#admin" then | 986 elseif xmlns == "http://jabber.org/protocol/muc#admin" then |
865 local actor = stanza.attr.from; | |
866 local affiliation = self:get_affiliation(actor); | |
867 local current_nick = self._jid_nick[actor]; | |
868 local role = current_nick and self._occupants[current_nick].role or self:get_default_role(affiliation); | |
869 local item = stanza.tags[1].tags[1]; | 987 local item = stanza.tags[1].tags[1]; |
870 if item and item.name == "item" then | 988 if item and item.name == "item" then |
871 if type == "set" then | 989 if type == "set" then |
872 local callback = function() origin.send(st.reply(stanza)); end | 990 return self:handle_admin_item_set_command(origin, stanza) |
873 if item.attr.jid then -- Validate provided JID | |
874 item.attr.jid = jid_prep(item.attr.jid); | |
875 if not item.attr.jid then | |
876 origin.send(st.error_reply(stanza, "modify", "jid-malformed")); | |
877 return; | |
878 end | |
879 end | |
880 if not item.attr.jid and item.attr.nick then -- COMPAT Workaround for Miranda sending 'nick' instead of 'jid' when changing affiliation | |
881 local occupant = self._occupants[self.jid.."/"..item.attr.nick]; | |
882 if occupant then item.attr.jid = occupant.jid; end | |
883 elseif not item.attr.nick and item.attr.jid then | |
884 local nick = self._jid_nick[item.attr.jid]; | |
885 if nick then item.attr.nick = select(3, jid_split(nick)); end | |
886 end | |
887 local reason = item.tags[1] and item.tags[1].name == "reason" and #item.tags[1] == 1 and item.tags[1][1]; | |
888 if item.attr.affiliation and item.attr.jid and not item.attr.role then | |
889 local success, errtype, err = self:set_affiliation(actor, item.attr.jid, item.attr.affiliation, callback, reason); | |
890 if not success then origin.send(st.error_reply(stanza, errtype, err)); end | |
891 elseif item.attr.role and item.attr.nick and not item.attr.affiliation then | |
892 local success, errtype, err = self:set_role(actor, self.jid.."/"..item.attr.nick, item.attr.role, callback, reason); | |
893 if not success then origin.send(st.error_reply(stanza, errtype, err)); end | |
894 else | |
895 origin.send(st.error_reply(stanza, "cancel", "bad-request")); | |
896 end | |
897 elseif type == "get" then | 991 elseif type == "get" then |
898 local _aff = item.attr.affiliation; | 992 return self:handle_admin_item_get_command(origin, stanza) |
899 local _rol = item.attr.role; | |
900 if _aff and not _rol then | |
901 if affiliation == "owner" or (affiliation == "admin" and _aff ~= "owner" and _aff ~= "admin") then | |
902 local reply = st.reply(stanza):query("http://jabber.org/protocol/muc#admin"); | |
903 for jid, affiliation in pairs(self._affiliations) do | |
904 if affiliation == _aff then | |
905 reply:tag("item", {affiliation = _aff, jid = jid}):up(); | |
906 end | |
907 end | |
908 origin.send(reply); | |
909 else | |
910 origin.send(st.error_reply(stanza, "auth", "forbidden")); | |
911 end | |
912 elseif _rol and not _aff then | |
913 if role == "moderator" then | |
914 -- TODO allow admins and owners not in room? Provide read-only access to everyone who can see the participants anyway? | |
915 if _rol == "none" then _rol = nil; end | |
916 local reply = st.reply(stanza):query("http://jabber.org/protocol/muc#admin"); | |
917 for occupant_jid, occupant in pairs(self._occupants) do | |
918 if occupant.role == _rol then | |
919 reply:tag("item", { | |
920 nick = select(3, jid_split(occupant_jid)), | |
921 role = _rol or "none", | |
922 affiliation = occupant.affiliation or "none", | |
923 jid = occupant.jid | |
924 }):up(); | |
925 end | |
926 end | |
927 origin.send(reply); | |
928 else | |
929 origin.send(st.error_reply(stanza, "auth", "forbidden")); | |
930 end | |
931 else | |
932 origin.send(st.error_reply(stanza, "cancel", "bad-request")); | |
933 end | |
934 end | 993 end |
935 elseif type == "set" or type == "get" then | 994 elseif type == "set" or type == "get" then |
936 origin.send(st.error_reply(stanza, "cancel", "bad-request")); | 995 origin.send(st.error_reply(stanza, "cancel", "bad-request")); |
996 return true; | |
937 end | 997 end |
938 elseif xmlns == "http://jabber.org/protocol/muc#owner" and (type == "get" or type == "set") and stanza.tags[1].name == "query" then | 998 elseif xmlns == "http://jabber.org/protocol/muc#owner" and (type == "get" or type == "set") and stanza.tags[1].name == "query" then |
939 if self:get_affiliation(stanza.attr.from) ~= "owner" then | 999 if stanza.attr.type == "get" then |
940 origin.send(st.error_reply(stanza, "auth", "forbidden", "Only owners can configure rooms")); | 1000 return self:handle_owner_query_get_to_room(origin, stanza) |
941 elseif stanza.attr.type == "get" then | |
942 self:send_form(origin, stanza); | |
943 elseif stanza.attr.type == "set" then | 1001 elseif stanza.attr.type == "set" then |
944 local child = stanza.tags[1].tags[1]; | 1002 return self:handle_owner_query_set_to_room(origin, stanza) |
945 if not child then | |
946 origin.send(st.error_reply(stanza, "modify", "bad-request")); | |
947 elseif child.name == "destroy" then | |
948 local newjid = child.attr.jid; | |
949 local reason, password; | |
950 for _,tag in ipairs(child.tags) do | |
951 if tag.name == "reason" then | |
952 reason = #tag.tags == 0 and tag[1]; | |
953 elseif tag.name == "password" then | |
954 password = #tag.tags == 0 and tag[1]; | |
955 end | |
956 end | |
957 self:destroy(newjid, reason, password); | |
958 origin.send(st.reply(stanza)); | |
959 else | |
960 self:process_form(origin, stanza); | |
961 end | |
962 end | 1003 end |
963 elseif type == "set" or type == "get" then | 1004 elseif type == "set" or type == "get" then |
964 origin.send(st.error_reply(stanza, "cancel", "service-unavailable")); | 1005 origin.send(st.error_reply(stanza, "cancel", "service-unavailable")); |
1006 return true; | |
965 end | 1007 end |
966 end | 1008 end |
967 | 1009 |
968 function room_mt:handle_groupchat_to_room(origin, stanza) | 1010 function room_mt:handle_groupchat_to_room(origin, stanza) |
969 local from = stanza.attr.from; | 1011 local from = stanza.attr.from; |