Software /
code /
prosody-modules
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 |
parent | 1710:b68eed25b880 |
child | 1712: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) |