comparison mod_delegation/mod_delegation.lua @ 1716:29dfdfc767b4

mod_delegation: service discovery extensions (xep-0128) management
author Goffi <goffi@goffi.org>
date Sat, 18 Apr 2015 00:13:09 +0200
parents 241c061bb953
children e22cd2205fc1
comparison
equal deleted inserted replaced
1715:241c061bb953 1716:29dfdfc767b4
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 _DISCO_NS = 'http://jabber.org/protocol/disco#info'
29 local _DATA_NS = 'jabber:x:data'
29 local _ORI_ID_PREFIX = "IQ_RESULT_" 30 local _ORI_ID_PREFIX = "IQ_RESULT_"
30 31
31 local _MAIN_SEP = '::' 32 local _MAIN_SEP = '::'
32 local _BARE_SEP = ':bare:' 33 local _BARE_SEP = ':bare:'
33 local _MAIN_PREFIX = _DELEGATION_NS.._MAIN_SEP 34 local _MAIN_PREFIX = _DELEGATION_NS.._MAIN_SEP
256 257
257 258
258 --> discovery nesting <-- 259 --> discovery nesting <--
259 260
260 -- disabling internal features/identities 261 -- disabling internal features/identities
262
263 local function find_form_type(stanza)
264 local form_type = nil
265 for field in stanza.childtags('field', 'jabber:x:data') do
266 if field.attr.var=='FORM_TYPE' and field.attr.type=='hidden' then
267 local value = field:get_child('value')
268 if not value then
269 module:log("warn", "No value found in FORM_TYPE field: "..tostring(stanza))
270 else
271 form_type=value.get_text()
272 end
273 end
274 end
275 return form_type
276 end
261 277
262 -- modules whose features/identities are managed by delegation 278 -- modules whose features/identities are managed by delegation
263 local disabled_modules = set.new() 279 local disabled_modules = set.new()
264 local disabled_identities = set.new() 280 local disabled_identities = set.new()
265 281
292 end 308 end
293 end 309 end
294 end 310 end
295 end 311 end
296 312
313 local function extension_added(event)
314 local source, stanza = event.source, event.item
315 local form_type = find_form_type(stanza)
316 if not form_type then return; end
317
318 for namespace, _ in pairs(ns_delegations) do
319 if source ~= module and string.sub(form_type, 1, #namespace) == namespace then
320 module:log("debug", "Removing extension which is delegated: %s", tostring(stanza))
321 source:remove_item("extension", stanza)
322 end
323 end
324 end
325
297 -- for disco nesting (see § 7.2) we need to remove internal features 326 -- for disco nesting (see § 7.2) we need to remove internal features
298 -- we use handle_items as it allow to remove already added features 327 -- we use handle_items as it allow to remove already added features
299 -- and catch the ones which can come later 328 -- and catch the ones which can come later
300 module:handle_items("feature", feature_added, function(_) end) 329 module:handle_items("feature", feature_added, function(_) end)
301 module:handle_items("identity", identity_added, function(_) end, false) 330 module:handle_items("identity", identity_added, function(_) end, false)
331 module:handle_items("extension", extension_added, function(_) end)
302 332
303 333
304 -- managing entity features/identities collection 334 -- managing entity features/identities collection
305 335
306 local disco_error 336 local disco_error
307 local bare_features = set.new() 337 local bare_features = set.new()
308 local bare_identities = {} 338 local bare_identities = {}
339 local bare_extensions = {}
309 340
310 local function disco_result(event) 341 local function disco_result(event)
311 -- parse result from disco nesting request 342 -- parse result from disco nesting request
312 -- and fill module features/identities and bare_features/bare_identities accordingly 343 -- and fill module features/identities and bare_features/bare_identities accordingly
313 local session, stanza = event.origin, event.stanza 344 local session, stanza = event.origin, event.stanza
363 if not found then 394 if not found then
364 table.insert(bare_identities, {category=category, type=type_, name=name}) 395 table.insert(bare_identities, {category=category, type=type_, name=name})
365 end 396 end
366 end 397 end
367 end 398 end
399 for extension in query:childtags("x", _DATA_NS) do
400 if main then
401 module:add_extension(extension)
402 else
403 table.insert(bare_extensions, extension)
404 end
405 end
368 end 406 end
369 407
370 function disco_error(event) 408 function disco_error(event)
371 local stanza = event.stanza 409 local stanza = event.stanza
372 if stanza.attr.to ~= module.host then 410 if stanza.attr.to ~= module.host then
396 434
397 -- disco to bare jids special case 435 -- disco to bare jids special case
398 436
399 module:hook("account-disco-info", function(event) 437 module:hook("account-disco-info", function(event)
400 -- this event is called when a disco info request is done on a bare jid 438 -- this event is called when a disco info request is done on a bare jid
401 -- we get the final reply and filter delegated features/identities 439 -- we get the final reply and filter delegated features/identities/extensions
402 local reply = event.reply; 440 local reply = event.reply;
403 reply.tags[1]:maptags(function(child) 441 reply.tags[1]:maptags(function(child)
404 if child.name == 'feature' then 442 if child.name == 'feature' then
405 local feature_ns = child.attr.var 443 local feature_ns = child.attr.var
406 for namespace, _ in pairs(ns_delegations) do 444 for namespace, _ in pairs(ns_delegations) do
418 then 456 then
419 module:log("debug", "Removing (%s/%s%s) identity because of delegation", item.category, item.type, item.name and "/"..item.name or "") 457 module:log("debug", "Removing (%s/%s%s) identity because of delegation", item.category, item.type, item.name and "/"..item.name or "")
420 return nil 458 return nil
421 end 459 end
422 end 460 end
461 elseif child.name == 'x' and child.attr.xmlns == _DATA_NS then
462 local form_type = find_form_type(child)
463 if form_type then
464 for namespace, _ in pairs(ns_delegations) do
465 if string.sub(form_type, 1, #namespace) == namespace then
466 module:log("debug", "Removing extension which is delegated: %s", tostring(child))
467 return nil
468 end
469 end
470 end
471
423 end 472 end
424 return child 473 return child
425 end) 474 end)
426 for feature in bare_features:items() do 475 for feature in bare_features:items() do
427 reply:tag('feature', {var=feature}):up(); 476 reply:tag('feature', {var=feature}):up()
428 end 477 end
429 for _, item in ipairs(bare_identities) do 478 for _, item in ipairs(bare_identities) do
430 reply:tag('identity', {category=item.category, type=item.type, name=item.name}):up(); 479 reply:tag('identity', {category=item.category, type=item.type, name=item.name}):up()
480 end
481 for _, stanza in ipairs(bare_extensions) do
482 reply:add_child(stanza)
431 end 483 end
432 484
433 end, -2^32); 485 end, -2^32);