Software / code / prosody
Comparison
plugins/mod_admin_shell.lua @ 13593:f57872788424
mod_admin_shell: Add session method to request (password) input from shell client
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Tue, 07 Jan 2025 18:17:30 +0000 |
| parent | 13591:382d1a92006f |
| child | 13594:abbdcef552fb |
comparison
equal
deleted
inserted
replaced
| 13592:34da8cc10b82 | 13593:f57872788424 |
|---|---|
| 23 local _G = _G; | 23 local _G = _G; |
| 24 | 24 |
| 25 local prosody = _G.prosody; | 25 local prosody = _G.prosody; |
| 26 | 26 |
| 27 local unpack = table.unpack; | 27 local unpack = table.unpack; |
| 28 local cache = require "prosody.util.cache"; | |
| 29 local new_short_id = require "prosody.util.id".short; | |
| 28 local iterators = require "prosody.util.iterators"; | 30 local iterators = require "prosody.util.iterators"; |
| 29 local keys, values = iterators.keys, iterators.values; | 31 local keys, values = iterators.keys, iterators.values; |
| 30 local jid_bare, jid_split, jid_join, jid_resource, jid_compare = import("prosody.util.jid", "bare", "prepped_split", "join", "resource", "compare"); | 32 local jid_bare, jid_split, jid_join, jid_resource, jid_compare = import("prosody.util.jid", "bare", "prepped_split", "join", "resource", "compare"); |
| 31 local set, array = require "prosody.util.set", require "prosody.util.array"; | 33 local set, array = require "prosody.util.set", require "prosody.util.array"; |
| 32 local cert_verify_identity = require "prosody.util.x509".verify_identity; | 34 local cert_verify_identity = require "prosody.util.x509".verify_identity; |
| 168 | 170 |
| 169 local function send_repl_output(session, line, attr) | 171 local function send_repl_output(session, line, attr) |
| 170 return session.send(st.stanza("repl-output", attr):text(tostring(line))); | 172 return session.send(st.stanza("repl-output", attr):text(tostring(line))); |
| 171 end | 173 end |
| 172 | 174 |
| 175 local function request_repl_input(session, input_type) | |
| 176 if input_type ~= "password" then | |
| 177 return promise.reject("internal error - unsupported input type "..tostring(input_type)); | |
| 178 end | |
| 179 local pending_inputs = session.pending_inputs; | |
| 180 if not pending_inputs then | |
| 181 pending_inputs = cache.new(5, function (input_id, input_promise) --luacheck: ignore 212/input_id | |
| 182 input_promise.reject(); | |
| 183 end); | |
| 184 session.pending_inputs = pending_inputs; | |
| 185 end | |
| 186 | |
| 187 local input_id = new_short_id(); | |
| 188 local p = promise.new(function (resolve, reject) | |
| 189 pending_inputs:set(input_id, { resolve = resolve, reject = reject }); | |
| 190 end):finally(function () | |
| 191 pending_inputs:set(input_id, nil); | |
| 192 end); | |
| 193 session.send(st.stanza("repl-request-input", { type = input_type, id = input_id })); | |
| 194 module:log("warn", "REQUESTED INPUT %s", input_type); | |
| 195 return p; | |
| 196 end | |
| 197 | |
| 198 module:hook("admin-disconnected", function (event) | |
| 199 local pending_inputs = event.session.pending_inputs; | |
| 200 if not pending_inputs then return; end | |
| 201 for input_promise in pending_inputs:values() do | |
| 202 input_promise.reject(); | |
| 203 end | |
| 204 end); | |
| 205 | |
| 206 module:hook("admin/repl-requested-input", function (event) | |
| 207 local input_id = event.stanza.attr.id; | |
| 208 local input_promise = event.origin.pending_inputs:get(input_id); | |
| 209 if not input_promise then | |
| 210 event.origin.send(st.stanza("repl-result", { type = "error" }):text("Internal error - unexpected input")); | |
| 211 return true; | |
| 212 end | |
| 213 input_promise.resolve(event.stanza:get_text()); | |
| 214 end); | |
| 215 | |
| 173 function console:new_session(admin_session) | 216 function console:new_session(admin_session) |
| 174 local session = { | 217 local session = { |
| 175 send = function (t) | 218 send = function (t) |
| 176 return send_repl_output(admin_session, t); | 219 return send_repl_output(admin_session, t); |
| 177 end; | 220 end; |
| 182 end | 225 end |
| 183 return send_repl_output(admin_session, table.concat(t, "\t")); | 226 return send_repl_output(admin_session, table.concat(t, "\t")); |
| 184 end; | 227 end; |
| 185 write = function (t) | 228 write = function (t) |
| 186 return send_repl_output(admin_session, t, { eol = "0" }); | 229 return send_repl_output(admin_session, t, { eol = "0" }); |
| 230 end; | |
| 231 request_input = function (input_type) | |
| 232 return request_repl_input(admin_session, input_type); | |
| 187 end; | 233 end; |
| 188 serialize = tostring; | 234 serialize = tostring; |
| 189 disconnect = function () admin_session:close(); end; | 235 disconnect = function () admin_session:close(); end; |
| 190 is_connected = function () | 236 is_connected = function () |
| 191 return not not admin_session.conn; | 237 return not not admin_session.conn; |