Comparison

plugins/muc/muc.lib.lua @ 1753:a84901db4085

MUC: Refactored IQ handling to be more easily extensible.
author Waqas Hussain <waqas20@gmail.com>
date Mon, 07 Sep 2009 20:50:06 +0500
parent 1752:4db786919805
child 1754:67b66eec9777
comparison
equal deleted inserted replaced
1752:4db786919805 1753:a84901db4085
308 end 308 end
309 309
310 function room_mt:handle_to_room(origin, stanza) -- presence changes and groupchat messages, along with disco/etc 310 function room_mt:handle_to_room(origin, stanza) -- presence changes and groupchat messages, along with disco/etc
311 local type = stanza.attr.type; 311 local type = stanza.attr.type;
312 local xmlns = stanza.tags[1] and stanza.tags[1].attr.xmlns; 312 local xmlns = stanza.tags[1] and stanza.tags[1].attr.xmlns;
313 if stanza.name == "iq" and type == "get" and xmlns ~= "http://jabber.org/protocol/muc#admin" then -- disco requests 313 if stanza.name == "iq" then
314 if xmlns == "http://jabber.org/protocol/disco#info" then 314 if xmlns == "http://jabber.org/protocol/disco#info" and type == "get" then
315 origin.send(room_get_disco_info(self, stanza)); 315 origin.send(room_get_disco_info(self, stanza));
316 elseif xmlns == "http://jabber.org/protocol/disco#items" then 316 elseif xmlns == "http://jabber.org/protocol/disco#items" and type == "get" then
317 origin.send(room_get_disco_items(self, stanza)); 317 origin.send(room_get_disco_items(self, stanza));
318 else 318 elseif xmlns == "http://jabber.org/protocol/muc#admin" then
319 origin.send(st.error_reply(stanza, "cancel", "service-unavailable")); 319 local actor = stanza.attr.from;
320 end 320 local affiliation = self:get_affiliation(actor);
321 elseif stanza.name == "iq" and xmlns == "http://jabber.org/protocol/muc#admin" then 321 local current_nick = self._jid_nick[actor];
322 local actor = stanza.attr.from; 322 local role = current_nick and self._occupants[current_nick].role or self:get_default_role(affiliation);
323 local affiliation = self:get_affiliation(actor); 323 local item = stanza.tags[1].tags[1];
324 local current_nick = self._jid_nick[actor]; 324 if item and item.name == "item" then
325 local role = current_nick and self._occupants[current_nick].role or self:get_default_role(affiliation); 325 if type == "set" then
326 local item = stanza.tags[1].tags[1]; 326 local callback = function() origin.send(st.reply(stanza)); end
327 if item and item.name == "item" then 327 if not item.attr.jid and item.attr.nick then -- COMPAT Workaround for Miranda sending 'nick' instead of 'jid' when changing affiliation
328 if type == "set" then 328 local occupant = self._occupants[self.jid.."/"..item.attr.nick];
329 local callback = function() origin.send(st.reply(stanza)); end 329 if occupant then item.attr.jid = occupant.jid; end
330 if not item.attr.jid and item.attr.nick then -- COMPAT Workaround for Miranda sending 'nick' instead of 'jid' when changing affiliation 330 end
331 local occupant = self._occupants[self.jid.."/"..item.attr.nick]; 331 if item.attr.affiliation and item.attr.jid and not item.attr.role then
332 if occupant then item.attr.jid = occupant.jid; end 332 local success, errtype, err = self:set_affiliation(actor, item.attr.jid, item.attr.affiliation, callback);
333 if not success then origin.send(st.error_reply(stanza, errtype, err)); end
334 elseif item.attr.role and item.attr.nick and not item.attr.affiliation then
335 local success, errtype, err = self:set_role(actor, self.jid.."/"..item.attr.nick, item.attr.role, callback);
336 if not success then origin.send(st.error_reply(stanza, errtype, err)); end
337 else
338 origin.send(st.error_reply(stanza, "cancel", "bad-request"));
339 end
340 elseif type == "get" then
341 local _aff = item.attr.affiliation;
342 local _rol = item.attr.role;
343 if _aff and not _rol then
344 if affiliation == "owner" or (affiliation == "admin" and _aff ~= "owner" and _aff ~= "admin") then
345 local reply = st.reply(stanza):query("http://jabber.org/protocol/muc#admin");
346 for jid, affiliation in pairs(self._affiliations) do
347 if affiliation == _aff then
348 reply:tag("item", {affiliation = _aff, jid = jid}):up();
349 end
350 end
351 origin.send(reply);
352 else
353 origin.send(st.error_reply(stanza, "auth", "forbidden"));
354 end
355 elseif _rol and not _aff then
356 if role == "moderator" then
357 -- TODO allow admins and owners not in room? Provide read-only access to everyone who can see the participants anyway?
358 if _rol == "none" then _rol = nil; end
359 local reply = st.reply(stanza):query("http://jabber.org/protocol/muc#admin");
360 for nick, occupant in pairs(self._occupants) do
361 if occupant.role == _rol then
362 reply:tag("item", {nick = nick, role = _rol or "none", affiliation = occupant.affiliation or "none", jid = occupant.jid}):up();
363 end
364 end
365 origin.send(reply);
366 else
367 origin.send(st.error_reply(stanza, "auth", "forbidden"));
368 end
369 else
370 origin.send(st.error_reply(stanza, "cancel", "bad-request"));
371 end
333 end 372 end
334 if item.attr.affiliation and item.attr.jid and not item.attr.role then 373 elseif type == "set" or type == "get" then
335 local success, errtype, err = self:set_affiliation(actor, item.attr.jid, item.attr.affiliation, callback); 374 origin.send(st.error_reply(stanza, "cancel", "bad-request"));
336 if not success then origin.send(st.error_reply(stanza, errtype, err)); end 375 end
337 elseif item.attr.role and item.attr.nick and not item.attr.affiliation then
338 local success, errtype, err = self:set_role(actor, self.jid.."/"..item.attr.nick, item.attr.role, callback);
339 if not success then origin.send(st.error_reply(stanza, errtype, err)); end
340 else
341 origin.send(st.error_reply(stanza, "cancel", "bad-request"));
342 end
343 elseif type == "get" then
344 local _aff = item.attr.affiliation;
345 local _rol = item.attr.role;
346 if _aff and not _rol then
347 if affiliation == "owner" or (affiliation == "admin" and _aff ~= "owner" and _aff ~= "admin") then
348 local reply = st.reply(stanza):query("http://jabber.org/protocol/muc#admin");
349 for jid, affiliation in pairs(self._affiliations) do
350 if affiliation == _aff then
351 reply:tag("item", {affiliation = _aff, jid = jid}):up();
352 end
353 end
354 origin.send(reply);
355 else
356 origin.send(st.error_reply(stanza, "auth", "forbidden"));
357 end
358 elseif _rol and not _aff then
359 if role == "moderator" then -- TODO allow admins and owners not in room? Provide read-only access to everyone who can see the participants anyway?
360 if _rol == "none" then _rol = nil; end
361 local reply = st.reply(stanza):query("http://jabber.org/protocol/muc#admin");
362 for nick, occupant in pairs(self._occupants) do
363 if occupant.role == _rol then
364 reply:tag("item", {nick = nick, role = _rol or "none", affiliation = occupant.affiliation or "none", jid = occupant.jid}):up();
365 end
366 end
367 origin.send(reply);
368 else
369 origin.send(st.error_reply(stanza, "auth", "forbidden"));
370 end
371 else
372 origin.send(st.error_reply(stanza, "cancel", "bad-request"));
373 end
374 end
375 elseif type == "set" or type == "get" then
376 origin.send(st.error_reply(stanza, "cancel", "bad-request"));
377 end 376 end
378 elseif stanza.name == "message" and type == "groupchat" then 377 elseif stanza.name == "message" and type == "groupchat" then
379 local from, to = stanza.attr.from, stanza.attr.to; 378 local from, to = stanza.attr.from, stanza.attr.to;
380 local room = jid_bare(to); 379 local room = jid_bare(to);
381 local current_nick = self._jid_nick[from]; 380 local current_nick = self._jid_nick[from];