comparison mod_delegation/mod_delegation.lua @ 1714:3d83f5337a73

mod_delegation: disco info request on bare jid is now managed
author Goffi <goffi@goffi.org>
date Fri, 17 Apr 2015 21:07:05 +0200
parents 01e9465f8f80
children 241c061bb953
comparison
equal deleted inserted replaced
1713:01e9465f8f80 1714:3d83f5337a73
5 -- COPYING file in the source package for more information. 5 -- COPYING file in the source package for more information.
6 6
7 -- This module manage namespace delegation, a way to delegate server features 7 -- This module manage namespace delegation, a way to delegate server features
8 -- to an external entity/component. Only the admin mode is implemented so far 8 -- to an external entity/component. Only the admin mode is implemented so far
9 9
10 -- TODO: client mode, managing entity error handling 10 -- TODO: client mode, managing entity error handling, disco extensions (XEP-0128)
11 11
12 local jid = require("util/jid") 12 local jid = require("util/jid")
13 local st = require("util/stanza") 13 local st = require("util/stanza")
14 local set = require("util/set") 14 local set = require("util/set")
15 15
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 _DISCO_NS = 'http://jabber.org/protocol/disco#info'
29 local _ORI_ID_PREFIX = "IQ_RESULT_" 29 local _ORI_ID_PREFIX = "IQ_RESULT_"
30 30
31 local _MAIN_SEP = '::' 31 local _MAIN_SEP = '::'
32 --local _BARE_SEP = ':bare:' 32 local _BARE_SEP = ':bare:'
33 local _MAIN_PREFIX = _DELEGATION_NS.._MAIN_SEP
34 local _BARE_PREFIX = _DELEGATION_NS.._BARE_SEP
35 local _PREFIXES = {_MAIN_PREFIX, _BARE_PREFIX}
33 36
34 local disco_nest 37 local disco_nest
35 38
36 module:log("debug", "Loading namespace delegation module "); 39 module:log("debug", "Loading namespace delegation module ");
37
38 40
39 --> Configuration management <-- 41 --> Configuration management <--
40 42
41 local ns_delegations = module:get_option("delegations", {}) 43 local ns_delegations = module:get_option("delegations", {})
42 44
295 module:handle_items("identity", identity_added, function(_) end, false) 297 module:handle_items("identity", identity_added, function(_) end, false)
296 298
297 299
298 -- managing entity features/identities collection 300 -- managing entity features/identities collection
299 301
300 local disco_main_error 302 local disco_error
301 303 local bare_features = set.new()
302 local function disco_main_result(event) 304 local bare_identities = {}
305
306 local function disco_result(event)
307 -- parse result from disco nesting request
308 -- and fill module features/identities and bare_features/bare_identities accordingly
303 local session, stanza = event.origin, event.stanza 309 local session, stanza = event.origin, event.stanza
304 if stanza.attr.to ~= module.host then 310 if stanza.attr.to ~= module.host then
305 module:log("warn", 'Stanza result has "to" attribute not addressed to current host, id conflict ?') 311 module:log("warn", 'Stanza result has "to" attribute not addressed to current host, id conflict ?')
306 return 312 return
307 end 313 end
308 module:unhook("iq-result/host/"..stanza.attr.id, disco_main_result) 314 module:unhook("iq-result/host/"..stanza.attr.id, disco_result)
309 module:unhook("iq-error/host/"..stanza.attr.id, disco_main_error) 315 module:unhook("iq-error/host/"..stanza.attr.id, disco_error)
310 local query = stanza:get_child("query", _DISCO_NS) 316 local query = stanza:get_child("query", _DISCO_NS)
311 if not query or not query.attr.node then 317 if not query or not query.attr.node then
312 session.send(st.error_reply(stanza, 'modify', 'not-acceptable')) 318 session.send(st.error_reply(stanza, 'modify', 'not-acceptable'))
313 return true 319 return true
314 end 320 end
315 -- local node = query.attr.node 321
322 local node = query.attr.node
323 local main
324
325 if string.sub(node, 1, #_MAIN_PREFIX) == _MAIN_PREFIX then
326 main=true
327 elseif string.sub(node, 1, #_BARE_PREFIX) == _BARE_PREFIX then
328 main=false
329 else
330 module:log("warn", "Unexpected node: "..node)
331 session.send(st.error_reply(stanza, 'modify', 'not-acceptable'))
332 return true
333 end
334
316 for feature in query:childtags("feature") do 335 for feature in query:childtags("feature") do
317 local namespace = feature.attr.var 336 local namespace = feature.attr.var
318 if not module:has_feature(namespace) then -- we avoid doubling features in case of disconnection/reconnexion 337 if main then
319 module:add_feature(namespace) 338 if not module:has_feature(namespace) then -- we avoid doubling features in case of disconnection/reconnexion
339 module:add_feature(namespace)
340 end
341 else
342 bare_features:add(namespace)
320 end 343 end
321 end 344 end
322 for identity in query:childtags("identity") do 345 for identity in query:childtags("identity") do
323 local category, type_, name = identity.attr.category, identity.attr.type, identity.attr.name 346 local category, type_, name = identity.attr.category, identity.attr.type, identity.attr.name
324 if not module:has_identity(category, type_, name) then 347 if main then
325 module:add_identity(category, type_, name) 348 if not module:has_identity(category, type_, name) then
326 end 349 module:add_identity(category, type_, name)
327 end 350 end
328 end 351 else
329 352 local found=false
330 function disco_main_error(event) 353 for _, item in ipairs(bare_identities) do
354 if item.category == category and item.type == type_ and item.name == name then
355 found=true
356 break
357 end
358 end
359 if not found then
360 table.insert(bare_identities, {category=category, type=type_, name=name})
361 end
362 end
363 end
364 end
365
366 function disco_error(event)
331 local stanza = event.stanza 367 local stanza = event.stanza
332 if stanza.attr.to ~= module.host then 368 if stanza.attr.to ~= module.host then
333 module:log("warn", 'Stanza result has "to" attribute not addressed to current host, id conflict ?') 369 module:log("warn", 'Stanza result has "to" attribute not addressed to current host, id conflict ?')
334 return 370 return
335 end 371 end
336 module:unhook("iq-result/host/"..stanza.attr.id, disco_main_result) 372 module:unhook("iq-result/host/"..stanza.attr.id, disco_result)
337 module:unhook("iq-error/host/"..stanza.attr.id, disco_main_error) 373 module:unhook("iq-error/host/"..stanza.attr.id, disco_error)
338 module:log("warn", "Got an error while requesting disco for nesting to "..stanza.attr.from) 374 module:log("warn", "Got an error while requesting disco for nesting to "..stanza.attr.from)
339 module:log("warn", "Ignoring disco nesting") 375 module:log("warn", "Ignoring disco nesting")
340 end 376 end
341 377
342 function disco_nest(namespace, entity_jid) 378 function disco_nest(namespace, entity_jid)
343 local main_node = _DELEGATION_NS.._MAIN_SEP..namespace 379 for _, prefix in ipairs(_PREFIXES) do
344 -- local bare_node = _DELEGATION_NS.._BARE_SEP..namespace 380 local node = prefix..namespace
345 381
346 local iq = st.iq({from=module.host, to=entity_jid, type='get'}) 382 local iq = st.iq({from=module.host, to=entity_jid, type='get'})
347 :tag('query', {xmlns=_DISCO_NS, node=main_node}) 383 :tag('query', {xmlns=_DISCO_NS, node=node})
348 384
349 local iq_id = iq.attr.id 385 local iq_id = iq.attr.id
350 386
351 module:hook("iq-result/host/"..iq_id, disco_main_result) 387 module:hook("iq-result/host/"..iq_id, disco_result)
352 module:hook("iq-error/host/"..iq_id, disco_main_error) 388 module:hook("iq-error/host/"..iq_id, disco_error)
353 module:send(iq) 389 module:send(iq)
390 end
354 end 391 end
355 392
356 -- disco to bare jids special case 393 -- disco to bare jids special case
357 394
358 module:hook("account-disco-info", function(event) 395 module:hook("account-disco-info", function(event)
380 end 417 end
381 end 418 end
382 end 419 end
383 return child 420 return child
384 end) 421 end)
422 for feature in bare_features:items() do
423 reply:tag('feature', {var=feature}):up();
424 end
425 for _, item in ipairs(bare_identities) do
426 reply:tag('identity', {category=item.category, type=item.type, name=item.name}):up();
427 end
428
385 end, -2^32); 429 end, -2^32);