Updates rayo filter to add user token info to dial messages.

Adds option to limit number of outgoing calls per user.
This commit is contained in:
damencho 2019-09-26 10:37:10 +01:00 committed by Дамян Минков
parent 51f257e894
commit 5cd351a46f
1 changed files with 117 additions and 1 deletions

View File

@ -10,6 +10,13 @@ if token_util == nil then
return;
end
-- configuration to limit number of outgoing calls
local LIMIT_OUTGOING_CALLS = module:get_option_number("max_number_outgoing_calls", -1);
-- Header names to use to push extra data extracted from token, if any
local OUT_INITIATOR_USER_ATTR_NAME = "X-outbound-call-initiator-user";
local OUT_INITIATOR_GROUP_ATTR_NAME = "X-outbound-call-initiator-group";
-- filters rayo iq in case of requested from not jwt authenticated sessions
-- or if the session has features in user context and it doesn't mention
-- feature "outbound-call" to be enabled
@ -39,11 +46,120 @@ module:hook("pre-iq/full", function(event)
(dial.attr.to == 'jitsi_meet_transcribe' and 'transcription'
or 'outbound-call'))
then
module:log("info",
module:log("warn",
"Filtering stanza dial, stanza:%s", tostring(stanza));
session.send(st.error_reply(stanza, "auth", "forbidden"));
return true;
end
-- now lets check any limits if configured
if LIMIT_OUTGOING_CALLS > 0
and get_concurrent_outgoing_count(
session.jitsi_meet_context_user["id"],
session.jitsi_meet_context_group) >= LIMIT_OUTGOING_CALLS
then
module:log("warn",
"Filtering stanza dial, stanza:%s, outgoing calls limit reached", tostring(stanza));
session.send(st.error_reply(stanza, "cancel", "resource-constraint"));
return true;
end
-- now lets insert token information if any
if session and session.jitsi_meet_context_user then
-- First remove any 'header' element if it already
-- exists, so it cannot be spoofed by a client
stanza:maptags(
function(tag)
if tag.name == "header"
and (tag.attr.name == OUT_INITIATOR_USER_ATTR_NAME
or tag.attr.name == OUT_INITIATOR_GROUP_ATTR_NAME) then
return nil
end
return tag
end
)
local dial = stanza:get_child('dial', 'urn:xmpp:rayo:1');
-- adds initiator user id from token
dial:tag("header", {
xmlns = "urn:xmpp:rayo:1",
name = OUT_INITIATOR_USER_ATTR_NAME,
value = session.jitsi_meet_context_user["id"] });
dial:up();
-- Add the initiator group information if it is present
if session.jitsi_meet_context_group then
dial:tag("header", {
xmlns = "urn:xmpp:rayo:1",
name = OUT_INITIATOR_GROUP_ATTR_NAME,
value = session.jitsi_meet_context_group });
dial:up();
end
end
end
end
end);
--- Finds and returns the number of concurrent outgoing calls for a user
-- @param context_user the user id extracted from the token
-- @param context_group the group id extracted from the token
-- @return returns the count of concurrent calls
function get_concurrent_outgoing_count(context_user, context_group)
local count = 0;
for _, host in pairs(hosts) do
local component = host;
if component then
local muc = component.modules.muc
local rooms = nil;
if muc and rawget(muc,"rooms") then
-- We're running 0.9.x or 0.10 (old MUC API)
return muc.rooms;
elseif muc and rawget(muc,"live_rooms") then
-- We're running >=0.11 (new MUC API)
rooms = muc.live_rooms();
elseif muc and rawget(muc,"each_room") then
-- We're running trunk<0.11 (each_room is later [DEPRECATED])
rooms = muc.each_room(true);
end
-- now lets iterate over rooms and occupants and search for
-- call initiated by the user
if rooms then
for room in rooms do
for _, occupant in room:each_occupant() do
for _, presence in occupant:each_session() do
local initiator = presence:get_child('initiator', 'http://jitsi.org/protocol/jigasi');
local found_user = false;
local found_group = false;
if initiator then
initiator:maptags(function (tag)
if tag.name == "header"
and tag.attr.name == OUT_INITIATOR_USER_ATTR_NAME then
found_user = tag.attr.value == context_user;
elseif tag.name == "header"
and tag.attr.name == OUT_INITIATOR_GROUP_ATTR_NAME then
found_group = tag.attr.value == context_group;
end
return tag;
end );
-- if found a jigasi participant initiated by the concurrent
-- participant, count it
if found_user
and (context_group == nil or found_group) then
count = count + 1;
end
end
end
end
end
end
end
end
return count;
end