Mercurial > prosody-modules
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); |