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.
--- 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";