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 |