Comparison

mod_delegation/mod_delegation.lua @ 1721:f49359330493

mod_delegation: handling of error replies from managing entities after forward.
author Goffi <goffi@goffi.org>
date Sun, 03 May 2015 17:50:16 +0200
parent 1720:48b7e8021afa
child 1722:c48c7f948cfb
comparison
equal deleted inserted replaced
1720:48b7e8021afa 1721:f49359330493
5 -- COPYING file in the source package for more information. 5 -- COPYING file in the source package for more information.
6 6
7 -- This module manage namespace delegation, a way to delegate server features 7 -- This module manage namespace delegation, a way to delegate server features
8 -- to an external entity/component. Only the admin mode is implemented so far 8 -- to an external entity/component. Only the admin mode is implemented so far
9 9
10 -- TODO: client mode, managing entity error handling, disco extensions (XEP-0128) 10 -- TODO: client mode
11 11
12 local jid = require("util/jid") 12 local jid = require("util/jid")
13 local st = require("util/stanza") 13 local st = require("util/stanza")
14 local set = require("util/set") 14 local set = require("util/set")
15 15
148 module:hook('presence/initial', on_presence) 148 module:hook('presence/initial', on_presence)
149 149
150 150
151 --> delegated namespaces hook <-- 151 --> delegated namespaces hook <--
152 152
153 local managing_ent_error
153 local stanza_cache = {} -- we cache original stanza to build reply 154 local stanza_cache = {} -- we cache original stanza to build reply
155
154 local function managing_ent_result(event) 156 local function managing_ent_result(event)
155 -- this function manage iq results from the managing entity 157 -- this function manage iq results from the managing entity
156 -- it do a couple of security check before sending the 158 -- it do a couple of security check before sending the
157 -- result to the managed entity 159 -- result to the managed entity
158 local stanza = event.stanza 160 local stanza = event.stanza
159 if stanza.attr.to ~= module.host then 161 if stanza.attr.to ~= module.host then
160 module:log("warn", 'forwarded stanza result has "to" attribute not addressed to current host, id conflict ?') 162 module:log("warn", 'forwarded stanza result has "to" attribute not addressed to current host, id conflict ?')
161 return 163 return
162 end 164 end
163 module:unhook("iq-result/host/"..stanza.attr.id, managing_ent_result) 165 module:unhook("iq-result/host/"..stanza.attr.id, managing_ent_result)
166 module:unhook("iq-error/host/"..stanza.attr.id, managing_ent_error)
164 167
165 -- lot of checks to do... 168 -- lot of checks to do...
166 local delegation = stanza.tags[1] 169 local delegation = stanza.tags[1]
167 if #stanza ~= 1 or delegation.name ~= "delegation" or 170 if #stanza ~= 1 or delegation.name ~= "delegation" or
168 delegation.attr.xmlns ~= _DELEGATION_NS then 171 delegation.attr.xmlns ~= _DELEGATION_NS then
199 end 202 end
200 203
201 -- at this point eveything is checked, 204 -- at this point eveything is checked,
202 -- and we (hopefully) can send the the result safely 205 -- and we (hopefully) can send the the result safely
203 module:send(iq) 206 module:send(iq)
207 end
208
209 function managing_ent_error(event)
210 local stanza = event.stanza
211 if stanza.attr.to ~= module.host then
212 module:log("warn", 'Stanza result has "to" attribute not addressed to current host, id conflict ?')
213 return
214 end
215 module:unhook("iq-result/host/"..stanza.attr.id, managing_ent_result)
216 module:unhook("iq-error/host/"..stanza.attr.id, managing_ent_error)
217 local original = stanza_cache[stanza.attr.from][stanza.attr.id]
218 stanza_cache[stanza.attr.from][stanza.attr.id] = nil
219 module:log("warn", "Got an error after forwarding stanza to "..stanza.attr.from)
220 module:send(st.error_reply(original, 'cancel', 'service-unavailable'))
204 end 221 end
205 222
206 local function forward_iq(stanza, ns_data) 223 local function forward_iq(stanza, ns_data)
207 local to_jid = ns_data.connected 224 local to_jid = ns_data.connected
208 local iq_stanza = st.iq({ from=module.host, to=to_jid, type="set" }) 225 local iq_stanza = st.iq({ from=module.host, to=to_jid, type="set" })
212 local iq_id = iq_stanza.attr.id 229 local iq_id = iq_stanza.attr.id
213 -- we save the original stanza to check the managing entity result 230 -- we save the original stanza to check the managing entity result
214 if not stanza_cache[to_jid] then stanza_cache[to_jid] = {} end 231 if not stanza_cache[to_jid] then stanza_cache[to_jid] = {} end
215 stanza_cache[to_jid][iq_id] = stanza 232 stanza_cache[to_jid][iq_id] = stanza
216 module:hook("iq-result/host/"..iq_id, managing_ent_result) 233 module:hook("iq-result/host/"..iq_id, managing_ent_result)
234 module:hook("iq-error/host/"..iq_id, managing_ent_error)
235 module:log("debug", "stanza forwarded")
217 module:send(iq_stanza) 236 module:send(iq_stanza)
218 end 237 end
219 238
220 local function iq_hook(event) 239 local function iq_hook(event)
221 -- general hook for all the iq which forward delegated ones 240 -- general hook for all the iq which forward delegated ones