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;