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 |