Mercurial > prosody-hg
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 |
| parents | b37ccf9bec89 |
| children | 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 |
