comparison mod_admin_web/admin_web/mod_admin_web_timber.lua @ 663:a826b61c8f3a

mod_admin_web: Utilize the shared module magic
author Florian Zeitz <florob@babelmonkeys.de>
date Mon, 30 Apr 2012 17:25:09 +0200
parents 210f4ce2697c
children da69b65288e4
comparison
equal deleted inserted replaced
662:b3d130e4b3ae 663:a826b61c8f3a
129 event.response.headers.content_type = mime_map[ext]; -- Content-Type should be nil when not known 129 event.response.headers.content_type = mime_map[ext]; -- Content-Type should be nil when not known
130 return data; 130 return data;
131 end 131 end
132 132
133 function module.add_host(module) 133 function module.add_host(module)
134 -- Setup HTTP server
134 module:depends("http"); 135 module:depends("http");
135 module:provides("http", { 136 module:provides("http", {
136 name = "admin"; 137 name = "admin";
137 route = { 138 route = {
138 ["GET"] = function(event) 139 ["GET"] = function(event)
140 return 301; 141 return 301;
141 end; 142 end;
142 ["GET /*"] = serve_file; 143 ["GET /*"] = serve_file;
143 } 144 }
144 }); 145 });
145 end 146
146 147 -- Setup adminsub service
147 prosody.events.add_handler("server-started", function () 148 local ok, err;
148 for host_name, host_table in pairs(hosts) do 149 service[module.host] = pubsub.new({
149 service[host_name] = pubsub.new({ 150 broadcaster = function(node, jids, item) return simple_broadcast(node, jids, item, module.host) end;
150 broadcaster = function(node, jids, item) return simple_broadcast(node, jids, item, host_name) end; 151 normalize_jid = jid_bare;
151 normalize_jid = jid_bare; 152 get_affiliation = function(jid) return get_affiliation(jid, module.host) end;
152 get_affiliation = function(jid) return get_affiliation(jid, host_name) end; 153 capabilities = {
153 capabilities = { 154 member = {
154 member = { 155 create = false;
155 create = false; 156 publish = false;
156 publish = false; 157 retract = false;
157 retract = false; 158 get_nodes = true;
158 get_nodes = true; 159
159 160 subscribe = true;
160 subscribe = true; 161 unsubscribe = true;
161 unsubscribe = true; 162 get_subscription = true;
162 get_subscription = true; 163 get_subscriptions = true;
163 get_subscriptions = true; 164 get_items = true;
164 get_items = true; 165
165 166 subscribe_other = false;
166 subscribe_other = false; 167 unsubscribe_other = false;
167 unsubscribe_other = false; 168 get_subscription_other = false;
168 get_subscription_other = false; 169 get_subscriptions_other = false;
169 get_subscriptions_other = false; 170
170 171 be_subscribed = true;
171 be_subscribed = true; 172 be_unsubscribed = true;
172 be_unsubscribed = true; 173
173 174 set_affiliation = false;
174 set_affiliation = false;
175 };
176
177 owner = {
178 create = true;
179 publish = true;
180 retract = true;
181 get_nodes = true;
182
183 subscribe = true;
184 unsubscribe = true;
185 get_subscription = true;
186 get_subscriptions = true;
187 get_items = true;
188
189 subscribe_other = true;
190 unsubscribe_other = true;
191 get_subscription_other = true;
192 get_subscriptions_other = true;
193
194 be_subscribed = true;
195 be_unsubscribed = true;
196
197 set_affiliation = true;
198 };
199 }; 175 };
200 }); 176
201 177 owner = {
202 if not select(2, service[host_name]:get_nodes(true))[xmlns_s2s_session] then 178 create = true;
203 local ok, errmsg = service[host_name]:create(xmlns_s2s_session, true); 179 publish = true;
180 retract = true;
181 get_nodes = true;
182
183 subscribe = true;
184 unsubscribe = true;
185 get_subscription = true;
186 get_subscriptions = true;
187 get_items = true;
188
189 subscribe_other = true;
190 unsubscribe_other = true;
191 get_subscription_other = true;
192 get_subscriptions_other = true;
193
194 be_subscribed = true;
195 be_unsubscribed = true;
196
197 set_affiliation = true;
198 };
199 };
200 });
201
202 -- Create node for s2s sessions
203 ok, err = service[module.host]:create(xmlns_s2s_session, true);
204 if not ok then
205 module:log("warn", "Could not create node " .. xmlns_s2s_session .. ": " .. tostring(err));
206 else
207 service[module.host]:set_affiliation(xmlns_s2s_session, true, module.host, "owner")
208 end
209
210 -- Add outgoing s2s sessions
211 for remotehost, session in pairs(hosts[module.host].s2sout) do
212 if session.type ~= "s2sout_unauthed" then
213 add_host(session, "out", module.host);
214 end
215 end
216
217 -- Add incomming s2s sessions
218 for session in pairs(incoming_s2s) do
219 if session.to_host == module.host then
220 add_host(session, "in", module.host);
221 end
222 end
223
224 -- Create node for c2s sessions
225 ok, err = service[module.host]:create(xmlns_c2s_session, true);
226 if not ok then
227 module:log("warn", "Could not create node " .. xmlns_c2s_session .. ": " .. tostring(err));
228 else
229 service[module.host]:set_affiliation(xmlns_c2s_session, true, module.host, "owner")
230 end
231
232 -- Add c2s sessions
233 for username, user in pairs(hosts[module.host].sessions or {}) do
234 for resource, session in pairs(user.sessions or {}) do
235 add_client(session, module.host);
236 end
237 end
238
239 -- Register adminsub handler
240 module:hook("iq/host/http://prosody.im/adminsub:adminsub", function(event)
241 local origin, stanza = event.origin, event.stanza;
242 local adminsub = stanza.tags[1];
243 local action = adminsub.tags[1];
244 local reply;
245 if action.name == "subscribe" then
246 local ok, ret = service[module.host]:add_subscription(action.attr.node, stanza.attr.from, stanza.attr.from);
247 if ok then
248 reply = st.reply(stanza)
249 :tag("adminsub", { xmlns = xmlns_adminsub });
250 else
251 reply = st.error_reply(stanza, "cancel", ret);
252 end
253 elseif action.name == "unsubscribe" then
254 local ok, ret = service[module.host]:remove_subscription(action.attr.node, stanza.attr.from, stanza.attr.from);
255 if ok then
256 reply = st.reply(stanza)
257 :tag("adminsub", { xmlns = xmlns_adminsub });
258 else
259 reply = st.error_reply(stanza, "cancel", ret);
260 end
261 elseif action.name == "items" then
262 local node = action.attr.node;
263 local ok, ret = service[module.host]:get_items(node, stanza.attr.from);
204 if not ok then 264 if not ok then
205 module:log("warn", "Could not create node " .. xmlns_s2s_session .. ": " .. tostring(errmsg)); 265 return origin.send(st.error_reply(stanza, "cancel", ret));
206 else 266 end
207 service[host_name]:set_affiliation(xmlns_s2s_session, true, host_name, "owner") 267
208 end 268 local data = st.stanza("items", { node = node });
209 end 269 for _, entry in pairs(ret) do
210 270 data:add_child(entry);
211 for remotehost, session in pairs(host_table.s2sout) do 271 end
212 if session.type ~= "s2sout_unauthed" then 272 if data then
213 add_host(session, "out", host_name);
214 end
215 end
216 for session in pairs(incoming_s2s) do
217 if session.to_host == host_name then
218 add_host(session, "in", host_name);
219 end
220 end
221
222 if not select(2, service[host_name]:get_nodes(true))[xmlns_c2s_session] then
223 local ok, errmsg = service[host_name]:create(xmlns_c2s_session, true);
224 if not ok then
225 module:log("warn", "Could not create node " .. xmlns_c2s_session .. ": " .. tostring(errmsg));
226 else
227 service[host_name]:set_affiliation(xmlns_c2s_session, true, host_name, "owner")
228 end
229 end
230
231 for username, user in pairs(host_table.sessions or {}) do
232 for resource, session in pairs(user.sessions or {}) do
233 add_client(session, host_name);
234 end
235 end
236
237 host_table.events.add_handler("iq/host/http://prosody.im/adminsub:adminsub", function(event)
238 local origin, stanza = event.origin, event.stanza;
239 local adminsub = stanza.tags[1];
240 local action = adminsub.tags[1];
241 local reply;
242 if action.name == "subscribe" then
243 local ok, ret = service[host_name]:add_subscription(action.attr.node, stanza.attr.from, stanza.attr.from);
244 if ok then
245 reply = st.reply(stanza)
246 :tag("adminsub", { xmlns = xmlns_adminsub });
247 else
248 reply = st.error_reply(stanza, "cancel", ret);
249 end
250 elseif action.name == "unsubscribe" then
251 local ok, ret = service[host_name]:remove_subscription(action.attr.node, stanza.attr.from, stanza.attr.from);
252 if ok then
253 reply = st.reply(stanza)
254 :tag("adminsub", { xmlns = xmlns_adminsub });
255 else
256 reply = st.error_reply(stanza, "cancel", ret);
257 end
258 elseif action.name == "items" then
259 local node = action.attr.node;
260 local ok, ret = service[host_name]:get_items(node, stanza.attr.from);
261 if not ok then
262 return origin.send(st.error_reply(stanza, "cancel", ret));
263 end
264
265 local data = st.stanza("items", { node = node });
266 for _, entry in pairs(ret) do
267 data:add_child(entry);
268 end
269 if data then
270 reply = st.reply(stanza)
271 :tag("adminsub", { xmlns = xmlns_adminsub })
272 :add_child(data);
273 else
274 reply = st.error_reply(stanza, "cancel", "item-not-found");
275 end
276 elseif action.name == "adminfor" then
277 local data = st.stanza("adminfor");
278 for host_name in pairs(hosts) do
279 if is_admin(stanza.attr.from, host_name) then
280 data:tag("item"):text(host_name):up();
281 end
282 end
283 reply = st.reply(stanza) 273 reply = st.reply(stanza)
284 :tag("adminsub", { xmlns = xmlns_adminsub }) 274 :tag("adminsub", { xmlns = xmlns_adminsub })
285 :add_child(data); 275 :add_child(data);
286 else 276 else
287 reply = st.error_reply(stanza, "feature-not-implemented"); 277 reply = st.error_reply(stanza, "cancel", "item-not-found");
288 end 278 end
289 return origin.send(reply); 279 elseif action.name == "adminfor" then
290 end); 280 local data = st.stanza("adminfor");
291 281 for host_name in pairs(hosts) do
292 host_table.events.add_handler("resource-bind", function(event) 282 if is_admin(stanza.attr.from, host_name) then
293 add_client(event.session, host_name); 283 data:tag("item"):text(host_name):up();
294 end); 284 end
295 285 end
296 host_table.events.add_handler("resource-unbind", function(event) 286 reply = st.reply(stanza)
297 del_client(event.session, host_name); 287 :tag("adminsub", { xmlns = xmlns_adminsub })
298 service[host_name]:remove_subscription(xmlns_c2s_session, host_name, event.session.full_jid); 288 :add_child(data);
299 service[host_name]:remove_subscription(xmlns_s2s_session, host_name, event.session.full_jid); 289 else
300 end); 290 reply = st.error_reply(stanza, "feature-not-implemented");
301 291 end
302 host_table.events.add_handler("s2sout-established", function(event) 292 return origin.send(reply);
303 add_host(event.session, "out", host_name); 293 end);
304 end); 294
305 295 -- Add/remove c2s sessions
306 host_table.events.add_handler("s2sin-established", function(event) 296 module:hook("resource-bind", function(event)
307 add_host(event.session, "in", host_name); 297 add_client(event.session, module.host);
308 end); 298 end);
309 299
310 host_table.events.add_handler("s2sout-destroyed", function(event) 300 module:hook("resource-unbind", function(event)
311 del_host(event.session, "out", host_name); 301 del_client(event.session, module.host);
312 end); 302 service[module.host]:remove_subscription(xmlns_c2s_session, module.host, event.session.full_jid);
313 303 service[module.host]:remove_subscription(xmlns_s2s_session, module.host, event.session.full_jid);
314 host_table.events.add_handler("s2sin-destroyed", function(event) 304 end);
315 del_host(event.session, "in", host_name); 305
316 end); 306 -- Add/remove s2s sessions
317 307 module:hook("s2sout-established", function(event)
318 end 308 add_host(event.session, "out", module.host);
319 end); 309 end);
310
311 module:hook("s2sin-established", function(event)
312 add_host(event.session, "in", module.host);
313 end);
314
315 module:hook("s2sout-destroyed", function(event)
316 del_host(event.session, "out", module.host);
317 end);
318
319 module:hook("s2sin-destroyed", function(event)
320 del_host(event.session, "in", module.host);
321 end);
322 end
320 323
321 function simple_broadcast(node, jids, item, host) 324 function simple_broadcast(node, jids, item, host)
322 item = st.clone(item); 325 item = st.clone(item);
323 item.attr.xmlns = nil; -- Clear the pubsub namespace 326 item.attr.xmlns = nil; -- Clear the pubsub namespace
324 local message = st.message({ from = host, type = "headline" }) 327 local message = st.message({ from = host, type = "headline" })