mirror of
https://gitcode.com/GitHub_Trending/ji/jitsi-meet.git
synced 2025-12-30 03:12:29 +00:00
We were using prosody,util.json and cjson at the same time, but the latter is more performant. Adds some error handling which were missing with the prosody util json one.
198 lines
6.0 KiB
Lua
198 lines
6.0 KiB
Lua
-- Prosody IM
|
|
-- Copyright (C) 2021-present 8x8, Inc.
|
|
--
|
|
|
|
local jid = require "util.jid";
|
|
local it = require "util.iterators";
|
|
local json = require 'cjson.safe';
|
|
local iterators = require "util.iterators";
|
|
local array = require"util.array";
|
|
|
|
local have_async = pcall(require, "util.async");
|
|
if not have_async then
|
|
module:log("error", "requires a version of Prosody with util.async");
|
|
return;
|
|
end
|
|
|
|
local async_handler_wrapper = module:require "util".async_handler_wrapper;
|
|
|
|
local tostring = tostring;
|
|
local neturl = require "net.url";
|
|
local parse = neturl.parseQuery;
|
|
|
|
-- option to enable/disable room API token verifications
|
|
local enableTokenVerification
|
|
= module:get_option_boolean("enable_roomsize_token_verification", false);
|
|
|
|
local token_util = module:require "token/util".new(module);
|
|
local get_room_from_jid = module:require "util".get_room_from_jid;
|
|
|
|
-- no token configuration but required
|
|
if token_util == nil and enableTokenVerification then
|
|
log("error", "no token configuration but it is required");
|
|
return;
|
|
end
|
|
|
|
-- required parameter for custom muc component prefix,
|
|
-- defaults to "conference"
|
|
local muc_domain_prefix
|
|
= module:get_option_string("muc_mapper_domain_prefix", "conference");
|
|
|
|
--- Verifies room name, domain name with the values in the token
|
|
-- @param token the token we received
|
|
-- @param room_address the full room address jid
|
|
-- @return true if values are ok or false otherwise
|
|
function verify_token(token, room_address)
|
|
if not enableTokenVerification then
|
|
return true;
|
|
end
|
|
|
|
-- if enableTokenVerification is enabled and we do not have token
|
|
-- stop here, cause the main virtual host can have guest access enabled
|
|
-- (allowEmptyToken = true) and we will allow access to rooms info without
|
|
-- a token
|
|
if token == nil then
|
|
log("warn", "no token provided");
|
|
return false;
|
|
end
|
|
|
|
local session = {};
|
|
session.auth_token = token;
|
|
local verified, reason = token_util:process_and_verify_token(session);
|
|
if not verified then
|
|
log("warn", "not a valid token %s", tostring(reason));
|
|
return false;
|
|
end
|
|
|
|
if not token_util:verify_room(session, room_address) then
|
|
log("warn", "Token %s not allowed to join: %s",
|
|
tostring(token), tostring(room_address));
|
|
return false;
|
|
end
|
|
|
|
return true;
|
|
end
|
|
|
|
--- Handles request for retrieving the room size
|
|
-- @param event the http event, holds the request query
|
|
-- @return GET response, containing a json with participants count,
|
|
-- the value is without counting the focus.
|
|
function handle_get_room_size(event)
|
|
if (not event.request.url.query) then
|
|
return { status_code = 400; };
|
|
end
|
|
|
|
local params = parse(event.request.url.query);
|
|
local room_name = params["room"];
|
|
local domain_name = params["domain"];
|
|
local subdomain = params["subdomain"];
|
|
|
|
local room_address
|
|
= jid.join(room_name, muc_domain_prefix.."."..domain_name);
|
|
|
|
if subdomain and subdomain ~= "" then
|
|
room_address = "["..subdomain.."]"..room_address;
|
|
end
|
|
|
|
if not verify_token(params["token"], room_address) then
|
|
return { status_code = 403; };
|
|
end
|
|
|
|
local room = get_room_from_jid(room_address);
|
|
local participant_count = 0;
|
|
|
|
log("debug", "Querying room %s", tostring(room_address));
|
|
|
|
if room then
|
|
local occupants = room._occupants;
|
|
if occupants then
|
|
participant_count = iterators.count(room:each_occupant());
|
|
end
|
|
log("debug",
|
|
"there are %s occupants in room", tostring(participant_count));
|
|
else
|
|
log("debug", "no such room exists");
|
|
return { status_code = 404; };
|
|
end
|
|
|
|
if participant_count > 1 then
|
|
participant_count = participant_count - 1;
|
|
end
|
|
|
|
return { status_code = 200; body = [[{"participants":]]..participant_count..[[}]] };
|
|
end
|
|
|
|
--- Handles request for retrieving the room participants details
|
|
-- @param event the http event, holds the request query
|
|
-- @return GET response, containing a json with participants details
|
|
function handle_get_room (event)
|
|
if (not event.request.url.query) then
|
|
return { status_code = 400; };
|
|
end
|
|
|
|
local params = parse(event.request.url.query);
|
|
local room_name = params["room"];
|
|
local domain_name = params["domain"];
|
|
local subdomain = params["subdomain"];
|
|
local room_address
|
|
= jid.join(room_name, muc_domain_prefix.."."..domain_name);
|
|
|
|
if subdomain and subdomain ~= "" then
|
|
room_address = "["..subdomain.."]"..room_address;
|
|
end
|
|
|
|
if not verify_token(params["token"], room_address) then
|
|
return { status_code = 403; };
|
|
end
|
|
|
|
local room = get_room_from_jid(room_address);
|
|
local participant_count = 0;
|
|
local occupants_json = array();
|
|
|
|
log("debug", "Querying room %s", tostring(room_address));
|
|
|
|
if room then
|
|
local occupants = room._occupants;
|
|
if occupants then
|
|
participant_count = iterators.count(room:each_occupant());
|
|
for _, occupant in room:each_occupant() do
|
|
-- filter focus as we keep it as hidden participant
|
|
if string.sub(occupant.nick,-string.len("/focus"))~="/focus" then
|
|
for _, pr in occupant:each_session() do
|
|
local nick = pr:get_child_text("nick", "http://jabber.org/protocol/nick") or "";
|
|
local email = pr:get_child_text("email") or "";
|
|
occupants_json:push({
|
|
jid = tostring(occupant.nick),
|
|
email = tostring(email),
|
|
display_name = tostring(nick)});
|
|
end
|
|
end
|
|
end
|
|
end
|
|
log("debug",
|
|
"there are %s occupants in room", tostring(participant_count));
|
|
else
|
|
log("debug", "no such room exists");
|
|
return { status_code = 404; };
|
|
end
|
|
|
|
if participant_count > 1 then
|
|
participant_count = participant_count - 1;
|
|
end
|
|
|
|
return { status_code = 200; body = json.encode(occupants_json); };
|
|
end;
|
|
|
|
function module.load()
|
|
module:depends("http");
|
|
module:provides("http", {
|
|
default_path = "/";
|
|
route = {
|
|
["GET room-size"] = function (event) return async_handler_wrapper(event,handle_get_room_size) end;
|
|
["GET sessions"] = function () return tostring(it.count(it.keys(prosody.full_sessions))); end;
|
|
["GET room"] = function (event) return async_handler_wrapper(event,handle_get_room) end;
|
|
};
|
|
});
|
|
end
|
|
|