Comparison

plugins/mod_disco.lua @ 5689:832ea1e9ac9e

mod_disco: Allow ansering disco requests including nodes, and adding custom items to disco#items requests
author Florian Zeitz <florob@babelmonkeys.de>
date Tue, 04 Jun 2013 23:59:59 +0200
parent 5627:0439d1349dc1
child 5772:9cef4b5c2fe3
comparison
equal deleted inserted replaced
5688:345761f0c2be 5689:832ea1e9ac9e
30 break; 30 break;
31 end 31 end
32 end 32 end
33 end 33 end
34 34
35 module:add_identity("server", "im", module:get_option_string("name", "Prosody")); -- FIXME should be in the non-existing mod_router 35 if module:get_host_type() == "normal" then
36 module:add_identity("server", "im", module:get_option_string("name", "Prosody")); -- FIXME should be in the non-existing mod_router
37 end
36 module:add_feature("http://jabber.org/protocol/disco#info"); 38 module:add_feature("http://jabber.org/protocol/disco#info");
37 module:add_feature("http://jabber.org/protocol/disco#items"); 39 module:add_feature("http://jabber.org/protocol/disco#items");
38 40
39 -- Generate and cache disco result and caps hash 41 -- Generate and cache disco result and caps hash
40 local _cached_server_disco_info, _cached_server_caps_feature, _cached_server_caps_hash; 42 local _cached_server_disco_info, _cached_server_caps_feature, _cached_server_caps_hash;
95 -- Handle disco requests to the server 97 -- Handle disco requests to the server
96 module:hook("iq/host/http://jabber.org/protocol/disco#info:query", function(event) 98 module:hook("iq/host/http://jabber.org/protocol/disco#info:query", function(event)
97 local origin, stanza = event.origin, event.stanza; 99 local origin, stanza = event.origin, event.stanza;
98 if stanza.attr.type ~= "get" then return; end 100 if stanza.attr.type ~= "get" then return; end
99 local node = stanza.tags[1].attr.node; 101 local node = stanza.tags[1].attr.node;
100 if node and node ~= "" and node ~= "http://prosody.im#"..get_server_caps_hash() then return; end -- TODO fire event? 102 if node and node ~= "" and node ~= "http://prosody.im#"..get_server_caps_hash() then
103 local reply = st.reply(stanza):tag('query', {xmlns='http://jabber.org/protocol/disco#info', node=node});
104 local event = { origin = origin, stanza = stanza, reply = reply, node = node, exists = false};
105 local ret = module:fire_event("host-disco-info-node", event);
106 if ret ~= nil then return ret; end
107 if event.exists then
108 origin.send(reply);
109 else
110 origin.send(st.error_reply(stanza, "cancel", "item-not-found", "Node does not exist"));
111 end
112 return true;
113 end
101 local reply_query = get_server_disco_info(); 114 local reply_query = get_server_disco_info();
102 reply_query.node = node; 115 reply_query.node = node;
103 local reply = st.reply(stanza):add_child(reply_query); 116 local reply = st.reply(stanza):add_child(reply_query);
104 origin.send(reply); 117 origin.send(reply);
105 return true; 118 return true;
106 end); 119 end);
107 module:hook("iq/host/http://jabber.org/protocol/disco#items:query", function(event) 120 module:hook("iq/host/http://jabber.org/protocol/disco#items:query", function(event)
108 local origin, stanza = event.origin, event.stanza; 121 local origin, stanza = event.origin, event.stanza;
109 if stanza.attr.type ~= "get" then return; end 122 if stanza.attr.type ~= "get" then return; end
110 local node = stanza.tags[1].attr.node; 123 local node = stanza.tags[1].attr.node;
111 if node and node ~= "" then return; end -- TODO fire event? 124 if node and node ~= "" then
112 125 local reply = st.reply(stanza):tag('query', {xmlns='http://jabber.org/protocol/disco#items', node=node});
126 local event = { origin = origin, stanza = stanza, reply = reply, node = node, exists = false};
127 local ret = module:fire_event("host-disco-items-node", event);
128 if ret ~= nil then return ret; end
129 if event.exists then
130 origin.send(reply);
131 else
132 origin.send(st.error_reply(stanza, "cancel", "item-not-found", "Node does not exist"));
133 end
134 return true;
135 end
113 local reply = st.reply(stanza):query("http://jabber.org/protocol/disco#items"); 136 local reply = st.reply(stanza):query("http://jabber.org/protocol/disco#items");
137 local ret = module:fire_event("host-disco-items", { origin = origin, stanza = stanza, reply = reply });
138 if ret ~= nil then return ret; end
114 for jid, name in pairs(get_children(module.host)) do 139 for jid, name in pairs(get_children(module.host)) do
115 reply:tag("item", {jid = jid, name = name~=true and name or nil}):up(); 140 reply:tag("item", {jid = jid, name = name~=true and name or nil}):up();
116 end 141 end
117 for _, item in ipairs(disco_items) do 142 for _, item in ipairs(disco_items) do
118 reply:tag("item", {jid=item[1], name=item[2]}):up(); 143 reply:tag("item", {jid=item[1], name=item[2]}):up();
136 local username = jid_split(stanza.attr.to) or origin.username; 161 local username = jid_split(stanza.attr.to) or origin.username;
137 if not stanza.attr.to or is_contact_subscribed(username, module.host, jid_bare(stanza.attr.from)) then 162 if not stanza.attr.to or is_contact_subscribed(username, module.host, jid_bare(stanza.attr.from)) then
138 if node and node ~= "" then 163 if node and node ~= "" then
139 local reply = st.reply(stanza):tag('query', {xmlns='http://jabber.org/protocol/disco#info', node=node}); 164 local reply = st.reply(stanza):tag('query', {xmlns='http://jabber.org/protocol/disco#info', node=node});
140 if not reply.attr.from then reply.attr.from = origin.username.."@"..origin.host; end -- COMPAT To satisfy Psi when querying own account 165 if not reply.attr.from then reply.attr.from = origin.username.."@"..origin.host; end -- COMPAT To satisfy Psi when querying own account
141 local event = { origin = origin, stanza = stanza, reply = reply, node = node, exists = false} 166 local event = { origin = origin, stanza = stanza, reply = reply, node = node, exists = false};
142 module:fire_event("account-disco-info-node", event); 167 local ret = module:fire_event("account-disco-info-node", event);
168 if ret ~= nil then return ret; end
143 if event.exists then 169 if event.exists then
144 origin.send(reply); 170 origin.send(reply);
145 else 171 else
146 origin.send(st.error_reply(stanza, "cancel", "item-not-found", "Node does not exist")); 172 origin.send(st.error_reply(stanza, "cancel", "item-not-found", "Node does not exist"));
147 end 173 end
161 local username = jid_split(stanza.attr.to) or origin.username; 187 local username = jid_split(stanza.attr.to) or origin.username;
162 if not stanza.attr.to or is_contact_subscribed(username, module.host, jid_bare(stanza.attr.from)) then 188 if not stanza.attr.to or is_contact_subscribed(username, module.host, jid_bare(stanza.attr.from)) then
163 if node and node ~= "" then 189 if node and node ~= "" then
164 local reply = st.reply(stanza):tag('query', {xmlns='http://jabber.org/protocol/disco#items', node=node}); 190 local reply = st.reply(stanza):tag('query', {xmlns='http://jabber.org/protocol/disco#items', node=node});
165 if not reply.attr.from then reply.attr.from = origin.username.."@"..origin.host; end -- COMPAT To satisfy Psi when querying own account 191 if not reply.attr.from then reply.attr.from = origin.username.."@"..origin.host; end -- COMPAT To satisfy Psi when querying own account
166 local event = { origin = origin, stanza = stanza, reply = reply, node = node, exists = false} 192 local event = { origin = origin, stanza = stanza, reply = reply, node = node, exists = false};
167 module:fire_event("account-disco-items-node", event); 193 local ret = module:fire_event("account-disco-items-node", event);
194 if ret ~= nil then return ret; end
168 if event.exists then 195 if event.exists then
169 origin.send(reply); 196 origin.send(reply);
170 else 197 else
171 origin.send(st.error_reply(stanza, "cancel", "item-not-found", "Node does not exist")); 198 origin.send(st.error_reply(stanza, "cancel", "item-not-found", "Node does not exist"));
172 end 199 end