diff options
author | Matthew Wild <mwild1@gmail.com> | 2025-01-07 18:17:30 +0000 |
---|---|---|
committer | Matthew Wild <mwild1@gmail.com> | 2025-01-07 18:17:30 +0000 |
commit | 7a9bc06049b4582294c16e2b4ceb7148abae188e (patch) | |
tree | b018810883c465cdbc0f844312cdba6321ec58cc /plugins | |
parent | 72b6c110f0c695f5fcaaab2edfa6ad9db37b1f09 (diff) | |
download | prosody-7a9bc06049b4582294c16e2b4ceb7148abae188e.tar.gz prosody-7a9bc06049b4582294c16e2b4ceb7148abae188e.zip |
mod_admin_shell: Add session method to request (password) input from shell client
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/mod_admin_shell.lua | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/plugins/mod_admin_shell.lua b/plugins/mod_admin_shell.lua index 131bd070..46c7494d 100644 --- a/plugins/mod_admin_shell.lua +++ b/plugins/mod_admin_shell.lua @@ -25,6 +25,8 @@ local _G = _G; local prosody = _G.prosody; local unpack = table.unpack; +local cache = require "prosody.util.cache"; +local new_short_id = require "prosody.util.id".short; local iterators = require "prosody.util.iterators"; local keys, values = iterators.keys, iterators.values; local jid_bare, jid_split, jid_join, jid_resource, jid_compare = import("prosody.util.jid", "bare", "prepped_split", "join", "resource", "compare"); @@ -170,6 +172,47 @@ local function send_repl_output(session, line, attr) return session.send(st.stanza("repl-output", attr):text(tostring(line))); end +local function request_repl_input(session, input_type) + if input_type ~= "password" then + return promise.reject("internal error - unsupported input type "..tostring(input_type)); + end + local pending_inputs = session.pending_inputs; + if not pending_inputs then + pending_inputs = cache.new(5, function (input_id, input_promise) --luacheck: ignore 212/input_id + input_promise.reject(); + end); + session.pending_inputs = pending_inputs; + end + + local input_id = new_short_id(); + local p = promise.new(function (resolve, reject) + pending_inputs:set(input_id, { resolve = resolve, reject = reject }); + end):finally(function () + pending_inputs:set(input_id, nil); + end); + session.send(st.stanza("repl-request-input", { type = input_type, id = input_id })); + module:log("warn", "REQUESTED INPUT %s", input_type); + return p; +end + +module:hook("admin-disconnected", function (event) + local pending_inputs = event.session.pending_inputs; + if not pending_inputs then return; end + for input_promise in pending_inputs:values() do + input_promise.reject(); + end +end); + +module:hook("admin/repl-requested-input", function (event) + local input_id = event.stanza.attr.id; + local input_promise = event.origin.pending_inputs:get(input_id); + if not input_promise then + event.origin.send(st.stanza("repl-result", { type = "error" }):text("Internal error - unexpected input")); + return true; + end + input_promise.resolve(event.stanza:get_text()); +end); + function console:new_session(admin_session) local session = { send = function (t) @@ -185,6 +228,9 @@ function console:new_session(admin_session) write = function (t) return send_repl_output(admin_session, t, { eol = "0" }); end; + request_input = function (input_type) + return request_repl_input(admin_session, input_type); + end; serialize = tostring; disconnect = function () admin_session:close(); end; is_connected = function () |