Software /
code /
prosody
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 |