Software /
code /
prosody
Comparison
plugins/muc/muc.lib.lua @ 1742:1483a62d69bb
MUC: Owners can now modify roles and affiliations
author | Waqas Hussain <waqas20@gmail.com> |
---|---|
date | Mon, 07 Sep 2009 20:30:16 +0500 |
parent | 1740:b37ccf9bec89 |
child | 1743:d00b144f4bcf |
comparison
equal
deleted
inserted
replaced
1741:2919f3b985fc | 1742:1483a62d69bb |
---|---|
145 stanza:tag("x", {xmlns = "jabber:x:delay", from = muc_domain, stamp = datetime.legacy()}):up(); -- XEP-0091 (deprecated) | 145 stanza:tag("x", {xmlns = "jabber:x:delay", from = muc_domain, stamp = datetime.legacy()}):up(); -- XEP-0091 (deprecated) |
146 t_insert(history, st.clone(st.preserialize(stanza))); | 146 t_insert(history, st.clone(st.preserialize(stanza))); |
147 while #history > history_length do t_remove(history, 1) end | 147 while #history > history_length do t_remove(history, 1) end |
148 end | 148 end |
149 end | 149 end |
150 | 150 function room_mt:broadcast_except_nick(stanza, nick) |
151 for nick, occupant in pairs(self._occupants) do | |
152 if nick ~= nick then | |
153 for jid in pairs(occupant.sessions) do | |
154 stanza.attr.to = jid; | |
155 self:route_stanza(stanza); | |
156 end | |
157 end | |
158 end | |
159 end | |
151 | 160 |
152 function room_mt:send_occupant_list(to) | 161 function room_mt:send_occupant_list(to) |
153 local current_nick = self._jid_nick[to]; | 162 local current_nick = self._jid_nick[to]; |
154 for occupant, o_data in pairs(self._occupants) do | 163 for occupant, o_data in pairs(self._occupants) do |
155 if occupant ~= current_nick then | 164 if occupant ~= current_nick then |
307 elseif xmlns == "http://jabber.org/protocol/disco#items" then | 316 elseif xmlns == "http://jabber.org/protocol/disco#items" then |
308 origin.send(room_get_disco_items(self, stanza)); | 317 origin.send(room_get_disco_items(self, stanza)); |
309 else | 318 else |
310 origin.send(st.error_reply(stanza, "cancel", "service-unavailable")); | 319 origin.send(st.error_reply(stanza, "cancel", "service-unavailable")); |
311 end | 320 end |
321 elseif stanza.name == "iq" and type == "set" and stanza.tags[1].attr.xmlns == "http://jabber.org/protocol/muc#admin" then | |
322 local actor = stanza.attr.from; | |
323 local affiliation = self:get_affiliation(actor); | |
324 local current_nick = self._jid_nick[actor]; | |
325 local role = current_nick and self._occupants[current_nick].role or self:get_default_role(affiliation); | |
326 local item = stanza.tags[1].tags[1]; | |
327 if item and item.name == "item" then | |
328 local callback = function() origin.send(st.reply(stanza)); end | |
329 if item.attr.affiliation and item.attr.jid and not item.attr.role and not item.attr.nick then | |
330 local success, errtype, err = self:set_affiliation(actor, item.attr.jid, item.attr.affiliation, callback); | |
331 if not success then origin.send(st.error_reply(stanza, errtype, err)); end | |
332 elseif item.attr.role and item.attr.nick and not item.attr.affiliation and not item.attr.jid then | |
333 local success, errtype, err = self:set_role(actor, item.attr.nick, item.attr.role, callback); | |
334 if not success then origin.send(st.error_reply(stanza, errtype, err)); end | |
335 else | |
336 origin.send(st.error_reply(stanza, "cancel", "bad-request")); | |
337 end | |
338 else | |
339 origin.send(st.error_reply(stanza, "cancel", "bad-request")); | |
340 end | |
312 elseif stanza.name == "message" and type == "groupchat" then | 341 elseif stanza.name == "message" and type == "groupchat" then |
313 local from, to = stanza.attr.from, stanza.attr.to; | 342 local from, to = stanza.attr.from, stanza.attr.to; |
314 local room = jid_bare(to); | 343 local room = jid_bare(to); |
315 local current_nick = self._jid_nick[from]; | 344 local current_nick = self._jid_nick[from]; |
316 if not current_nick then -- not in room | 345 if not current_nick then -- not in room |
367 local bare = node and node.."@"..host or host; | 396 local bare = node and node.."@"..host or host; |
368 local result = self._affiliations[bare]; -- Affiliations are granted, revoked, and maintained based on the user's bare JID. | 397 local result = self._affiliations[bare]; -- Affiliations are granted, revoked, and maintained based on the user's bare JID. |
369 if not result and self._affiliations[host] == "outcast" then result = "outcast"; end -- host banned | 398 if not result and self._affiliations[host] == "outcast" then result = "outcast"; end -- host banned |
370 return result; | 399 return result; |
371 end | 400 end |
372 | 401 function room_mt:set_affiliation(actor, jid, affiliation, callback) |
373 function room_mt:set_affiliation(jid, affiliation) | 402 jid = jid_bare(jid); |
374 local node, host, resource = jid_split(jid); | |
375 local bare = node and node.."@"..host or host; | |
376 if affiliation == "none" then affiliation = nil; end | 403 if affiliation == "none" then affiliation = nil; end |
377 if affiliation and affiliation ~= "outcast" and affiliation ~= "owner" and affiliation ~= "admin" and affiliation ~= "member" then return false; end | 404 if affiliation and affiliation ~= "outcast" and affiliation ~= "owner" and affiliation ~= "admin" and affiliation ~= "member" then |
378 self._affiliations[bare] = affiliation; | 405 return nil, "modify", "not-acceptable"; |
379 -- TODO set roles based on new affiliation | 406 end |
407 if self:get_affiliation(actor) ~= "owner" then return nil, "cancel", "not-allowed"; end | |
408 if jid_bare(actor) == jid then return nil, "cancel", "not-allowed"; end | |
409 self._affiliations[jid] = affiliation; | |
410 local role = self:get_default_role(affiliation); | |
411 local p = st.presence({type = "unavailable"}) | |
412 :tag("x", {xmlns = "http://jabber.org/protocol/muc#user"}) | |
413 :tag("item", {affiliation=affiliation, role=role or "none"}):up(); | |
414 local x = p.tags[1]; | |
415 local item = x.tags[1]; | |
416 if not role then -- getting kicked | |
417 if affiliation == "outcast" then | |
418 x:tag("status", {code="301"}):up(); -- banned | |
419 else | |
420 x:tag("status", {code="321"}):up(); -- affiliation change | |
421 end | |
422 end | |
423 local modified_nicks = {}; | |
424 for nick, occupant in pairs(self._occupants) do | |
425 if jid_bare(occupant.jid) == jid then | |
426 if not role then -- getting kicked | |
427 self._occupants[nick] = nil; | |
428 else | |
429 t_insert(modified_nicks, nick); | |
430 occupant.affiliation, occupant.role = affiliation, role; | |
431 end | |
432 p.attr.from = nick; | |
433 for jid in pairs(occupant.sessions) do -- remove for all sessions of the nick | |
434 if not role then self._jid_nick[jid] = nil; end | |
435 p.attr.to = jid; | |
436 self:route_stanza(p); | |
437 end | |
438 end | |
439 end | |
440 if callback then callback(); end | |
441 for _, nick in ipairs(modified_nicks) do | |
442 p.attr.from = nick; | |
443 self:broadcast_except_nick(p, nick); | |
444 end | |
445 return true; | |
446 end | |
447 | |
448 function room_mt:get_role(nick) | |
449 local session = self._occupants[nick]; | |
450 return session and session.role or nil; | |
451 end | |
452 function room_mt:set_role(actor, nick, role, callback) | |
453 if role and role ~= "moderator" and role ~= "participant" and role ~= "visitor" then return nil, "modify", "not-acceptable"; end | |
454 if self:get_affiliation(actor) ~= "owner" then return nil, "cancel", "not-allowed"; end | |
455 local occupant = self._occupants[nick]; | |
456 if not occupant then return nil, "modify", "not-acceptable"; end | |
457 if jid_bare(actor) == occupant.jid then return nil, "cancel", "not-allowed"; end | |
458 local p = st.presence({from = nick, type = "unavailable"}) | |
459 :tag("x", {xmlns = "http://jabber.org/protocol/muc#user"}) | |
460 :tag("item", {affiliation=occupant.affiliation, nick=nick, role=role or "none"}):up(); | |
461 if not role then -- kick | |
462 self._occupants[nick] = nil; | |
463 for jid in pairs(occupant.sessions) do -- remove for all sessions of the nick | |
464 self._jid_nick[jid] = nil; | |
465 end | |
466 p:tag("status", {code = "307"}):up(); | |
467 else | |
468 occupant.role = role; | |
469 end | |
470 for jid in pairs(occupant.sessions) do -- send to all sessions of the nick | |
471 p.attr.to = jid; | |
472 self:route_stanza(p); | |
473 end | |
474 if callback then callback(); end | |
475 self:broadcast_except_nick(p, nick); | |
380 return true; | 476 return true; |
381 end | 477 end |
382 | 478 |
383 local _M = {}; -- module "muc" | 479 local _M = {}; -- module "muc" |
384 | 480 |