mod_mix_pam: LuaCheck the module

This commit is contained in:
PapaTutuWawa 2021-02-20 20:55:07 +01:00
parent cd68dfa583
commit c251502799

View File

@ -1,6 +1,6 @@
local host = module:get_host() local module_host = module:get_host();
--[[ --[[
if host ~= "*" then if module_host ~= "*" then
module:log("error", "mix_pam should be used on the user host!"); module:log("error", "mix_pam should be used on the user host!");
end end
]]-- ]]--
@ -26,13 +26,13 @@ module:add_feature(mix_pam_xmlns);
-- NOTE: To show that we archive messages -- NOTE: To show that we archive messages
-- module:add_feature(mix_pam_xmlns.."#archive"); -- module:add_feature(mix_pam_xmlns.."#archive");
function contains_key(table, key) local function contains_key(table, key)
-- Returns true if table contains the key key. Returns false -- Returns true if table contains the key key. Returns false
-- otherwise. -- otherwise.
return table[key] ~= nil; return table[key] ~= nil;
end end
function set_mix_spid(user, channel, spid) local function set_mix_spid(user, channel, spid)
if mix_spids[user] ~= nil then if mix_spids[user] ~= nil then
mix_spids[user][channel] = spid; mix_spids[user][channel] = spid;
else else
@ -41,10 +41,10 @@ function set_mix_spid(user, channel, spid)
mix_pam:set("spids", mix_spids); mix_pam:set("spids", mix_spids);
end end
function get_mix_spid(user, channel) local function get_mix_spid(user, channel)
return mix_spids[user][channel]; return mix_spids[user][channel];
end; end;
function remove_mix_spid(user, channel) local function remove_mix_spid(user, channel)
mix_spids[user][channel] = nil; mix_spids[user][channel] = nil;
if mix_spids[user][channel] == {} then if mix_spids[user][channel] == {} then
mix_spids[user][channel] = nil; mix_spids[user][channel] = nil;
@ -53,7 +53,7 @@ function remove_mix_spid(user, channel)
mix_pam:set("spids", mix_spids); mix_pam:set("spids", mix_spids);
end end
function add_mix_host(host) local function add_mix_host(host)
if mix_hosts[host] ~= nil then if mix_hosts[host] ~= nil then
mix_hosts[host] = mix_hosts[host] + 1; mix_hosts[host] = mix_hosts[host] + 1;
module:log("debug", "Known MIX host has a new user"); module:log("debug", "Known MIX host has a new user");
@ -64,8 +64,7 @@ function add_mix_host(host)
mix_pam:set("hosts", mix_hosts); mix_pam:set("hosts", mix_hosts);
end end
local function remove_mix_host(host)
function remove_mix_host(host)
if mix_hosts[host] ~= nil then if mix_hosts[host] ~= nil then
local count = mix_hosts[host]; local count = mix_hosts[host];
if count == 1 then if count == 1 then
@ -81,12 +80,11 @@ function remove_mix_host(host)
mix_pam:set("hosts", mix_hosts); mix_pam:set("hosts", mix_hosts);
end end
local function is_mix_host(host)
function is_mix_host(host)
return mix_hosts[host] ~= nil; return mix_hosts[host] ~= nil;
end end
function is_mix_message(stanza) local function is_mix_message(stanza)
return stanza:get_child("mix", "urn:xmpp:mix:core:1") ~= nil; return stanza:get_child("mix", "urn:xmpp:mix:core:1") ~= nil;
end end
@ -122,14 +120,14 @@ function module.load()
end end
local client_state_tracker = {}; -- [stanza ID] -> resource local client_state_tracker = {}; -- [stanza ID] -> resource
function add_state(id, resource) local function add_state(id, resource)
client_state_tracker[id] = resource; client_state_tracker[id] = resource;
module:log("debug", "Adding a resource %s for id %s", resource, id); module:log("debug", "Adding a resource %s for id %s", resource, id);
end end
function has_state(id) local function has_state(id)
return client_state_tracker[id] ~= nil; return client_state_tracker[id] ~= nil;
end end
function pop_state(id) local function pop_state(id)
module:log("debug", "Popping a resource for stanza id %s", id); module:log("debug", "Popping a resource for stanza id %s", id);
if has_state(id) then if has_state(id) then
@ -141,22 +139,11 @@ function pop_state(id)
return nil; return nil;
end end
module:hook("iq/self", function(event) local function handle_client_join(event)
local stanza = event.stanza;
if #stanza.tags == 0 then return; end
if stanza:get_child("client-join", mix_pam_xmlns) ~= nil then
return handle_client_join(event);
elseif stanza:get_child("client-leave", mix_pam_xmlns) ~= nil then
return handle_client_leave(event);
end
end);
function handle_client_join(event)
-- Client requests to join -- Client requests to join
module:log("debug", "client-join received"); module:log("debug", "client-join received");
local stanza, origin = event.stanza, event.origin; local stanza, origin = event.stanza, event.origin;
local from, to = jid.bare(stanza.attr.from), jid.bare(stanza.attr.to); local from = jid.bare(stanza.attr.from);
local client_join = stanza:get_child("client-join", mix_pam_xmlns); local client_join = stanza:get_child("client-join", mix_pam_xmlns);
if client_join.attr.channel == nil then if client_join.attr.channel == nil then
@ -170,7 +157,12 @@ function handle_client_join(event)
end end
-- Transform the client-join into a join -- Transform the client-join into a join
local join_iq = st.iq({ type = "set", from = jid.bare(stanza.attr.from), to = client_join.attr.channel, id = stanza.attr.id, xmlns = "jabber:client" }); local join_iq = st.iq({
type = "set";
from = jid.bare(stanza.attr.from);
to = client_join.attr.channel;
id = stanza.attr.id, xmlns = "jabber:client"
});
join_iq:add_child(join); join_iq:add_child(join);
add_state(stanza.attr.id, jid.resource(from)); add_state(stanza.attr.id, jid.resource(from));
@ -179,11 +171,11 @@ function handle_client_join(event)
return true; return true;
end end
function handle_client_leave(event) local function handle_client_leave(event)
-- Client requests to leave -- Client requests to leave
module:log("debug", "client-leave received"); module:log("debug", "client-leave received");
local stanza, origin = event.stanza, event.origin; local stanza, origin = event.stanza, event.origin;
local from, to = jid.bare(stanza.attr.from), jid.bare(stanza.attr.to); local from = jid.bare(stanza.attr.from);
local client_leave = stanza:get_child("client-leave", mix_pam_xmlns); local client_leave = stanza:get_child("client-leave", mix_pam_xmlns);
if client_leave.attr.channel == nil then if client_leave.attr.channel == nil then
@ -197,7 +189,12 @@ function handle_client_leave(event)
end end
-- Transform the client-join into a join -- Transform the client-join into a join
local leave_iq = st.iq({ type = "set", from = jid.bare(stanza.attr.from), to = client_leave.attr.channel, id = stanza.attr.id }); local leave_iq = st.iq({
type = "set";
from = jid.bare(stanza.attr.from);
to = client_leave.attr.channel;
id = stanza.attr.id
});
leave_iq:add_child(leave); leave_iq:add_child(leave);
add_state(stanza.attr.id, jid.resource(from)); add_state(stanza.attr.id, jid.resource(from));
@ -206,6 +203,94 @@ function handle_client_leave(event)
return true; return true;
end end
module:hook("iq/self", function(event)
local stanza = event.stanza;
if #stanza.tags == 0 then return; end
if stanza:get_child("client-join", mix_pam_xmlns) ~= nil then
return handle_client_join(event);
elseif stanza:get_child("client-leave", mix_pam_xmlns) ~= nil then
return handle_client_leave(event);
end
end);
local function handle_mix_join(event)
-- The MIX server responded
module:log("debug", "Received MIX-JOIN result");
module:log("debug", "Adding %s as a new MIX host", jid.host(event.stanza.attr.from));
add_mix_host(jid.host(event.stanza.attr.from));
mix_pam:set("hosts", mix_hosts);
local stanza = event.stanza;
local spid = stanza:get_child("join", "urn:xmpp:mix:core:1").attr.id;
local channel_jid = spid.."#"..stanza.attr.from;
local origin = pop_state(stanza.attr.id);
local resource = origin.resource;
if resource == nil then
module:log("error", "Got a MIX join result for a not-requested id %s", stanza.attr.id);
module:log("error", "Maybe the server changed the stanza ID?");
return false;
end
-- Keep track of the SPID
set_mix_spid(stanza.attr.to, stanza.attr.from, spid);
local client_join = st.iq({
type = "result";
id = stanza.attr.id;
from = jid.bare(stanza.attr.to);
to = stanza.attr.to.."/"..resource
}):tag("client-join", { xmlns = mix_pam_xmlns, jid = channel_jid });
client_join:add_child(stanza:get_child("join", "urn:xmpp:mix:core:1"));
module:send(client_join);
-- TODO: Error handling?
rm_add_to_roster(origin, stanza.attr.from, {
subscription = "both",
groups = {},
});
rm_roster_push(jid.node(stanza.attr.to), module_host, stanza.attr.from);
return true;
end
local function handle_mix_leave(event)
-- The MIX server responded
module:log("debug", "Received MIX-LEAVE result");
remove_mix_host(jid.host(event.stanza.attr.from));
mix_pam:set("hosts", mix_hosts);
local stanza = event.stanza;
local origin = pop_state(stanza.attr.id);
local resource = origin.resource;
if resource == nil then
module:log("error", "Got a MIX leave result for a not-requested id %s", stanza.attr.id);
module:log("error", "Maybe the MIX server changed the stanza ID?");
return false;
end
-- Keep track of the SPID
set_mix_spid(stanza.attr.to, jid.bare(stanza.attr.from));
local client_leave = st.iq({
type = "result";
id = stanza.attr.id;
from = jid.bare(stanza.attr.to);
to = stanza.attr.to.."/"..resource
}):tag("client-leave", { xmlns = mix_pam_xmlns });
client_leave:add_child(stanza:get_child("leave", "urn:xmpp:mix:core:1"));
module:send(client_leave);
-- Remove from roster
-- TODO: Error handling
rm_remove_from_roster(origin, jid.bare(stanza.attr.from));
rm_roster_push(jid.node(stanza.attr.to), module_host, jid.bare(stanza.attr.from));
return true;
end
module:hook("iq/bare", function(event) module:hook("iq/bare", function(event)
-- We handle the MIX results here since IQ stanzas against bare JIDs -- We handle the MIX results here since IQ stanzas against bare JIDs
-- don't make a lot of sense. We first have to translate them into -- don't make a lot of sense. We first have to translate them into
@ -222,98 +307,33 @@ module:hook("iq/bare", function(event)
end end
end); end);
function handle_mix_join(event)
-- The MIX server responded
module:log("debug", "Received MIX-JOIN result");
module:log("debug", "Adding %s as a new MIX host", jid.host(event.stanza.attr.from));
add_mix_host(jid.host(event.stanza.attr.from));
mix_pam:set("hosts", mix_hosts);
local stanza = event.stanza;
local spid = stanza:get_child("join", "urn:xmpp:mix:core:1").attr.id;
local channel_jid = spid.."#"..stanza.attr.from;
local origin = pop_state(stanza.attr.id);
local resource = origin.resource;
if resource == nil then
module:log("error", "Got a MIX join result for a not-requested id %s. Maybe the MIX server changed the stanza ID?", stanza.attr.id);
return false;
end
-- Keep track of the SPID
set_mix_spid(stanza.attr.to, stanza.attr.from, spid);
local client_join = st.iq({ type = "result", id = stanza.attr.id, from = jid.bare(stanza.attr.to), to = stanza.attr.to.."/"..resource })
:tag("client-join", { xmlns = mix_pam_xmlns, jid = channel_jid });
client_join:add_child(stanza:get_child("join", "urn:xmpp:mix:core:1"));
module:send(client_join);
-- TODO: Error handling?
rm_add_to_roster(origin, stanza.attr.from, {
subscription = "both",
groups = {},
});
rm_roster_push(jid.node(stanza.attr.to), host, stanza.attr.from);
return true;
end
function handle_mix_leave(event)
-- The MIX server responded
module:log("debug", "Received MIX-LEAVE result");
remove_mix_host(jid.host(event.stanza.attr.from));
mix_pam:set("hosts", mix_hosts);
local stanza = event.stanza;
local origin = pop_state(stanza.attr.id);
local resource = origin.resource;
if resource == nil then
module:log("error", "Got a MIX leave result for a not-requested id %s. Maybe the MIX server changed the stanza ID?", stanza.attr.id);
return false;
end
-- Keep track of the SPID
set_mix_spid(stanza.attr.to, jid.bare(stanza.attr.from));
local client_leave = st.iq({ type = "result", id = stanza.attr.id, from = jid.bare(stanza.attr.to), to = stanza.attr.to.."/"..resource })
:tag("client-leave", { xmlns = mix_pam_xmlns });
client_leave:add_child(stanza:get_child("leave", "urn:xmpp:mix:core:1"));
module:send(client_leave);
-- Remove from roster
-- TODO: Error handling
rm_remove_from_roster(origin, jid.bare(stanza.attr.from));
rm_roster_push(jid.node(stanza.attr.to), host, jid.bare(stanza.attr.from));
return true;
end
local user_resources = {}; -- [bare jid] -> array of bound resources local user_resources = {}; -- [bare jid] -> array of bound resources
module:hook("resource-bind", function(event) module:hook("resource-bind", function(event)
local jid, resource = jid.bare(event.session.full_jid), event.session.resource; local session_jid, resource = jid.bare(event.session.full_jid), event.session.resource;
if user_resources[jid] ~= nil then if user_resources[session_jid] ~= nil then
for _, r in pairs(user_resources) do for _, r in pairs(user_resources) do
if r == resource then return; end if r == resource then return; end
end end
table.insert(user_resources[jid], resource); table.insert(user_resources[session_jid], resource);
else else
user_resources[jid] = { resource }; user_resources[session_jid] = { resource };
end end
module:log("debug", "Caught resource %s of %s", resource, jid); module:log("debug", "Caught resource %s of %s", resource, session_jid);
end); end);
module:hook("resource-unbind", function(event) module:hook("resource-unbind", function(event)
local jid, resource = jid.bare(event.session.full_jid), event.session.resource; local session_jid, resource = jid.bare(event.session.full_jid), event.session.resource;
for i, r in pairs(user_resources[jid]) do for i, r in pairs(user_resources[session_jid]) do
if r == resource then if r == resource then
table.remove(user_resources[jid], i); table.remove(user_resources[session_jid], i);
return; return;
end end
end end
module:log("debug", "Unbind of not recorded resource %s (%s)", resource, jid); module:log("debug", "Unbind of not recorded resource %s (%s)", resource, session_jid);
end); end);
module:hook("roster-get", function(event) module:hook("roster-get", function(event)
@ -323,7 +343,7 @@ module:hook("roster-get", function(event)
:get_child("query", "jabber:iq:roster") :get_child("query", "jabber:iq:roster")
:get_child("annotate", mix_roster_xmlns); :get_child("annotate", mix_roster_xmlns);
if not annotate then return; end if not annotate then return; end
local reply, stanza = event.reply, event.stanza; local stanza = event.stanza;
module:log("debug", "Annotated roster request received"); module:log("debug", "Annotated roster request received");
@ -341,8 +361,8 @@ end);
module:hook("message/bare", function(event) module:hook("message/bare", function(event)
local stanza = event.stanza; local stanza = event.stanza;
local host = jid.host(stanza.attr.from); local jid_host = jid.host(stanza.attr.from);
if not is_mix_host(host) then return; end if not is_mix_host(jid_host) then return; end
if not is_mix_message(stanza) then return; end if not is_mix_message(stanza) then return; end
-- MIX-CORE says that if the message cannot be delivered, it should -- MIX-CORE says that if the message cannot be delivered, it should