Software /
code /
prosody
Comparison
plugins/mod_roster.lua @ 3525:1e44e7e8e79c
mod_roster: Updated to use the new events API.
author | Waqas Hussain <waqas20@gmail.com> |
---|---|
date | Sat, 16 Oct 2010 05:26:46 +0500 |
parent | 3323:5228a395999b |
child | 3526:69a8c7e635c5 |
comparison
equal
deleted
inserted
replaced
3524:d206b4e0a9f3 | 3525:1e44e7e8e79c |
---|---|
3 -- Copyright (C) 2008-2010 Waqas Hussain | 3 -- Copyright (C) 2008-2010 Waqas Hussain |
4 -- | 4 -- |
5 -- This project is MIT/X11 licensed. Please see the | 5 -- This project is MIT/X11 licensed. Please see the |
6 -- COPYING file in the source package for more information. | 6 -- COPYING file in the source package for more information. |
7 -- | 7 -- |
8 | |
9 | 8 |
10 | 9 |
11 local st = require "util.stanza" | 10 local st = require "util.stanza" |
12 | 11 |
13 local jid_split = require "util.jid".split; | 12 local jid_split = require "util.jid".split; |
28 if origin.username then | 27 if origin.username then |
29 features:add_child(rosterver_stream_feature); | 28 features:add_child(rosterver_stream_feature); |
30 end | 29 end |
31 end); | 30 end); |
32 | 31 |
33 module:add_iq_handler("c2s", "jabber:iq:roster", | 32 module:hook("iq/self/jabber:iq:roster:query", function(event) |
34 function (session, stanza) | 33 local session, stanza = event.origin, event.stanza; |
35 if stanza.tags[1].name == "query" then | 34 |
36 if stanza.attr.type == "get" then | 35 if stanza.attr.type == "get" then |
37 local roster = st.reply(stanza); | 36 local roster = st.reply(stanza); |
38 | 37 |
39 local client_ver = tonumber(stanza.tags[1].attr.ver); | 38 local client_ver = tonumber(stanza.tags[1].attr.ver); |
40 local server_ver = tonumber(session.roster[false].version or 1); | 39 local server_ver = tonumber(session.roster[false].version or 1); |
41 | 40 |
42 if not (client_ver and server_ver) or client_ver ~= server_ver then | 41 if not (client_ver and server_ver) or client_ver ~= server_ver then |
43 roster:query("jabber:iq:roster"); | 42 roster:query("jabber:iq:roster"); |
44 -- Client does not support versioning, or has stale roster | 43 -- Client does not support versioning, or has stale roster |
45 for jid, item in pairs(session.roster) do | 44 for jid, item in pairs(session.roster) do |
46 if jid ~= "pending" and jid then | 45 if jid ~= "pending" and jid then |
47 roster:tag("item", { | 46 roster:tag("item", { |
48 jid = jid, | 47 jid = jid, |
49 subscription = item.subscription, | 48 subscription = item.subscription, |
50 ask = item.ask, | 49 ask = item.ask, |
51 name = item.name, | 50 name = item.name, |
52 }); | 51 }); |
53 for group in pairs(item.groups) do | 52 for group in pairs(item.groups) do |
54 roster:tag("group"):text(group):up(); | 53 roster:tag("group"):text(group):up(); |
54 end | |
55 roster:up(); -- move out from item | |
56 end | |
57 end | |
58 roster.tags[1].attr.ver = server_ver; | |
59 end | |
60 session.send(roster); | |
61 session.interested = true; -- resource is interested in roster updates | |
62 else -- stanza.attr.type == "set" | |
63 local query = stanza.tags[1]; | |
64 if #query.tags == 1 and query.tags[1].name == "item" | |
65 and query.tags[1].attr.xmlns == "jabber:iq:roster" and query.tags[1].attr.jid | |
66 -- Protection against overwriting roster.pending, until we move it | |
67 and query.tags[1].attr.jid ~= "pending" then | |
68 local item = query.tags[1]; | |
69 local from_node, from_host = jid_split(stanza.attr.from); | |
70 local from_bare = from_node and (from_node.."@"..from_host) or from_host; -- bare JID | |
71 local jid = jid_prep(item.attr.jid); | |
72 local node, host, resource = jid_split(jid); | |
73 if not resource and host then | |
74 if jid ~= from_node.."@"..from_host then | |
75 if item.attr.subscription == "remove" then | |
76 local roster = session.roster; | |
77 local r_item = roster[jid]; | |
78 if r_item then | |
79 local to_bare = node and (node.."@"..host) or host; -- bare JID | |
80 if r_item.subscription == "both" or r_item.subscription == "from" or (roster.pending and roster.pending[jid]) then | |
81 core_post_stanza(session, st.presence({type="unsubscribed", from=session.full_jid, to=to_bare})); | |
82 end | |
83 if r_item.subscription == "both" or r_item.subscription == "to" or r_item.ask then | |
84 core_post_stanza(session, st.presence({type="unsubscribe", from=session.full_jid, to=to_bare})); | |
85 end | |
86 local success, err_type, err_cond, err_msg = rm_remove_from_roster(session, jid); | |
87 if success then | |
88 session.send(st.reply(stanza)); | |
89 rm_roster_push(from_node, from_host, jid); | |
90 else | |
91 session.send(st.error_reply(stanza, err_type, err_cond, err_msg)); | |
92 end | |
93 else | |
94 session.send(st.error_reply(stanza, "modify", "item-not-found")); | |
95 end | |
96 else | |
97 local r_item = {name = item.attr.name, groups = {}}; | |
98 if r_item.name == "" then r_item.name = nil; end | |
99 if session.roster[jid] then | |
100 r_item.subscription = session.roster[jid].subscription; | |
101 r_item.ask = session.roster[jid].ask; | |
102 else | |
103 r_item.subscription = "none"; | |
104 end | |
105 for _, child in ipairs(item) do | |
106 if child.name == "group" then | |
107 local text = t_concat(child); | |
108 if text and text ~= "" then | |
109 r_item.groups[text] = true; | |
55 end | 110 end |
56 roster:up(); -- move out from item | |
57 end | 111 end |
58 end | 112 end |
59 roster.tags[1].attr.ver = server_ver; | 113 local success, err_type, err_cond, err_msg = rm_add_to_roster(session, jid, r_item); |
114 if success then | |
115 -- Ok, send success | |
116 session.send(st.reply(stanza)); | |
117 -- and push change to all resources | |
118 rm_roster_push(from_node, from_host, jid); | |
119 else | |
120 -- Adding to roster failed | |
121 session.send(st.error_reply(stanza, err_type, err_cond, err_msg)); | |
122 end | |
60 end | 123 end |
61 session.send(roster); | 124 else |
62 session.interested = true; -- resource is interested in roster updates | 125 -- Trying to add self to roster |
63 return true; | 126 session.send(st.error_reply(stanza, "cancel", "not-allowed")); |
64 elseif stanza.attr.type == "set" then | |
65 local query = stanza.tags[1]; | |
66 if #query.tags == 1 and query.tags[1].name == "item" | |
67 and query.tags[1].attr.xmlns == "jabber:iq:roster" and query.tags[1].attr.jid | |
68 -- Protection against overwriting roster.pending, until we move it | |
69 and query.tags[1].attr.jid ~= "pending" then | |
70 local item = query.tags[1]; | |
71 local from_node, from_host = jid_split(stanza.attr.from); | |
72 local from_bare = from_node and (from_node.."@"..from_host) or from_host; -- bare JID | |
73 local jid = jid_prep(item.attr.jid); | |
74 local node, host, resource = jid_split(jid); | |
75 if not resource and host then | |
76 if jid ~= from_node.."@"..from_host then | |
77 if item.attr.subscription == "remove" then | |
78 local roster = session.roster; | |
79 local r_item = roster[jid]; | |
80 if r_item then | |
81 local to_bare = node and (node.."@"..host) or host; -- bare JID | |
82 if r_item.subscription == "both" or r_item.subscription == "from" or (roster.pending and roster.pending[jid]) then | |
83 core_post_stanza(session, st.presence({type="unsubscribed", from=session.full_jid, to=to_bare})); | |
84 end | |
85 if r_item.subscription == "both" or r_item.subscription == "to" or r_item.ask then | |
86 core_post_stanza(session, st.presence({type="unsubscribe", from=session.full_jid, to=to_bare})); | |
87 end | |
88 local success, err_type, err_cond, err_msg = rm_remove_from_roster(session, jid); | |
89 if success then | |
90 session.send(st.reply(stanza)); | |
91 rm_roster_push(from_node, from_host, jid); | |
92 else | |
93 session.send(st.error_reply(stanza, err_type, err_cond, err_msg)); | |
94 end | |
95 else | |
96 session.send(st.error_reply(stanza, "modify", "item-not-found")); | |
97 end | |
98 else | |
99 local r_item = {name = item.attr.name, groups = {}}; | |
100 if r_item.name == "" then r_item.name = nil; end | |
101 if session.roster[jid] then | |
102 r_item.subscription = session.roster[jid].subscription; | |
103 r_item.ask = session.roster[jid].ask; | |
104 else | |
105 r_item.subscription = "none"; | |
106 end | |
107 for _, child in ipairs(item) do | |
108 if child.name == "group" then | |
109 local text = t_concat(child); | |
110 if text and text ~= "" then | |
111 r_item.groups[text] = true; | |
112 end | |
113 end | |
114 end | |
115 local success, err_type, err_cond, err_msg = rm_add_to_roster(session, jid, r_item); | |
116 if success then | |
117 -- Ok, send success | |
118 session.send(st.reply(stanza)); | |
119 -- and push change to all resources | |
120 rm_roster_push(from_node, from_host, jid); | |
121 else | |
122 -- Adding to roster failed | |
123 session.send(st.error_reply(stanza, err_type, err_cond, err_msg)); | |
124 end | |
125 end | |
126 else | |
127 -- Trying to add self to roster | |
128 session.send(st.error_reply(stanza, "cancel", "not-allowed")); | |
129 end | |
130 else | |
131 -- Invalid JID added to roster | |
132 session.send(st.error_reply(stanza, "modify", "bad-request")); -- FIXME what's the correct error? | |
133 end | |
134 else | |
135 -- Roster set didn't include a single item, or its name wasn't 'item' | |
136 session.send(st.error_reply(stanza, "modify", "bad-request")); | |
137 end | |
138 return true; | |
139 end | 127 end |
128 else | |
129 -- Invalid JID added to roster | |
130 session.send(st.error_reply(stanza, "modify", "bad-request")); -- FIXME what's the correct error? | |
140 end | 131 end |
141 end); | 132 else |
133 -- Roster set didn't include a single item, or its name wasn't 'item' | |
134 session.send(st.error_reply(stanza, "modify", "bad-request")); | |
135 end | |
136 end | |
137 return true; | |
138 end); |