Software /
code /
prosody
Comparison
plugins/muc/muc.lib.lua @ 2877:1edeb8fe7d14
Merge 0.6.2/waqas with 0.6.2/MattJ
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Wed, 03 Mar 2010 22:05:05 +0000 |
parent | 2864:1ce0e2ceb419 |
child | 2923:b7049746bd29 |
comparison
equal
deleted
inserted
replaced
2813:46dfcc33ea9e | 2877:1edeb8fe7d14 |
---|---|
126 stanza.attr.to = sid; | 126 stanza.attr.to = sid; |
127 self:_route_stanza(stanza); | 127 self:_route_stanza(stanza); |
128 end | 128 end |
129 end | 129 end |
130 function room_mt:broadcast_message(stanza, historic) | 130 function room_mt:broadcast_message(stanza, historic) |
131 local to = stanza.attr.to; | |
131 for occupant, o_data in pairs(self._occupants) do | 132 for occupant, o_data in pairs(self._occupants) do |
132 for jid in pairs(o_data.sessions) do | 133 for jid in pairs(o_data.sessions) do |
133 stanza.attr.to = jid; | 134 stanza.attr.to = jid; |
134 self:_route_stanza(stanza); | 135 self:_route_stanza(stanza); |
135 end | 136 end |
136 end | 137 end |
138 stanza.attr.to = to; | |
137 if historic then -- add to history | 139 if historic then -- add to history |
138 local history = self._data['history']; | 140 local history = self._data['history']; |
139 if not history then history = {}; self._data['history'] = history; end | 141 if not history then history = {}; self._data['history'] = history; end |
140 -- stanza = st.clone(stanza); | 142 stanza = st.clone(stanza); |
141 stanza:tag("delay", {xmlns = "urn:xmpp:delay", from = muc_domain, stamp = datetime.datetime()}):up(); -- XEP-0203 | 143 stanza:tag("delay", {xmlns = "urn:xmpp:delay", from = muc_domain, stamp = datetime.datetime()}):up(); -- XEP-0203 |
142 stanza:tag("x", {xmlns = "jabber:x:delay", from = muc_domain, stamp = datetime.legacy()}):up(); -- XEP-0091 (deprecated) | 144 stanza:tag("x", {xmlns = "jabber:x:delay", from = muc_domain, stamp = datetime.legacy()}):up(); -- XEP-0091 (deprecated) |
143 t_insert(history, st.clone(st.preserialize(stanza))); | 145 t_insert(history, st.preserialize(stanza)); |
144 while #history > history_length do t_remove(history, 1) end | 146 while #history > history_length do t_remove(history, 1) end |
145 end | 147 end |
146 end | 148 end |
147 function room_mt:broadcast_except_nick(stanza, nick) | 149 function room_mt:broadcast_except_nick(stanza, nick) |
148 for rnick, occupant in pairs(self._occupants) do | 150 for rnick, occupant in pairs(self._occupants) do |
459 end | 461 end |
460 end | 462 end |
461 if not item.attr.jid and item.attr.nick then -- COMPAT Workaround for Miranda sending 'nick' instead of 'jid' when changing affiliation | 463 if not item.attr.jid and item.attr.nick then -- COMPAT Workaround for Miranda sending 'nick' instead of 'jid' when changing affiliation |
462 local occupant = self._occupants[self.jid.."/"..item.attr.nick]; | 464 local occupant = self._occupants[self.jid.."/"..item.attr.nick]; |
463 if occupant then item.attr.jid = occupant.jid; end | 465 if occupant then item.attr.jid = occupant.jid; end |
466 elseif not item.attr.nick and item.attr.jid then | |
467 local nick = self._jid_nick[item.attr.jid]; | |
468 if nick then item.attr.nick = select(3, jid_split(nick)); end | |
464 end | 469 end |
465 local reason = item.tags[1] and item.tags[1].name == "reason" and #item.tags[1] == 1 and item.tags[1][1]; | 470 local reason = item.tags[1] and item.tags[1].name == "reason" and #item.tags[1] == 1 and item.tags[1][1]; |
466 if item.attr.affiliation and item.attr.jid and not item.attr.role then | 471 if item.attr.affiliation and item.attr.jid and not item.attr.role then |
467 local success, errtype, err = self:set_affiliation(actor, item.attr.jid, item.attr.affiliation, callback, reason); | 472 local success, errtype, err = self:set_affiliation(actor, item.attr.jid, item.attr.affiliation, callback, reason); |
468 if not success then origin.send(st.error_reply(stanza, errtype, err)); end | 473 if not success then origin.send(st.error_reply(stanza, errtype, err)); end |
490 elseif _rol and not _aff then | 495 elseif _rol and not _aff then |
491 if role == "moderator" then | 496 if role == "moderator" then |
492 -- TODO allow admins and owners not in room? Provide read-only access to everyone who can see the participants anyway? | 497 -- TODO allow admins and owners not in room? Provide read-only access to everyone who can see the participants anyway? |
493 if _rol == "none" then _rol = nil; end | 498 if _rol == "none" then _rol = nil; end |
494 local reply = st.reply(stanza):query("http://jabber.org/protocol/muc#admin"); | 499 local reply = st.reply(stanza):query("http://jabber.org/protocol/muc#admin"); |
495 for nick, occupant in pairs(self._occupants) do | 500 for occupant_jid, occupant in pairs(self._occupants) do |
496 if occupant.role == _rol then | 501 if occupant.role == _rol then |
497 reply:tag("item", {nick = nick, role = _rol or "none", affiliation = occupant.affiliation or "none", jid = occupant.jid}):up(); | 502 reply:tag("item", { |
503 nick = select(3, jid_split(occupant_jid)), | |
504 role = _rol or "none", | |
505 affiliation = occupant.affiliation or "none", | |
506 jid = occupant.jid | |
507 }):up(); | |
498 end | 508 end |
499 end | 509 end |
500 origin.send(reply); | 510 origin.send(reply); |
501 else | 511 else |
502 origin.send(st.error_reply(stanza, "auth", "forbidden")); | 512 origin.send(st.error_reply(stanza, "auth", "forbidden")); |
515 end | 525 end |
516 elseif stanza.name == "message" and type == "groupchat" then | 526 elseif stanza.name == "message" and type == "groupchat" then |
517 local from, to = stanza.attr.from, stanza.attr.to; | 527 local from, to = stanza.attr.from, stanza.attr.to; |
518 local room = jid_bare(to); | 528 local room = jid_bare(to); |
519 local current_nick = self._jid_nick[from]; | 529 local current_nick = self._jid_nick[from]; |
520 if not current_nick then -- not in room | 530 local occupant = self._occupants[current_nick]; |
531 if not occupant then -- not in room | |
521 origin.send(st.error_reply(stanza, "cancel", "not-acceptable")); | 532 origin.send(st.error_reply(stanza, "cancel", "not-acceptable")); |
533 elseif occupant.role == "visitor" then | |
534 origin.send(st.error_reply(stanza, "cancel", "forbidden")); | |
522 else | 535 else |
523 local from = stanza.attr.from; | 536 local from = stanza.attr.from; |
524 stanza.attr.from = current_nick; | 537 stanza.attr.from = current_nick; |
525 local subject = getText(stanza, {"subject"}); | 538 local subject = getText(stanza, {"subject"}); |
526 if subject then | 539 if subject then |
527 self:set_subject(current_nick, subject); -- TODO use broadcast_message_stanza | 540 if occupant.role == "moderator" then |
541 self:set_subject(current_nick, subject); -- TODO use broadcast_message_stanza | |
542 else | |
543 stanza.attr.from = from; | |
544 origin.send(st.error_reply(stanza, "cancel", "forbidden")); | |
545 end | |
528 else | 546 else |
529 self:broadcast_message(stanza, true); | 547 self:broadcast_message(stanza, true); |
530 end | 548 end |
549 stanza.attr.from = from; | |
531 end | 550 end |
532 elseif stanza.name == "message" and type == "error" and is_kickable_error(stanza) then | 551 elseif stanza.name == "message" and type == "error" and is_kickable_error(stanza) then |
533 local current_nick = self._jid_nick[stanza.attr.from]; | 552 local current_nick = self._jid_nick[stanza.attr.from]; |
534 log("debug", "%s kicked from %s for sending an error message", current_nick, self.jid); | 553 log("debug", "%s kicked from %s for sending an error message", current_nick, self.jid); |
535 self:handle_to_occupant(origin, st.presence({type='unavailable', from=stanza.attr.from, to=stanza.attr.to}) | 554 self:handle_to_occupant(origin, st.presence({type='unavailable', from=stanza.attr.from, to=stanza.attr.to}) |
649 | 668 |
650 function room_mt:get_role(nick) | 669 function room_mt:get_role(nick) |
651 local session = self._occupants[nick]; | 670 local session = self._occupants[nick]; |
652 return session and session.role or nil; | 671 return session and session.role or nil; |
653 end | 672 end |
654 function room_mt:set_role(actor, nick, role, callback, reason) | 673 function room_mt:set_role(actor, occupant_jid, role, callback, reason) |
655 if role == "none" then role = nil; end | 674 if role == "none" then role = nil; end |
656 if role and role ~= "moderator" and role ~= "participant" and role ~= "visitor" then return nil, "modify", "not-acceptable"; end | 675 if role and role ~= "moderator" and role ~= "participant" and role ~= "visitor" then return nil, "modify", "not-acceptable"; end |
657 if self:get_affiliation(actor) ~= "owner" then return nil, "cancel", "not-allowed"; end | 676 if self:get_affiliation(actor) ~= "owner" then return nil, "cancel", "not-allowed"; end |
658 local occupant = self._occupants[nick]; | 677 local occupant = self._occupants[occupant_jid]; |
659 if not occupant then return nil, "modify", "not-acceptable"; end | 678 if not occupant then return nil, "modify", "not-acceptable"; end |
660 if occupant.affiliation == "owner" or occupant.affiliation == "admin" then return nil, "cancel", "not-allowed"; end | 679 if occupant.affiliation == "owner" or occupant.affiliation == "admin" then return nil, "cancel", "not-allowed"; end |
661 local p = st.presence({from = nick}) | 680 local p = st.presence({from = occupant_jid}) |
662 :tag("x", {xmlns = "http://jabber.org/protocol/muc#user"}) | 681 :tag("x", {xmlns = "http://jabber.org/protocol/muc#user"}) |
663 :tag("item", {affiliation=occupant.affiliation or "none", nick=nick, role=role or "none"}) | 682 :tag("item", {affiliation=occupant.affiliation or "none", nick=select(3, jid_split(occupant_jid)), role=role or "none"}) |
664 :tag("reason"):text(reason or ""):up() | 683 :tag("reason"):text(reason or ""):up() |
665 :up(); | 684 :up(); |
666 if not role then -- kick | 685 if not role then -- kick |
667 p.attr.type = "unavailable"; | 686 p.attr.type = "unavailable"; |
668 self._occupants[nick] = nil; | 687 self._occupants[occupant_jid] = nil; |
669 for jid in pairs(occupant.sessions) do -- remove for all sessions of the nick | 688 for jid in pairs(occupant.sessions) do -- remove for all sessions of the nick |
670 self._jid_nick[jid] = nil; | 689 self._jid_nick[jid] = nil; |
671 end | 690 end |
672 p:tag("status", {code = "307"}):up(); | 691 p:tag("status", {code = "307"}):up(); |
673 else | 692 else |
676 for jid in pairs(occupant.sessions) do -- send to all sessions of the nick | 695 for jid in pairs(occupant.sessions) do -- send to all sessions of the nick |
677 p.attr.to = jid; | 696 p.attr.to = jid; |
678 self:_route_stanza(p); | 697 self:_route_stanza(p); |
679 end | 698 end |
680 if callback then callback(); end | 699 if callback then callback(); end |
681 self:broadcast_except_nick(p, nick); | 700 self:broadcast_except_nick(p, occupant_jid); |
682 return true; | 701 return true; |
683 end | 702 end |
684 | 703 |
685 function room_mt:_route_stanza(stanza) | 704 function room_mt:_route_stanza(stanza) |
686 local muc_child; | 705 local muc_child; |