mod_delegation/mod_delegation.lua
changeset 1716 c1973605d096
parent 1715 55b9ac807ac9
child 1717 01e9465f8f80
equal deleted inserted replaced
1715:55b9ac807ac9 1716: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