Mercurial > prosody-modules
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 |