Comparison

mod_delegation/mod_delegation.lua @ 1712:c1973605d096

mod_delegation: disco nesting for host
author Goffi <goffi@goffi.org>
date Fri, 17 Apr 2015 21:06:30 +0200
parent 1711:55b9ac807ac9
child 1713:01e9465f8f80
comparison
equal deleted inserted replaced
1711:55b9ac807ac9 1712:c1973605d096
23 end 23 end
24 local connected_cb = delegation_session.connected_cb 24 local connected_cb = delegation_session.connected_cb
25 25
26 local _DELEGATION_NS = 'urn:xmpp:delegation:1' 26 local _DELEGATION_NS = 'urn:xmpp:delegation:1'
27 local _FORWARDED_NS = 'urn:xmpp:forward:0' 27 local _FORWARDED_NS = 'urn:xmpp:forward:0'
28 local _DISCO_NS = 'http://jabber.org/protocol/disco#info'
28 local _ORI_ID_PREFIX = "IQ_RESULT_" 29 local _ORI_ID_PREFIX = "IQ_RESULT_"
30
31 local _MAIN_SEP = '::'
32 --local _BARE_SEP = ':bare:'
33
34 local disco_nest
29 35
30 module:log("debug", "Loading namespace delegation module "); 36 module:log("debug", "Loading namespace delegation module ");
31 37
32 38
33 --> Configuration management <-- 39 --> Configuration management <--
82 88
83 local function set_connected(entity_jid) 89 local function set_connected(entity_jid)
84 -- set the "connected" key for all namespace managed by entity_jid 90 -- set the "connected" key for all namespace managed by entity_jid
85 -- if the namespace has already a connected entity, ignore the new one 91 -- if the namespace has already a connected entity, ignore the new one
86 local function set_config(jid_) 92 local function set_config(jid_)
87 for _, ns_data in pairs(jid2ns[jid_]) do 93 for namespace, ns_data in pairs(jid2ns[jid_]) do
88 if ns_data.connected == nil then 94 if ns_data.connected == nil then
89 ns_data.connected = entity_jid 95 ns_data.connected = entity_jid
96 disco_nest(namespace, entity_jid)
90 end 97 end
91 end 98 end
92 end 99 end
93 local bare_jid = jid.bare(entity_jid) 100 local bare_jid = jid.bare(entity_jid)
94 set_config(bare_jid) 101 set_config(bare_jid)
241 module:hook("iq/self", iq_hook, 2^32) 248 module:hook("iq/self", iq_hook, 2^32)
242 module:hook("iq/host", iq_hook, 2^32) 249 module:hook("iq/host", iq_hook, 2^32)
243 250
244 251
245 --> discovery nesting <-- 252 --> discovery nesting <--
253
254 -- disabling internal features/identities
246 255
247 -- modules whose features/identities are managed by delegation 256 -- modules whose features/identities are managed by delegation
248 local disabled_modules = set.new() 257 local disabled_modules = set.new()
249 258
250 local function identity_added(event) 259 local function identity_added(event)
281 -- for disco nesting (see § 7.2) we need to remove internal features 290 -- for disco nesting (see § 7.2) we need to remove internal features
282 -- we use handle_items as it allow to remove already added features 291 -- we use handle_items as it allow to remove already added features
283 -- and catch the ones which can come later 292 -- and catch the ones which can come later
284 module:handle_items("feature", feature_added, function(_) end) 293 module:handle_items("feature", feature_added, function(_) end)
285 module:handle_items("identity", identity_added, function(_) end, false) 294 module:handle_items("identity", identity_added, function(_) end, false)
295
296
297 -- managing entity features/identities collection
298
299 local disco_main_error
300
301 local function disco_main_result(event)
302 local session, stanza = event.origin, event.stanza
303 if stanza.attr.to ~= module.host then
304 module:log("warn", 'Stanza result has "to" attribute not addressed to current host, id conflict ?')
305 return
306 end
307 module:unhook("iq-result/host/"..stanza.attr.id, disco_main_result)
308 module:unhook("iq-error/host/"..stanza.attr.id, disco_main_error)
309 local query = stanza:get_child("query", _DISCO_NS)
310 if not query or not query.attr.node then
311 session.send(st.error_reply(stanza, 'modify', 'not-acceptable'))
312 return true
313 end
314 -- local node = query.attr.node
315 for feature in query:childtags("feature") do
316 local namespace = feature.attr.var
317 if not module:has_feature(namespace) then -- we avoid doubling features in case of disconnection/reconnexion
318 module:add_feature(namespace)
319 end
320 end
321 for identity in query:childtags("identity") do
322 local category, type_, name = identity.attr.category, identity.attr.type, identity.attr.name
323 if not module:has_identity(category, type_, name) then
324 module:add_identity(category, type_, name)
325 end
326 end
327 end
328
329 function disco_main_error(event)
330 local stanza = event.stanza
331 if stanza.attr.to ~= module.host then
332 module:log("warn", 'Stanza result has "to" attribute not addressed to current host, id conflict ?')
333 return
334 end
335 module:unhook("iq-result/host/"..stanza.attr.id, disco_main_result)
336 module:unhook("iq-error/host/"..stanza.attr.id, disco_main_error)
337 module:log("warn", "Got an error while requesting disco for nesting to "..stanza.attr.from)
338 module:log("warn", "Ignoring disco nesting")
339 end
340
341 function disco_nest(namespace, entity_jid)
342 local main_node = _DELEGATION_NS.._MAIN_SEP..namespace
343 -- local bare_node = _DELEGATION_NS.._BARE_SEP..namespace
344
345 local iq = st.iq({from=module.host, to=entity_jid, type='get'})
346 :tag('query', {xmlns=_DISCO_NS, node=main_node})
347
348 local iq_id = iq.attr.id
349
350 module:hook("iq-result/host/"..iq_id, disco_main_result)
351 module:hook("iq-error/host/"..iq_id, disco_main_error)
352 module:send(iq)
353 end