Comparison

mod_client_management/mod_client_management.lua @ 5305:9b9f35aaeb91

mod_client_management: Add support for revocation of clients (when possible) We decided to keep the unified listing of "clients", which includes both SASL2 clients and OAuth grants, etc. To a user, or someone wanting to manage what can access their account, they are largely equivalent. To accomplish this technically, we add a prefix to the id to state what type it really is.
author Matthew Wild <mwild1@gmail.com>
date Wed, 05 Apr 2023 19:42:16 +0100
parent 5304:717ff9468464
child 5306:210aeb5afe42
comparison
equal deleted inserted replaced
5304:717ff9468464 5305:9b9f35aaeb91
228 -- Go through known clients, check whether they could possibly log in 228 -- Go through known clients, check whether they could possibly log in
229 for client_id, client in pairs(clients or {}) do --luacheck: ignore 213/client_id 229 for client_id, client in pairs(clients or {}) do --luacheck: ignore 213/client_id
230 local active = is_client_active(client); 230 local active = is_client_active(client);
231 if active then 231 if active then
232 client.type = "session"; 232 client.type = "session";
233 client.id = "client/"..client.id;
233 client.active = active; 234 client.active = active;
234 table.insert(active_clients, client); 235 table.insert(active_clients, client);
235 if active.grant then 236 if active.grant then
236 used_grants[active.grant.id] = true; 237 used_grants[active.grant.id] = true;
237 end 238 end
240 241
241 -- Next, account for any grants that have been issued, but never actually logged in 242 -- Next, account for any grants that have been issued, but never actually logged in
242 for grant_id, grant in pairs(tokenauth.get_user_grants(username) or {}) do 243 for grant_id, grant in pairs(tokenauth.get_user_grants(username) or {}) do
243 if not used_grants[grant_id] then -- exclude grants already accounted for 244 if not used_grants[grant_id] then -- exclude grants already accounted for
244 table.insert(active_clients, { 245 table.insert(active_clients, {
245 id = grant_id; 246 id = "grant/"..grant.id;
246 type = "access"; 247 type = "access";
247 first_seen = grant.created; 248 first_seen = grant.created;
248 last_seen = grant.accessed; 249 last_seen = grant.accessed;
249 active = { 250 active = {
250 grant = grant; 251 grant = grant;
270 end); 271 end);
271 272
272 return active_clients; 273 return active_clients;
273 end 274 end
274 275
276 function revoke_client_access(username, client_selector)
277 if client_selector.id then
278 local c_type, c_id = client_selector.id:match("^(%w+)/(.+)$");
279 if c_type == "client" then
280 local client = client_store:get_key(username, c_id);
281 if not client then
282 return nil, "item-not-found";
283 end
284 local status = is_client_active(client);
285 if status.connected then
286 local ok, err = prosody.full_sessions[client.full_jid]:close();
287 if not ok then return ok, err; end
288 end
289 if status.fast then
290 local ok = mod_fast.revoke_fast_tokens(username, client.id);
291 if not ok then return nil, "internal-server-error"; end
292 end
293 if status.grant then
294 local ok = tokenauth.revoke_grant(username, status.grant.id);
295 if not ok then return nil, "internal-server-error"; end
296 end
297 return true;
298 elseif c_type == "grant" then
299 local grant = tokenauth.get_grant_info(username, c_id);
300 if not grant then
301 return nil, "item-not-found";
302 end
303 local ok = tokenauth.revoke_grant(username, c_id);
304 if not ok then return nil, "internal-server-error"; end
305 return true;
306 end
307 end
308
309 return nil, "item-not-found";
310 end
311
275 -- Protocol 312 -- Protocol
276 313
277 local xmlns_manage_clients = "xmpp:prosody.im/protocol/manage-clients"; 314 local xmlns_manage_clients = "xmpp:prosody.im/protocol/manage-clients";
278 315
279 module:hook("iq-get/self/xmpp:prosody.im/protocol/manage-clients:list", function (event) 316 module:hook("iq-get/self/xmpp:prosody.im/protocol/manage-clients:list", function (event)