mod_mix_pam: LuaCheck the module
This commit is contained in:
parent
cd68dfa583
commit
c251502799
@ -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!");
|
||||
end
|
||||
]]--
|
||||
@ -26,13 +26,13 @@ module:add_feature(mix_pam_xmlns);
|
||||
-- NOTE: To show that we archive messages
|
||||
-- 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
|
||||
-- otherwise.
|
||||
return table[key] ~= nil;
|
||||
end
|
||||
|
||||
function set_mix_spid(user, channel, spid)
|
||||
local function set_mix_spid(user, channel, spid)
|
||||
if mix_spids[user] ~= nil then
|
||||
mix_spids[user][channel] = spid;
|
||||
else
|
||||
@ -41,10 +41,10 @@ function set_mix_spid(user, channel, spid)
|
||||
|
||||
mix_pam:set("spids", mix_spids);
|
||||
end
|
||||
function get_mix_spid(user, channel)
|
||||
local function get_mix_spid(user, channel)
|
||||
return mix_spids[user][channel];
|
||||
end;
|
||||
function remove_mix_spid(user, channel)
|
||||
local function remove_mix_spid(user, channel)
|
||||
mix_spids[user][channel] = nil;
|
||||
if mix_spids[user][channel] == {} then
|
||||
mix_spids[user][channel] = nil;
|
||||
@ -53,7 +53,7 @@ function remove_mix_spid(user, channel)
|
||||
mix_pam:set("spids", mix_spids);
|
||||
end
|
||||
|
||||
function add_mix_host(host)
|
||||
local function add_mix_host(host)
|
||||
if mix_hosts[host] ~= nil then
|
||||
mix_hosts[host] = mix_hosts[host] + 1;
|
||||
module:log("debug", "Known MIX host has a new user");
|
||||
@ -64,9 +64,8 @@ function add_mix_host(host)
|
||||
|
||||
mix_pam:set("hosts", mix_hosts);
|
||||
end
|
||||
|
||||
function remove_mix_host(host)
|
||||
if mix_hosts[host] ~= nil then
|
||||
local function remove_mix_host(host)
|
||||
if mix_hosts[host] ~= nil then
|
||||
local count = mix_hosts[host];
|
||||
if count == 1 then
|
||||
mix_hosts[host] = nil;
|
||||
@ -81,19 +80,18 @@ function remove_mix_host(host)
|
||||
|
||||
mix_pam:set("hosts", mix_hosts);
|
||||
end
|
||||
|
||||
function is_mix_host(host)
|
||||
local function is_mix_host(host)
|
||||
return mix_hosts[host] ~= nil;
|
||||
end
|
||||
|
||||
function is_mix_message(stanza)
|
||||
local function is_mix_message(stanza)
|
||||
return stanza:get_child("mix", "urn:xmpp:mix:core:1") ~= nil;
|
||||
end
|
||||
|
||||
function module.load()
|
||||
mix_hosts = mix_pam:get("hosts");
|
||||
module:log("info", "Loaded known MIX hosts");
|
||||
|
||||
|
||||
if mix_hosts == nil then
|
||||
module:log("info", "No known MIX hosts loaded");
|
||||
mix_hosts = {};
|
||||
@ -104,7 +102,7 @@ function module.load()
|
||||
|
||||
mix_spids = mix_pam:get("spids");
|
||||
module:log("info", "Loaded known MIX SPIDs");
|
||||
|
||||
|
||||
if mix_spids == nil then
|
||||
module:log("info", "No known MIX SPIDs loaded");
|
||||
mix_spids = {};
|
||||
@ -122,14 +120,14 @@ function module.load()
|
||||
end
|
||||
|
||||
local client_state_tracker = {}; -- [stanza ID] -> resource
|
||||
function add_state(id, resource)
|
||||
local function add_state(id, resource)
|
||||
client_state_tracker[id] = resource;
|
||||
module:log("debug", "Adding a resource %s for id %s", resource, id);
|
||||
end
|
||||
function has_state(id)
|
||||
local function has_state(id)
|
||||
return client_state_tracker[id] ~= nil;
|
||||
end
|
||||
function pop_state(id)
|
||||
local function pop_state(id)
|
||||
module:log("debug", "Popping a resource for stanza id %s", id);
|
||||
|
||||
if has_state(id) then
|
||||
@ -141,6 +139,70 @@ function pop_state(id)
|
||||
return nil;
|
||||
end
|
||||
|
||||
local function handle_client_join(event)
|
||||
-- Client requests to join
|
||||
module:log("debug", "client-join received");
|
||||
local stanza, origin = event.stanza, event.origin;
|
||||
local from = jid.bare(stanza.attr.from);
|
||||
|
||||
local client_join = stanza:get_child("client-join", mix_pam_xmlns);
|
||||
if client_join.attr.channel == nil then
|
||||
origin.send(st.error_reply(stanza, "cancel", "bad-request", "No channel specified"));
|
||||
return true;
|
||||
end
|
||||
local join = client_join:get_child("join", "urn:xmpp:mix:core:1");
|
||||
if join == nil then
|
||||
origin.send(st.error_reply(stanza, "cancel", "bad-request", "No join stanza"));
|
||||
return true;
|
||||
end
|
||||
|
||||
-- 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"
|
||||
});
|
||||
join_iq:add_child(join);
|
||||
|
||||
add_state(stanza.attr.id, jid.resource(from));
|
||||
|
||||
module:send(join_iq);
|
||||
return true;
|
||||
end
|
||||
|
||||
local function handle_client_leave(event)
|
||||
-- Client requests to leave
|
||||
module:log("debug", "client-leave received");
|
||||
local stanza, origin = event.stanza, event.origin;
|
||||
local from = jid.bare(stanza.attr.from);
|
||||
|
||||
local client_leave = stanza:get_child("client-leave", mix_pam_xmlns);
|
||||
if client_leave.attr.channel == nil then
|
||||
origin.send(st.error_reply(stanza, "cancel", "bad-request", "No channel specified"));
|
||||
return true;
|
||||
end
|
||||
local leave = client_leave:get_child("leave", "urn:xmpp:mix:core:1");
|
||||
if leave == nil then
|
||||
origin.send(st.error_reply(stanza, "cancel", "bad-request", "No leave stanza"));
|
||||
return true;
|
||||
end
|
||||
|
||||
-- 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
|
||||
});
|
||||
leave_iq:add_child(leave);
|
||||
|
||||
add_state(stanza.attr.id, jid.resource(from));
|
||||
|
||||
module:send(leave_iq);
|
||||
return true;
|
||||
end
|
||||
|
||||
module:hook("iq/self", function(event)
|
||||
local stanza = event.stanza;
|
||||
if #stanza.tags == 0 then return; end
|
||||
@ -152,57 +214,80 @@ module:hook("iq/self", function(event)
|
||||
end
|
||||
end);
|
||||
|
||||
function handle_client_join(event)
|
||||
-- Client requests to join
|
||||
module:log("debug", "client-join received");
|
||||
local stanza, origin = event.stanza, event.origin;
|
||||
local from, to = jid.bare(stanza.attr.from), jid.bare(stanza.attr.to);
|
||||
|
||||
local client_join = stanza:get_child("client-join", mix_pam_xmlns);
|
||||
if client_join.attr.channel == nil then
|
||||
origin.send(st.error_reply(stanza, "cancel", "bad-request", "No channel specified"));
|
||||
return true;
|
||||
end
|
||||
local join = client_join:get_child("join", "urn:xmpp:mix:core:1");
|
||||
if join == nil then
|
||||
origin.send(st.error_reply(stanza, "cancel", "bad-request", "No join stanza"));
|
||||
return true;
|
||||
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
|
||||
|
||||
-- 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" });
|
||||
join_iq:add_child(join);
|
||||
|
||||
add_state(stanza.attr.id, jid.resource(from));
|
||||
-- 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);
|
||||
|
||||
module:send(join_iq);
|
||||
return true;
|
||||
end
|
||||
|
||||
function handle_client_leave(event)
|
||||
-- Client requests to leave
|
||||
module:log("debug", "client-leave received");
|
||||
local stanza, origin = event.stanza, event.origin;
|
||||
local from, to = jid.bare(stanza.attr.from), jid.bare(stanza.attr.to);
|
||||
|
||||
local client_leave = stanza:get_child("client-leave", mix_pam_xmlns);
|
||||
if client_leave.attr.channel == nil then
|
||||
origin.send(st.error_reply(stanza, "cancel", "bad-request", "No channel specified"));
|
||||
return true;
|
||||
end
|
||||
local leave = client_leave:get_child("leave", "urn:xmpp:mix:core:1");
|
||||
if leave == nil then
|
||||
origin.send(st.error_reply(stanza, "cancel", "bad-request", "No leave stanza"));
|
||||
return true;
|
||||
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
|
||||
|
||||
-- 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 });
|
||||
leave_iq:add_child(leave);
|
||||
-- Keep track of the SPID
|
||||
set_mix_spid(stanza.attr.to, jid.bare(stanza.attr.from));
|
||||
|
||||
add_state(stanza.attr.id, jid.resource(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));
|
||||
|
||||
module:send(leave_iq);
|
||||
return true;
|
||||
end
|
||||
|
||||
@ -222,98 +307,33 @@ module:hook("iq/bare", function(event)
|
||||
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
|
||||
|
||||
module:hook("resource-bind", function(event)
|
||||
local jid, resource = jid.bare(event.session.full_jid), event.session.resource;
|
||||
if user_resources[jid] ~= nil then
|
||||
local session_jid, resource = jid.bare(event.session.full_jid), event.session.resource;
|
||||
if user_resources[session_jid] ~= nil then
|
||||
for _, r in pairs(user_resources) do
|
||||
if r == resource then return; end
|
||||
end
|
||||
|
||||
table.insert(user_resources[jid], resource);
|
||||
table.insert(user_resources[session_jid], resource);
|
||||
else
|
||||
user_resources[jid] = { resource };
|
||||
user_resources[session_jid] = { resource };
|
||||
end
|
||||
|
||||
module:log("debug", "Caught resource %s of %s", resource, jid);
|
||||
module:log("debug", "Caught resource %s of %s", resource, session_jid);
|
||||
end);
|
||||
|
||||
module:hook("resource-unbind", function(event)
|
||||
local jid, resource = jid.bare(event.session.full_jid), event.session.resource;
|
||||
for i, r in pairs(user_resources[jid]) do
|
||||
local session_jid, resource = jid.bare(event.session.full_jid), event.session.resource;
|
||||
for i, r in pairs(user_resources[session_jid]) do
|
||||
if r == resource then
|
||||
table.remove(user_resources[jid], i);
|
||||
table.remove(user_resources[session_jid], i);
|
||||
return;
|
||||
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);
|
||||
|
||||
module:hook("roster-get", function(event)
|
||||
@ -323,7 +343,7 @@ module:hook("roster-get", function(event)
|
||||
:get_child("query", "jabber:iq:roster")
|
||||
:get_child("annotate", mix_roster_xmlns);
|
||||
if not annotate then return; end
|
||||
local reply, stanza = event.reply, event.stanza;
|
||||
local stanza = event.stanza;
|
||||
|
||||
module:log("debug", "Annotated roster request received");
|
||||
|
||||
@ -341,10 +361,10 @@ end);
|
||||
|
||||
module:hook("message/bare", function(event)
|
||||
local stanza = event.stanza;
|
||||
local host = jid.host(stanza.attr.from);
|
||||
if not is_mix_host(host) then return; end
|
||||
local jid_host = jid.host(stanza.attr.from);
|
||||
if not is_mix_host(jid_host) then return; end
|
||||
if not is_mix_message(stanza) then return; end
|
||||
|
||||
|
||||
-- MIX-CORE says that if the message cannot be delivered, it should
|
||||
-- just be dropped
|
||||
if user_resources[stanza.attr.to] == nil then
|
||||
|
Loading…
Reference in New Issue
Block a user