Software /
code /
prosody-modules
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 |
parent | 1715:241c061bb953 |
child | 1717: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); |