comparison mod_delegation/mod_delegation.lua @ 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
comparison
equal deleted inserted replaced
1710:b68eed25b880 1711:55b9ac807ac9
196 :tag("forwarded", { xmlns=_FORWARDED_NS }) 196 :tag("forwarded", { xmlns=_FORWARDED_NS })
197 :add_child(stanza) 197 :add_child(stanza)
198 local iq_id = iq_stanza.attr.id 198 local iq_id = iq_stanza.attr.id
199 -- we save the original stanza to check the managing entity result 199 -- we save the original stanza to check the managing entity result
200 ns_data[_ORI_ID_PREFIX..iq_id] = stanza 200 ns_data[_ORI_ID_PREFIX..iq_id] = stanza
201 module:log("debug", "stanza forwarded to "..to_jid..": "..tostring(iq_stanza))
202 module:hook("iq-result/host/"..iq_id, managing_ent_result) 201 module:hook("iq-result/host/"..iq_id, managing_ent_result)
203 module:send(iq_stanza) 202 module:send(iq_stanza)
204 end 203 end
205 204
206 local function iq_hook(event) 205 local function iq_hook(event)
212 if #stanza == 1 and stanza.attr.type == 'get' or stanza.attr.type == 'set' then 211 if #stanza == 1 and stanza.attr.type == 'get' or stanza.attr.type == 'set' then
213 local namespace = stanza.tags[1].attr.xmlns 212 local namespace = stanza.tags[1].attr.xmlns
214 local ns_data = ns_delegations[namespace] 213 local ns_data = ns_delegations[namespace]
215 214
216 if ns_data then 215 if ns_data then
217 module:log("debug", "Namespace %s is delegated", namespace)
218 if ns_data.filtering then 216 if ns_data.filtering then
219 local first_child = stanza.tags[1] 217 local first_child = stanza.tags[1]
220 for _, attribute in ns_data.filtering do 218 for _, attribute in ns_data.filtering do
221 -- if any filtered attribute if not present, 219 -- if any filtered attribute if not present,
222 -- we must continue the normal bahaviour 220 -- we must continue the normal bahaviour
223 if not first_child.attr[attribute] then 221 if not first_child.attr[attribute] then
224 module:log("debug", "Filtered attribute %s not present, doing normal workflow", attribute) 222 -- Filtered attribute is not present, we do normal workflow
225 return; 223 return;
226 end 224 end
227 end 225 end
228 end 226 end
229 if not ns_data.connected then 227 if not ns_data.connected then
230 module:log("warn", "No connected entity to manage "..namespace) 228 module:log("warn", "No connected entity to manage "..namespace)
231 session.send(st.error_reply(stanza, 'cancel', 'service-unavailable')) 229 session.send(st.error_reply(stanza, 'cancel', 'service-unavailable'))
232 else 230 else
233 local managing_entity = ns_data.connected
234 module:log("debug", "Entity %s is managing %s", managing_entity, namespace)
235 forward_iq(stanza, ns_data) 231 forward_iq(stanza, ns_data)
236 end 232 end
237 return true 233 return true
238 else 234 else
239 -- we have no delegation, we continue normal behaviour 235 -- we have no delegation, we continue normal behaviour
242 end 238 end
243 end 239 end
244 240
245 module:hook("iq/self", iq_hook, 2^32) 241 module:hook("iq/self", iq_hook, 2^32)
246 module:hook("iq/host", iq_hook, 2^32) 242 module:hook("iq/host", iq_hook, 2^32)
243
244
245 --> discovery nesting <--
246
247 -- modules whose features/identities are managed by delegation
248 local disabled_modules = set.new()
249
250 local function identity_added(event)
251 local source = event.source
252 if disabled_modules:contains(source) then
253 local item = event.item
254 local category, type_, name = item.category, item.type, item.name
255 module:log("debug", "Removing (%s/%s%s) identity because of delegation", category, type_, name and "/"..name or "")
256 source:remove_item("identity", item)
257 end
258
259 end
260
261 local function feature_added(event)
262 local source, item = event.source, event.item
263 for namespace, _ in pairs(ns_delegations) do
264 if source ~= module and string.sub(item, 1, #namespace) == namespace then
265 module:log("debug", "Removing %s feature which is delegated", item)
266 source:remove_item("feature", item)
267 disabled_modules:add(source)
268 if source.items and source.items.identity then
269 -- we remove all identities added by the source module
270 -- that can cause issues if the module manages several features/identities
271 -- but this case is probably rare (or doesn't happen at all)
272 -- FIXME: any better way ?
273 for _, identity in pairs(source.items.identity) do
274 identity_added({source=source, item=identity})
275 end
276 end
277 end
278 end
279 end
280
281 -- for disco nesting (see ยง 7.2) we need to remove internal features
282 -- we use handle_items as it allow to remove already added features
283 -- and catch the ones which can come later
284 module:handle_items("feature", feature_added, function(_) end)
285 module:handle_items("identity", identity_added, function(_) end, false)