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