changeset 1711:55b9ac807ac9

mod_delegation: delegated features/identities are removed from disco.
author Goffi <goffi@goffi.org>
date Fri, 17 Apr 2015 21:05:40 +0200
parents b68eed25b880
children c1973605d096
files mod_delegation/mod_delegation.lua
diffstat 1 files changed, 44 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/mod_delegation/mod_delegation.lua	Fri Apr 17 21:05:08 2015 +0200
+++ b/mod_delegation/mod_delegation.lua	Fri Apr 17 21:05:40 2015 +0200
@@ -198,7 +198,6 @@
 	local iq_id = iq_stanza.attr.id
 	-- we save the original stanza to check the managing entity result
 	ns_data[_ORI_ID_PREFIX..iq_id] = stanza
-	module:log("debug", "stanza forwarded to "..to_jid..": "..tostring(iq_stanza))
 	module:hook("iq-result/host/"..iq_id, managing_ent_result)
 	module:send(iq_stanza)
 end
@@ -214,14 +213,13 @@
 		local ns_data = ns_delegations[namespace]
 
 		if ns_data then
-			module:log("debug", "Namespace %s is delegated", namespace)
 			if ns_data.filtering then
 				local first_child = stanza.tags[1]
 				for _, attribute in ns_data.filtering do
 					-- if any filtered attribute if not present,
 					-- we must continue the normal bahaviour
 					if not first_child.attr[attribute] then
-						module:log("debug", "Filtered attribute %s not present, doing normal workflow", attribute)
+						-- Filtered attribute is not present, we do normal workflow
 						return;
 					end
 				end
@@ -230,8 +228,6 @@
 				module:log("warn", "No connected entity to manage "..namespace)
 				session.send(st.error_reply(stanza, 'cancel', 'service-unavailable'))
 			else
-				local managing_entity = ns_data.connected
-				module:log("debug", "Entity %s is managing %s", managing_entity, namespace)
 				forward_iq(stanza, ns_data)
 			end
 			return true
@@ -244,3 +240,46 @@
 
 module:hook("iq/self", iq_hook, 2^32)
 module:hook("iq/host", iq_hook, 2^32)
+
+
+--> discovery nesting <--
+
+-- modules whose features/identities are managed by delegation
+local disabled_modules = set.new()
+
+local function identity_added(event)
+	local source = event.source
+	if disabled_modules:contains(source) then
+		local item = event.item
+		local category, type_, name = item.category, item.type, item.name
+		module:log("debug", "Removing (%s/%s%s) identity because of delegation", category, type_, name and "/"..name or "")
+		source:remove_item("identity", item)
+	end
+
+end
+
+local function feature_added(event)
+	local source, item = event.source, event.item
+	for namespace, _ in pairs(ns_delegations) do
+		if source ~= module and string.sub(item, 1, #namespace) == namespace then
+			module:log("debug", "Removing %s feature which is delegated", item)
+			source:remove_item("feature", item)
+			disabled_modules:add(source)
+			if source.items and source.items.identity then
+				-- we remove all identities added by the source module
+				-- that can cause issues if the module manages several features/identities
+				-- but this case is probably rare (or doesn't happen at all)
+				-- FIXME: any better way ?
+				for _, identity in pairs(source.items.identity) do
+					identity_added({source=source, item=identity})
+				end
+			end
+		end
+	end
+end
+
+-- for disco nesting (see ยง 7.2) we need to remove internal features
+-- we use handle_items as it allow to remove already added features
+-- and catch the ones which can come later
+module:handle_items("feature", feature_added, function(_) end)
+module:handle_items("identity", identity_added, function(_) end, false)