Comparison

mod_http_admin_api/mod_http_admin_api.lua @ 4363:636d56bbad97

mod_http_admin_api: 100% untested user debug info endpoint
author Matthew Wild <mwild1@gmail.com>
date Thu, 21 Jan 2021 14:42:11 +0000
parent 4362:116c88c28532
child 4364:49cf9d188b26
comparison
equal deleted inserted replaced
4362:116c88c28532 4363:636d56bbad97
8 local tokens = module:depends("tokenauth"); 8 local tokens = module:depends("tokenauth");
9 local mod_pep = module:depends("pep"); 9 local mod_pep = module:depends("pep");
10 10
11 local group_store = module:open_store("groups"); 11 local group_store = module:open_store("groups");
12 local group_memberships = module:open_store("groups", "map"); 12 local group_memberships = module:open_store("groups", "map");
13 local push_errors = module:shared("cloud_notify/push_errors");
13 14
14 local json_content_type = "application/json"; 15 local json_content_type = "application/json";
15 16
16 local www_authenticate_header = ("Bearer realm=%q"):format(module.host.."/"..module.name); 17 local www_authenticate_header = ("Bearer realm=%q"):format(module.host.."/"..module.name);
17 18
159 username = username; 160 username = username;
160 display_name = display_name; 161 display_name = display_name;
161 }; 162 };
162 end 163 end
163 164
165 local function get_session_debug_info(session)
166 local info = {
167 full_jid = session.full_jid;
168 ip = session.ip;
169 since = math.floor(session.conntime);
170 status = {
171 connected = not not session.conn;
172 hibernating = not not session.hibernating;
173 };
174 features = {
175 carbons = not not session.want_carbons;
176 encrypted = not not session.secure;
177 acks = not not session.smacks;
178 resumption = not not session.resumption_token;
179 mobile_optimization = not not session.csi_counter;
180 push_notifications = not not session.push_identifier;
181 history = not not session.mam_requested;
182 };
183 queues = {};
184 };
185 -- CSI
186 if session.state then
187 info.status.active = session.state == "active";
188 info.queues.held_stanzas = session.csi_counter or 0;
189 end
190 -- Smacks queue
191 if session.last_requested_h and session.last_acknowledged_stanza then
192 info.queues.awaiting_acks = session.last_requested_h - session.last_acknowledged_stanza;
193 end
194 if session.push_identifier then
195 info.push_info = {
196 id = session.push_identifier;
197 wakeup_push_sent = session.first_hibernated_push;
198 };
199 end
200 return info;
201 end
202
203 local function get_user_omemo_info(username)
204 local everything_valid = true;
205 local omemo_status = {};
206 local omemo_devices;
207 local pep_service = mod_pep.get_pep_service(username);
208 if pep_service and pep_service.nodes then
209 local ok, _, device_list = pep_service:get_last_item("eu.siacs.conversations.axolotl.devicelist", true);
210 if ok and device_list then
211 device_list = device_list:get_child("list", "eu.siacs.conversations.axolotl");
212 end
213 if device_list then
214 omemo_devices = {};
215 for device_entry in device_list:childtags("device") do
216 local device_info = {};
217 local device_id = tonumber(device_entry.attr.id or "");
218 if device_id then
219 device_info.id = device_id;
220 local bundle_id = ("eu.siacs.conversations.axolotl.bundles:%d"):format(device_id);
221 local have_bundle, _, bundle = pep_service:get_last_item(bundle_id, true);
222 if have_bundle and bundle and bundle:get_child("bundle", "eu.siacs.conversations.axolotl") then
223 device_info.have_bundle = true;
224 local config_ok, bundle_config = pep_service:get_node_config(bundle_id, true);
225 if config_ok and bundle_config then
226 device_info.bundle_config = bundle_config;
227 if bundle_config.max_items == 1
228 and bundle_config.access_model == "open"
229 and bundle_config.persist_items == true
230 and bundle_config.publish_model == "publishers" then
231 device_info.valid = true;
232 end
233 end
234 end
235 end
236 if device_info.valid == nil then
237 device_info.valid = false;
238 everything_valid = false;
239 end
240 table.insert(omemo_devices, device_info);
241 end
242
243 local config_ok, list_config = pep_service:get_node_config("eu.siacs.conversations.axolotl.devicelist", true);
244 if config_ok and list_config then
245 omemo_status.config = list_config;
246 if list_config.max_items == 1
247 and list_config.access_model == "open"
248 and list_config.persist_items == true
249 and list_config.publish_model == "publishers" then
250 omemo_status.config_valid = true;
251 end
252 end
253 if omemo_status.config_valid == nil then
254 omemo_status.config_valid = false;
255 everything_valid = false;
256 end
257 end
258 end
259 omemo_status.valid = everything_valid;
260 return {
261 status = omemo_status;
262 devices = omemo_devices;
263 };
264 end
265
266 local function get_user_debug_info(username)
267 local debug_info = {
268 time = os.time();
269 };
270 -- Online sessions
271 do
272 local user_sessions = hosts[module.host].sessions[username];
273 local sessions = {};
274 if user_sessions then
275 for _, session in pairs(user_sessions) do
276 table.insert(sessions, get_session_debug_info(session));
277 end
278 end
279 debug_info.sessions = sessions;
280 end
281 -- Push registrations
282 do
283 local store = module:open_store("cloud_notify");
284 local services = store:get(username);
285 local push_registrations = {};
286 if services then
287 for identifier, push_info in pairs(services) do
288 push_registrations[identifier] = {
289 since = push_info.timestamp;
290 service = push_info.jid;
291 node = push_info.node;
292 error_count = push_errors[identifier] or 0;
293 };
294 end
295 end
296 debug_info.push_registrations = push_registrations;
297 end
298 -- OMEMO
299 debug_info.omemo = get_user_omemo_info(username);
300
301 return debug_info;
302 end
303
164 local function get_user_groups(username) 304 local function get_user_groups(username)
165 local groups; 305 local groups;
166 do 306 do
167 local group_set = group_memberships:get_all(username); 307 local group_set = group_memberships:get_all(username);
168 if group_set and next(group_set) then 308 if group_set and next(group_set) then
195 end 335 end
196 end 336 end
197 337
198 if property == "groups" then 338 if property == "groups" then
199 return json.encode(get_user_groups(username)); 339 return json.encode(get_user_groups(username));
340 elseif property == "debug" then
341 return json.encode(get_user_debug_info(username));
200 end 342 end
201 343
202 local user_info = get_user_info(username); 344 local user_info = get_user_info(username);
203 if not user_info then 345 if not user_info then
204 return 404; 346 return 404;