# HG changeset patch # User Waqas Hussain # Date 1287188806 -18000 # Node ID 1e44e7e8e79c04896bd1094d72adfe6be8066ec6 # Parent d206b4e0a9f3eaf1694e10cbbd28a9007aa83387 mod_roster: Updated to use the new events API. diff -r d206b4e0a9f3 -r 1e44e7e8e79c plugins/mod_roster.lua --- a/plugins/mod_roster.lua Sat Oct 16 05:16:45 2010 +0500 +++ b/plugins/mod_roster.lua Sat Oct 16 05:26:46 2010 +0500 @@ -7,7 +7,6 @@ -- - local st = require "util.stanza" local jid_split = require "util.jid".split; @@ -30,112 +29,110 @@ end end); -module:add_iq_handler("c2s", "jabber:iq:roster", - function (session, stanza) - if stanza.tags[1].name == "query" then - if stanza.attr.type == "get" then - local roster = st.reply(stanza); - - local client_ver = tonumber(stanza.tags[1].attr.ver); - local server_ver = tonumber(session.roster[false].version or 1); - - if not (client_ver and server_ver) or client_ver ~= server_ver then - roster:query("jabber:iq:roster"); - -- Client does not support versioning, or has stale roster - for jid, item in pairs(session.roster) do - if jid ~= "pending" and jid then - roster:tag("item", { - jid = jid, - subscription = item.subscription, - ask = item.ask, - name = item.name, - }); - for group in pairs(item.groups) do - roster:tag("group"):text(group):up(); +module:hook("iq/self/jabber:iq:roster:query", function(event) + local session, stanza = event.origin, event.stanza; + + if stanza.attr.type == "get" then + local roster = st.reply(stanza); + + local client_ver = tonumber(stanza.tags[1].attr.ver); + local server_ver = tonumber(session.roster[false].version or 1); + + if not (client_ver and server_ver) or client_ver ~= server_ver then + roster:query("jabber:iq:roster"); + -- Client does not support versioning, or has stale roster + for jid, item in pairs(session.roster) do + if jid ~= "pending" and jid then + roster:tag("item", { + jid = jid, + subscription = item.subscription, + ask = item.ask, + name = item.name, + }); + for group in pairs(item.groups) do + roster:tag("group"):text(group):up(); + end + roster:up(); -- move out from item + end + end + roster.tags[1].attr.ver = server_ver; + end + session.send(roster); + session.interested = true; -- resource is interested in roster updates + else -- stanza.attr.type == "set" + local query = stanza.tags[1]; + if #query.tags == 1 and query.tags[1].name == "item" + and query.tags[1].attr.xmlns == "jabber:iq:roster" and query.tags[1].attr.jid + -- Protection against overwriting roster.pending, until we move it + and query.tags[1].attr.jid ~= "pending" then + local item = query.tags[1]; + local from_node, from_host = jid_split(stanza.attr.from); + local from_bare = from_node and (from_node.."@"..from_host) or from_host; -- bare JID + local jid = jid_prep(item.attr.jid); + local node, host, resource = jid_split(jid); + if not resource and host then + if jid ~= from_node.."@"..from_host then + if item.attr.subscription == "remove" then + local roster = session.roster; + local r_item = roster[jid]; + if r_item then + local to_bare = node and (node.."@"..host) or host; -- bare JID + if r_item.subscription == "both" or r_item.subscription == "from" or (roster.pending and roster.pending[jid]) then + core_post_stanza(session, st.presence({type="unsubscribed", from=session.full_jid, to=to_bare})); + end + if r_item.subscription == "both" or r_item.subscription == "to" or r_item.ask then + core_post_stanza(session, st.presence({type="unsubscribe", from=session.full_jid, to=to_bare})); + end + local success, err_type, err_cond, err_msg = rm_remove_from_roster(session, jid); + if success then + session.send(st.reply(stanza)); + rm_roster_push(from_node, from_host, jid); + else + session.send(st.error_reply(stanza, err_type, err_cond, err_msg)); + end + else + session.send(st.error_reply(stanza, "modify", "item-not-found")); + end + else + local r_item = {name = item.attr.name, groups = {}}; + if r_item.name == "" then r_item.name = nil; end + if session.roster[jid] then + r_item.subscription = session.roster[jid].subscription; + r_item.ask = session.roster[jid].ask; + else + r_item.subscription = "none"; + end + for _, child in ipairs(item) do + if child.name == "group" then + local text = t_concat(child); + if text and text ~= "" then + r_item.groups[text] = true; end - roster:up(); -- move out from item end end - roster.tags[1].attr.ver = server_ver; + local success, err_type, err_cond, err_msg = rm_add_to_roster(session, jid, r_item); + if success then + -- Ok, send success + session.send(st.reply(stanza)); + -- and push change to all resources + rm_roster_push(from_node, from_host, jid); + else + -- Adding to roster failed + session.send(st.error_reply(stanza, err_type, err_cond, err_msg)); + end end - session.send(roster); - session.interested = true; -- resource is interested in roster updates - return true; - elseif stanza.attr.type == "set" then - local query = stanza.tags[1]; - if #query.tags == 1 and query.tags[1].name == "item" - and query.tags[1].attr.xmlns == "jabber:iq:roster" and query.tags[1].attr.jid - -- Protection against overwriting roster.pending, until we move it - and query.tags[1].attr.jid ~= "pending" then - local item = query.tags[1]; - local from_node, from_host = jid_split(stanza.attr.from); - local from_bare = from_node and (from_node.."@"..from_host) or from_host; -- bare JID - local jid = jid_prep(item.attr.jid); - local node, host, resource = jid_split(jid); - if not resource and host then - if jid ~= from_node.."@"..from_host then - if item.attr.subscription == "remove" then - local roster = session.roster; - local r_item = roster[jid]; - if r_item then - local to_bare = node and (node.."@"..host) or host; -- bare JID - if r_item.subscription == "both" or r_item.subscription == "from" or (roster.pending and roster.pending[jid]) then - core_post_stanza(session, st.presence({type="unsubscribed", from=session.full_jid, to=to_bare})); - end - if r_item.subscription == "both" or r_item.subscription == "to" or r_item.ask then - core_post_stanza(session, st.presence({type="unsubscribe", from=session.full_jid, to=to_bare})); - end - local success, err_type, err_cond, err_msg = rm_remove_from_roster(session, jid); - if success then - session.send(st.reply(stanza)); - rm_roster_push(from_node, from_host, jid); - else - session.send(st.error_reply(stanza, err_type, err_cond, err_msg)); - end - else - session.send(st.error_reply(stanza, "modify", "item-not-found")); - end - else - local r_item = {name = item.attr.name, groups = {}}; - if r_item.name == "" then r_item.name = nil; end - if session.roster[jid] then - r_item.subscription = session.roster[jid].subscription; - r_item.ask = session.roster[jid].ask; - else - r_item.subscription = "none"; - end - for _, child in ipairs(item) do - if child.name == "group" then - local text = t_concat(child); - if text and text ~= "" then - r_item.groups[text] = true; - end - end - end - local success, err_type, err_cond, err_msg = rm_add_to_roster(session, jid, r_item); - if success then - -- Ok, send success - session.send(st.reply(stanza)); - -- and push change to all resources - rm_roster_push(from_node, from_host, jid); - else - -- Adding to roster failed - session.send(st.error_reply(stanza, err_type, err_cond, err_msg)); - end - end - else - -- Trying to add self to roster - session.send(st.error_reply(stanza, "cancel", "not-allowed")); - end - else - -- Invalid JID added to roster - session.send(st.error_reply(stanza, "modify", "bad-request")); -- FIXME what's the correct error? - end - else - -- Roster set didn't include a single item, or its name wasn't 'item' - session.send(st.error_reply(stanza, "modify", "bad-request")); - end - return true; + else + -- Trying to add self to roster + session.send(st.error_reply(stanza, "cancel", "not-allowed")); end + else + -- Invalid JID added to roster + session.send(st.error_reply(stanza, "modify", "bad-request")); -- FIXME what's the correct error? end - end); + else + -- Roster set didn't include a single item, or its name wasn't 'item' + session.send(st.error_reply(stanza, "modify", "bad-request")); + end + end + return true; +end);