comparison mod_adhoc_cmd_admin/mod_adhoc_cmd_admin.lua @ 121:a9898f13c89e

mod_adhoc: Major refactoring. Actuall data exchange happens here now mod_adhoc_cmd_*: Update to work with aforementioned change
author Florian Zeitz <florob@babelmonkeys.de>
date Fri, 22 Jan 2010 04:25:58 +0100
parents e02281edc273
children c04443ea114c
comparison
equal deleted inserted replaced
120:7a2d33e8ad1f 121:a9898f13c89e
16 local usermanager_create_user = require "core.usermanager".create_user; 16 local usermanager_create_user = require "core.usermanager".create_user;
17 local is_admin = require "core.usermanager".is_admin; 17 local is_admin = require "core.usermanager".is_admin;
18 18
19 local st, jid, uuid = require "util.stanza", require "util.jid", require "util.uuid"; 19 local st, jid, uuid = require "util.stanza", require "util.jid", require "util.uuid";
20 local dataforms_new = require "util.dataforms".new; 20 local dataforms_new = require "util.dataforms".new;
21 module:log("debug", module:get_name());
21 local adhoc_new = module:require "adhoc".new; 22 local adhoc_new = module:require "adhoc".new;
22 23
23 local sessions = {}; 24 local sessions = {};
24 25
25 local add_user_layout = dataforms_new{ 26 local add_user_layout = dataforms_new{
73 { name = "FORM_TYPE", type = "hidden", value = "http://jabber.org/protocol/admin" }; 74 { name = "FORM_TYPE", type = "hidden", value = "http://jabber.org/protocol/admin" };
74 { name = "subject", type = "text-single", label = "Subject" }; 75 { name = "subject", type = "text-single", label = "Subject" };
75 { name = "announcement", type = "text-multi", required = true, label = "Announcement" }; 76 { name = "announcement", type = "text-multi", required = true, label = "Announcement" };
76 }; 77 };
77 78
78 function add_user_command_handler(item, origin, stanza) 79 function add_user_command_handler(self, data, sessid)
79 if stanza.tags[1].attr.sessionid and sessions[stanza.tags[1].attr.sessionid] then 80 if sessid and sessions[sessid] then
80 if stanza.tags[1].attr.action == "cancel" then 81 if data.action == "cancel" then
81 origin.send(st.reply(stanza):add_child(item:cmdtag("canceled", stanza.tags[1].attr.sessionid))); 82 sessions[sessid] = nil;
82 sessions[stanza.tags[1].attr.sessionid] = nil; 83 return { status = "canceled" }, sessid;
83 return true; 84 end
84 end 85 local fields = add_user_layout:data(data.form);
85 local form = stanza.tags[1]:child_with_ns("jabber:x:data");
86 local fields = add_user_layout:data(form);
87 local username, host, resource = jid.split(fields.accountjid); 86 local username, host, resource = jid.split(fields.accountjid);
88 if (fields["password"] == fields["password-verify"]) and username and host and host == stanza.attr.to then 87 if (fields["password"] == fields["password-verify"]) and username and host and host == data.to then
89 if usermanager_user_exists(username, host) then 88 if usermanager_user_exists(username, host) then
90 origin.send(st.error_reply(stanza, "cancel", "conflict", "Account already exists"):up() 89 sessions[sessid] = nil;
91 :add_child(item:cmdtag("canceled", stanza.tags[1].attr.sessionid) 90 return { status = "error", error = { type = "cancel", condition = "conflict", message = "Account already exists" } }, sessid;
92 :tag("note", {type="error"}):text("Account already exists")));
93 sessions[stanza.tags[1].attr.sessionid] = nil;
94 return true;
95 else 91 else
96 if usermanager_create_user(username, fields.password, host) then 92 if usermanager_create_user(username, fields.password, host) then
97 origin.send(st.reply(stanza):add_child(item:cmdtag("completed", stanza.tags[1].attr.sessionid) 93 sessions[sessid] = nil;
98 :tag("note", {type="info"}):text("Account successfully created"))); 94 module:log("info", "Created new account " .. username.."@"..host);
99 sessions[stanza.tags[1].attr.sessionid] = nil; 95 return { status = "completed", info = "Account successfully created" }, sessid;
100 module:log("debug", "Created new account " .. username.."@"..host);
101 return true;
102 else 96 else
103 origin.send(st.error_reply(stanza, "wait", "internal-server-error", 97 sessions[sessid] = nil;
104 "Failed to write data to disk"):up() 98 return { status = "error", error = { type = "wait", condition = "internal-server-error",
105 :add_child(item:cmdtag("canceled", stanza.tags[1].attr.sessionid) 99 message = "Failed to write data to disk" } }, sessid;
106 :tag("note", {type="error"}):text("Failed to write data to disk")));
107 sessions[stanza.tags[1].attr.sessionid] = nil;
108 return true;
109 end 100 end
110 end 101 end
111 else 102 else
112 module:log("debug", fields.accountjid .. " " .. fields.password .. " " .. fields["password-verify"]); 103 module:log("debug", fields.accountjid .. " " .. fields.password .. " " .. fields["password-verify"]);
113 origin.send(st.error_reply(stanza, "cancel", "conflict", 104 sessions[sessid] = nil;
114 "Invalid data.\nPassword mismatch, or empty username"):up() 105 return { status = "error", error = { type = "cancel", condition = "conflict",
115 :add_child(item:cmdtag("canceled", stanza.tags[1].attr.sessionid) 106 message = "Invalid data.\nPassword mismatch, or empty username" } }, sessid;
116 :tag("note", {type="error"}):text("Invalid data.\nPassword mismatch, or empty username"))); 107 end
117 sessions[stanza.tags[1].attr.sessionid] = nil; 108 else
118 return true; 109 local sessionid=uuid.generate();
119 end 110 sessions[sessionid] = "executing";
120 else 111 return { status = "executing", form = add_user_layout }, sessionid;
121 local sessionid=uuid.generate(); 112 end
122 sessions[sessionid] = "executing"; 113 end
123 origin.send(st.reply(stanza):add_child(item:cmdtag("executing", sessionid):add_child(add_user_layout:form()))); 114
124 end 115 function change_user_password_command_handler(self, data, sessid)
125 return true; 116 if sessid and sessions[sessid] then
126 end 117 if data.action == "cancel" then
127 118 sessions[sessid] = nil;
128 function change_user_password_command_handler(item, origin, stanza) 119 return { status = "canceled" }, sessid;
129 if stanza.tags[1].attr.sessionid and sessions[stanza.tags[1].attr.sessionid] then 120 end
130 if stanza.tags[1].attr.action == "cancel" then 121 local fields = change_user_password_layout:data(data.form);
131 origin.send(st.reply(stanza):add_child(item:cmdtag("canceled", stanza.tags[1].attr.sessionid)));
132 sessions[stanza.tags[1].attr.sessionid] = nil;
133 return true;
134 end
135 local form = stanza.tags[1]:child_with_ns("jabber:x:data");
136 local fields = change_user_password_layout:data(form);
137 local username, host, resource = jid.split(fields.accountjid); 122 local username, host, resource = jid.split(fields.accountjid);
138 if usermanager_user_exists(username, host) and usermanager_create_user(username, fields.password, host) then 123 if usermanager_user_exists(username, host) and usermanager_create_user(username, fields.password, host) then
139 origin.send(st.reply(stanza):add_child(item:cmdtag("completed", stanza.tags[1].attr.sessionid) 124 return { status = "completed", info = "Password successfully changed" }, sessid;
140 :tag("note", {type="info"})
141 :text("Password successfully changed")));
142 else 125 else
143 origin.send(st.error_reply(stanza, "cancel", "item-not-found", "User does not exist") 126 sessions[sessid] = nil;
144 :add_child(item:cmdtag("canceled", stanza.tags[1].attr.sessionid) 127 return { status = "error", error = { type = "cancel", condition = "item-not-found", message = "User does not exist" } }, sessid;
145 :tag("note", {type="error"}):text("User does not exist"))); 128 end
146 end 129 sessions[sessid] = nil;
147 sessions[stanza.tags[1].attr.sessionid] = nil; 130 return { status = "canceled" }, sessid;
148 return true; 131 else
149 else 132 local sessionid=uuid.generate();
150 local sessionid=uuid.generate(); 133 sessions[sessionid] = "executing";
151 sessions[sessionid] = "executing"; 134 return { status = "executing", form = change_user_password_layout }, sessionid;
152 origin.send(st.reply(stanza):add_child(item:cmdtag("executing", sessionid):add_child(change_user_password_layout:form()))); 135 end
153 end 136 end
154 return true; 137
155 end 138 function delete_user_command_handler(self, data, sessid)
156 139 if sessid and sessions[sessid] then
157 function delete_user_command_handler(item, origin, stanza) 140 if data.action == "cancel" then
158 if stanza.tags[1].attr.sessionid and sessions[stanza.tags[1].attr.sessionid] then 141 sessions[sessid] = nil;
159 if stanza.tags[1].attr.action == "cancel" then 142 return { status = "canceled" }, sessid;
160 origin.send(st.reply(stanza):add_child(item:cmdtag("canceled", stanza.tags[1].attr.sessionid))); 143 end
161 sessions[stanza.tags[1].attr.sessionid] = nil; 144 local fields = delete_user_layout:data(data.form);
162 return true;
163 end
164 local form = stanza.tags[1]:child_with_ns("jabber:x:data");
165 local fields = delete_user_layout:data(form);
166 local failed = {}; 145 local failed = {};
167 local succeeded = {}; 146 local succeeded = {};
168 for _, aJID in ipairs(fields.accountjids) do 147 for _, aJID in ipairs(fields.accountjids) do
169 local username, host, resource = jid.split(aJID); 148 local username, host, resource = jid.split(aJID);
170 if usermanager_user_exists(username, host) and usermanager_create_user(username, nil, host) then 149 if usermanager_user_exists(username, host) and usermanager_create_user(username, nil, host) then
171 module:log("debug", "User" .. aJID .. "has been deleted"); 150 module:log("debug", "User " .. aJID .. " has been deleted");
172 succeeded[#succeeded+1] = aJID; 151 succeeded[#succeeded+1] = aJID;
173 else 152 else
174 module:log("debug", "Tried to delete not existing user "..aJID); 153 module:log("debug", "Tried to delete non-existant user "..aJID);
175 failed[#failed+1] = aJID; 154 failed[#failed+1] = aJID;
176 end 155 end
177 end 156 end
178 origin.send(st.reply(stanza):add_child(item:cmdtag("completed", stanza.tags[1].attr.sessionid) 157 sessions[sessid] = nil;
179 :tag("note", {type="info"}) 158 return {status = "completed", info = (#succeeded ~= 0 and
180 :text((#succeeded ~= 0 and "The following accounts were successfully deleted:\n"..t_concat(succeeded, "\n").."\n" or "") 159 "The following accounts were successfully deleted:\n"..t_concat(succeeded, "\n").."\n" or "")..
181 ..(#failed ~= 0 and "The following accounts could not be deleted:\n"..t_concat(failed, "\n") or "")))); 160 (#failed ~= 0 and
182 sessions[stanza.tags[1].attr.sessionid] = nil; 161 "The following accounts could not be deleted:\n"..t_concat(failed, "\n") or "") }, sessid;
183 return true; 162 else
184 else 163 local sessionid=uuid.generate();
185 local sessionid=uuid.generate(); 164 sessions[sessionid] = "executing";
186 sessions[sessionid] = "executing"; 165 return { status = "executing", form = delete_user_layout }, sessionid;
187 origin.send(st.reply(stanza):add_child(item:cmdtag("executing", sessionid):add_child(delete_user_layout:form()))); 166 end
188 end 167 end
189 return true; 168
190 end 169 function get_user_password_handler(self, data, sessid)
191 170 if sessid and sessions[sessid] then
192 function get_user_password_handler(item, origin, stanza) 171 if data.action == "cancel" then
193 if stanza.tags[1].attr.sessionid and sessions[stanza.tags[1].attr.sessionid] then 172 sessions[sessid] = nil;
194 if stanza.tags[1].attr.action == "cancel" then 173 return { status = "canceled" }, sessid;
195 origin.send(st.reply(stanza):add_child(item:cmdtag("canceled", stanza.tags[1].attr.sessionid))); 174 end
196 sessions[stanza.tags[1].attr.sessionid] = nil; 175 local fields = get_user_password_layout:data(data.form);
197 return true;
198 end
199 local form = stanza.tags[1]:child_with_ns("jabber:x:data");
200 local fields = get_user_password_layout:data(form);
201 local accountjid = st.stanza("field", {var="accountjid", label = "JID", type="jid-single"}); 176 local accountjid = st.stanza("field", {var="accountjid", label = "JID", type="jid-single"});
202 local password = st.stanza("field", {var="password", label = "Password", type="text-single"}); 177 local password = st.stanza("field", {var="password", label = "Password", type="text-single"});
203 local user, host, resource = jid.split(fields.accountjid); 178 local user, host, resource = jid.split(fields.accountjid);
204 if usermanager_user_exists(user, host) then 179 if usermanager_user_exists(user, host) then
205 accountjid:tag("value"):text(fields.accountjid):up(); 180 accountjid:tag("value"):text(fields.accountjid):up();
206 password:tag("value"):text(usermanager_get_password(user, host)):up(); 181 password:tag("value"):text(usermanager_get_password(user, host)):up();
207 else 182 else
208 origin.send(st.error_reply(stanza, "cancel", "item-not-found", "User does not exist") 183 sessions[sessid] = nil;
209 :add_child(item:cmdtag("canceled", stanza.tags[1].attr.sessionid) 184 return { status = "error", error = { type = "cancel", condition = "item-not-found", message = "User does not exist" } }, sessid;
210 :tag("note", {type="error"}):text("User does not exist"))); 185 end
211 sessions[stanza.tags[1].attr.sessionid] = nil; 186 sessions[sessid] = nil;
212 return true; 187 return { status = "completed", other = st.stanza("x", {xmlns="jabber:x:data", type="result"})
213 end
214 origin.send(st.reply(stanza):add_child(item:cmdtag("completed", stanza.tags[1].attr.sessionid)
215 :tag("x", {xmlns="jabber:x:data", type="result"})
216 :tag("field", {type="hidden", var="FORM_TYPE"}) 188 :tag("field", {type="hidden", var="FORM_TYPE"})
217 :tag("value"):text("http://jabber.org/protocol/admin"):up():up() 189 :tag("value"):text("http://jabber.org/protocol/admin"):up():up()
218 :add_child(accountjid) 190 :add_child(accountjid)
219 :add_child(password))); 191 :add_child(password) }, sessid;
220 sessions[stanza.tags[1].attr.sessionid] = nil; 192 else
221 return true; 193 local sessionid=uuid.generate();
222 else 194 sessions[sessionid] = "executing";
223 local sessionid=uuid.generate(); 195 return { status = "executing", form = get_user_password_layout }, sessionid;
224 sessions[sessionid] = "executing"; 196 end
225 origin.send(st.reply(stanza):add_child(item:cmdtag("executing", sessionid):add_child(get_user_password_layout:form()))); 197 end
226 end 198
227 return true; 199 function get_online_users_command_handler(self, data, sessid)
228 end 200 if sessid and sessions[sessid] then
229 201 if data.action == "cancel" then
230 function get_online_users_command_handler(item, origin, stanza) 202 sessions[sessid] = nil;
231 if stanza.tags[1].attr.sessionid and sessions[stanza.tags[1].attr.sessionid] then 203 return { status = "canceled" }, sessid;
232 if stanza.tags[1].attr.action == "cancel" then 204 end
233 origin.send(st.reply(stanza):add_child(item:cmdtag("canceled", stanza.tags[1].attr.sessionid))); 205
234 sessions[stanza.tags[1].attr.sessionid] = nil; 206 local fields = add_user_layout:data(data.form);
235 return true;
236 end
237
238 local form = stanza.tags[1]:child_with_ns("jabber:x:data");
239 local fields = add_user_layout:data(form);
240 207
241 local max_items = nil 208 local max_items = nil
242 if fields.max_items ~= "all" then 209 if fields.max_items ~= "all" then
243 max_items = tonumber(fields.max_items); 210 max_items = tonumber(fields.max_items);
244 end 211 end
245 local count = 0; 212 local count = 0;
246 local field = st.stanza("field", {label="The list of all online users", var="onlineuserjids", type="text-multi"}); 213 local field = st.stanza("field", {label="The list of all online users", var="onlineuserjids", type="text-multi"});
247 for username, user in pairs(hosts[stanza.attr.to].sessions or {}) do 214 for username, user in pairs(hosts[data.to].sessions or {}) do
248 if (max_items ~= nil) and (count >= max_items) then 215 if (max_items ~= nil) and (count >= max_items) then
249 break; 216 break;
250 end 217 end
251 field:tag("value"):text(username.."@"..stanza.attr.to):up(); 218 field:tag("value"):text(username.."@"..data.to):up();
252 count = count + 1; 219 count = count + 1;
253 end 220 end
254 origin.send(st.reply(stanza):add_child(item:cmdtag("completed", stanza.tags[1].attr.sessionid) 221 sessions[sessid] = nil;
255 :tag("x", {xmlns="jabber:x:data", type="result"}) 222 return { status = "completed", other = st.stanza("x", {xmlns="jabber:x:data", type="result"})
256 :tag("field", {type="hidden", var="FORM_TYPE"}) 223 :tag("field", {type="hidden", var="FORM_TYPE"})
257 :tag("value"):text("http://jabber.org/protocol/admin"):up():up() 224 :tag("value"):text("http://jabber.org/protocol/admin"):up():up()
258 :add_child(field))); 225 :add_child(field) }, sessid;
259 sessions[stanza.tags[1].attr.sessionid] = nil; 226 else
260 return true; 227 local sessionid=uuid.generate();
261 else 228 sessions[sessionid] = "executing";
262 local sessionid=uuid.generate(); 229 return { status = "executing", form = get_online_users_layout }, sessionid;
263 sessions[sessionid] = "executing"; 230 end
264 origin.send(st.reply(stanza):add_child(item:cmdtag("executing", sessionid):add_child(get_online_users_layout:form()))); 231 end
265 end 232
266 233 function announce_handler(self, data, sessid)
267 return true; 234 if sessid and sessions[sessid] then
268 end 235 if data.action == "cancel" then
269 236 sessions[sessid] = nil;
270 function announce_handler(item, origin, stanza) 237 return { status = "canceled" }, sessid;
271 if stanza.tags[1].attr.sessionid and sessions[stanza.tags[1].attr.sessionid] then 238 end
272 if stanza.tags[1].attr.action == "cancel" then 239
273 origin.send(st.reply(stanza):add_child(item:cmdtag("canceled", stanza.tags[1].attr.sessionid))); 240 local fields = announce_layout:data(data.form);
274 sessions[stanza.tags[1].attr.sessionid] = nil;
275 return true;
276 end
277
278 local form = stanza.tags[1]:child_with_ns("jabber:x:data");
279 local fields = add_user_layout:data(form);
280 241
281 module:log("info", "Sending server announcement to all online users"); 242 module:log("info", "Sending server announcement to all online users");
282 local host_session = hosts[stanza.attr.to]; 243 local host_session = hosts[data.to];
283 local message = st.message({type = "headline", from = stanza.attr.to}, fields.announcement):up() 244 local message = st.message({type = "headline", from = data.to}, fields.announcement):up()
284 :tag("subject"):text(fields.subject or "Announcement"); 245 :tag("subject"):text(fields.subject or "Announcement");
285 246
286 local c = 0; 247 local c = 0;
287 for user in pairs(host_session.sessions) do 248 for user in pairs(host_session.sessions) do
288 c = c + 1; 249 c = c + 1;
289 message.attr.to = user.."@"..stanza.attr.to; 250 message.attr.to = user.."@"..data.to;
290 core_post_stanza(host_session, message); 251 core_post_stanza(host_session, message);
291 end 252 end
292 253
293 module:log("info", "Announcement sent to %d online users", c); 254 module:log("info", "Announcement sent to %d online users", c);
294 255 sessions[sessid] = nil;
295 origin.send(st.reply(stanza):add_child(item:cmdtag("completed", stanza.tags[1].attr.sessionid) 256 return { status = "completed", info = "Announcement sent." }, sessid;
296 :tag("note"):text("Announcement sent."))); 257 else
297 sessions[stanza.tags[1].attr.sessionid] = nil; 258 local sessionid=uuid.generate();
298 return true; 259 sessions[sessionid] = "executing";
299 else 260 return { status = "executing", form = announce_layout }, sessionid;
300 local sessionid=uuid.generate();
301 sessions[sessionid] = "executing";
302 origin.send(st.reply(stanza):add_child(item:cmdtag("executing", sessionid):add_child(announce_layout:form())));
303 end 261 end
304 262
305 return true; 263 return true;
306 end 264 end
307 265