changeset 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
parents 717ff9468464
children 210aeb5afe42
files mod_client_management/mod_client_management.lua
diffstat 1 files changed, 38 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/mod_client_management/mod_client_management.lua	Wed Apr 05 19:39:53 2023 +0100
+++ b/mod_client_management/mod_client_management.lua	Wed Apr 05 19:42:16 2023 +0100
@@ -230,6 +230,7 @@
 		local active = is_client_active(client);
 		if active then
 			client.type = "session";
+			client.id = "client/"..client.id;
 			client.active = active;
 			table.insert(active_clients, client);
 			if active.grant then
@@ -242,7 +243,7 @@
 	for grant_id, grant in pairs(tokenauth.get_user_grants(username) or {}) do
 		if not used_grants[grant_id] then -- exclude grants already accounted for
 			table.insert(active_clients, {
-				id = grant_id;
+				id = "grant/"..grant.id;
 				type = "access";
 				first_seen = grant.created;
 				last_seen = grant.accessed;
@@ -272,6 +273,42 @@
 	return active_clients;
 end
 
+function revoke_client_access(username, client_selector)
+	if client_selector.id then
+		local c_type, c_id = client_selector.id:match("^(%w+)/(.+)$");
+		if c_type == "client" then
+			local client = client_store:get_key(username, c_id);
+			if not client then
+				return nil, "item-not-found";
+			end
+			local status = is_client_active(client);
+			if status.connected then
+				local ok, err = prosody.full_sessions[client.full_jid]:close();
+				if not ok then return ok, err; end
+			end
+			if status.fast then
+				local ok = mod_fast.revoke_fast_tokens(username, client.id);
+				if not ok then return nil, "internal-server-error"; end
+			end
+			if status.grant then
+				local ok = tokenauth.revoke_grant(username, status.grant.id);
+				if not ok then return nil, "internal-server-error"; end
+			end
+			return true;
+		elseif c_type == "grant" then
+			local grant = tokenauth.get_grant_info(username, c_id);
+			if not grant then
+				return nil, "item-not-found";
+			end
+			local ok = tokenauth.revoke_grant(username, c_id);
+			if not ok then return nil, "internal-server-error"; end
+			return true;
+		end
+	end
+
+	return nil, "item-not-found";
+end
+
 -- Protocol
 
 local xmlns_manage_clients = "xmpp:prosody.im/protocol/manage-clients";