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 |
