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