2020-06-29 23:11:41 +00:00
local st = require " util.stanza " ;
local jid = require " util.jid " ;
local http = require " net.http " ;
local json = require " cjson " ;
local inspect = require ( ' inspect ' ) ;
local socket = require " socket " ;
local uuid_gen = require " util.uuid " . generate ;
local jwt = require " luajwtjitsi " ;
local it = require " util.iterators " ;
2020-06-29 23:20:04 +00:00
local neturl = require " net.url " ;
local parse = neturl.parseQuery ;
2020-06-29 23:11:41 +00:00
local get_room_from_jid = module : require " util " . get_room_from_jid ;
local room_jid_match_rewrite = module : require " util " . room_jid_match_rewrite ;
local is_healthcheck_room = module : require " util " . is_healthcheck_room ;
2020-07-14 20:50:34 +00:00
local room_jid_split_subdomain = module : require " util " . room_jid_split_subdomain ;
local internal_room_jid_match_rewrite = module : require " util " . internal_room_jid_match_rewrite ;
2020-06-29 23:20:04 +00:00
local async_handler_wrapper = module : require " util " . async_handler_wrapper ;
-- this basically strips the domain from the conference.domain address
local parentHostName = string.gmatch ( tostring ( module.host ) , " %w+.(%w.+) " ) ( ) ;
if parentHostName == nil then
log ( " error " , " Failed to start - unable to get parent hostname " ) ;
return ;
end
local parentCtx = module : context ( parentHostName ) ;
if parentCtx == nil then
log ( " error " ,
" Failed to start - unable to get parent context for host: %s " ,
tostring ( parentHostName ) ) ;
return ;
end
local token_util = module : require " token/util " . new ( parentCtx ) ;
2020-08-14 19:13:57 +00:00
local ASAPKeyServer ;
local ASAPKeyPath ;
local ASAPKeyId ;
local ASAPIssuer ;
local ASAPAudience ;
local ASAPAcceptedIssuers ;
local ASAPAcceptedAudiences ;
local ASAPTTL ;
local ASAPTTL_THRESHOLD ;
local ASAPKey ;
local JibriRegion ;
local disableTokenVerification ;
local muc_component_host ;
local external_api_url ;
local jwtKeyCacheSize ;
local jwtKeyCache ;
local function load_config ( )
ASAPKeyServer = module : get_option_string ( " asap_key_server " ) ;
if ASAPKeyServer then
module : log ( " debug " , " ASAP Public Key URL %s " , ASAPKeyServer ) ;
token_util : set_asap_key_server ( ASAPKeyServer ) ;
end
2020-08-06 22:12:31 +00:00
2020-08-14 19:13:57 +00:00
ASAPKeyPath
= module : get_option_string ( " asap_key_path " , ' /etc/prosody/certs/asap.key ' ) ;
2020-06-29 23:11:41 +00:00
2020-08-14 19:13:57 +00:00
ASAPKeyId
= module : get_option_string ( " asap_key_id " , ' jitsi ' ) ;
2020-06-29 23:11:41 +00:00
2020-08-14 19:13:57 +00:00
ASAPIssuer
= module : get_option_string ( " asap_issuer " , ' jitsi ' ) ;
2020-06-29 23:11:41 +00:00
2020-08-14 19:13:57 +00:00
ASAPAudience
= module : get_option_string ( " asap_audience " , ' jibri-queue ' ) ;
2020-06-29 23:11:41 +00:00
2020-08-14 19:13:57 +00:00
ASAPAcceptedIssuers
= module : get_option_array ( ' asap_accepted_issuers ' , { ' jibri-queue ' } ) ;
module : log ( " debug " , " ASAP Accepted Issuers %s " , ASAPAcceptedIssuers ) ;
token_util : set_asap_accepted_issuers ( ASAPAcceptedIssuers ) ;
2020-08-10 20:21:31 +00:00
2020-08-14 19:13:57 +00:00
ASAPAcceptedAudiences
= module : get_option_array ( ' asap_accepted_audiences ' , { ' * ' } ) ;
module : log ( " debug " , " ASAP Accepted Audiences %s " , ASAPAcceptedAudiences ) ;
token_util : set_asap_accepted_audiences ( ASAPAcceptedAudiences ) ;
2020-08-10 20:21:31 +00:00
2020-08-14 19:13:57 +00:00
-- do not require room to be set on tokens for jibri queue
token_util : set_asap_require_room_claim ( false ) ;
2020-08-10 20:21:31 +00:00
2020-08-14 19:13:57 +00:00
ASAPTTL
= module : get_option_number ( " asap_ttl " , 3600 ) ;
ASAPTTL_THRESHOLD
= module : get_option_number ( " asap_ttl_threshold " , 600 ) ;
2020-08-10 20:21:31 +00:00
2020-08-14 19:13:57 +00:00
queueServiceURL
= module : get_option_string ( " jibri_queue_url " ) ;
2020-08-12 19:43:34 +00:00
2020-08-14 19:13:57 +00:00
JibriRegion
= module : get_option_string ( " jibri_region " , ' default ' ) ;
2020-06-29 23:11:41 +00:00
2020-08-14 19:13:57 +00:00
-- option to enable/disable token verifications
disableTokenVerification
= module : get_option_boolean ( " disable_jibri_queue_token_verification " , false ) ;
2020-06-29 23:11:41 +00:00
2020-08-14 19:13:57 +00:00
muc_component_host
= module : get_option_string ( " muc_component " ) ;
2020-06-29 23:11:41 +00:00
2020-08-14 19:13:57 +00:00
external_api_url = module : get_option_string ( " external_api_url " , tostring ( parentHostName ) ) ;
module : log ( " debug " , " External advertised API URL " , external_api_url ) ;
-- TODO: Figure out a less arbitrary default cache size.
jwtKeyCacheSize
= module : get_option_number ( " jwt_pubkey_cache_size " , 128 ) ;
jwtKeyCache = require " util.cache " . new ( jwtKeyCacheSize ) ;
if queueServiceURL == nil then
log ( " error " , " No jibri_queue_url specified. No service to contact! " ) ;
return ;
end
if muc_component_host == nil then
log ( " error " , " No muc_component specified. No muc to operate on for jibri queue! " ) ;
return ;
end
-- Read ASAP key once on module startup
local f = io.open ( ASAPKeyPath , " r " ) ;
if f then
ASAPKey = f : read ( " *all " ) ;
f : close ( ) ;
if not ASAPKey then
module : log ( " warn " , " No ASAP Key read from %s, disabling jibri queue component plugin " , ASAPKeyPath ) ;
return
end
else
module : log ( " warn " , " Error reading ASAP Key %s, disabling jibri queue component plugin " , ASAPKeyPath ) ;
return
end
return true ;
end
2020-06-29 23:11:41 +00:00
2020-08-14 19:13:57 +00:00
local function reload_config ( )
module : log ( " info " , " Reloading configuration for jibri queue component " ) ;
local config_success = load_config ( ) ;
2020-06-29 23:20:04 +00:00
2020-08-14 19:13:57 +00:00
if not config_success then
log ( " error " , " Unsuccessful reconfiguration, jibri queue component may misbehave " ) ;
end
end
2020-08-06 22:12:31 +00:00
2020-08-14 19:13:57 +00:00
local config_success = load_config ( ) ;
if not config_success then
log ( " error " , " Unsuccessful configuration step, jibri queue component disabled " )
2020-06-29 23:20:04 +00:00
return ;
end
2020-06-29 23:11:41 +00:00
local http_headers = {
[ " User-Agent " ] = " Prosody ( " .. prosody.version .. " ; " .. prosody.platform .. " ) " ,
[ " Content-Type " ] = " application/json "
} ;
-- we use async to detect Prosody 0.10 and earlier
local have_async = pcall ( require , " util.async " ) ;
if not have_async then
module : log ( " warn " , " conference duration will not work with Prosody version 0.10 or less. " ) ;
return ;
end
log ( " info " , " Starting jibri queue handling for %s " , muc_component_host ) ;
local function round ( num , numDecimalPlaces )
local mult = 10 ^ ( numDecimalPlaces or 0 )
return math.floor ( num * mult + 0.5 ) / mult
end
local function generateToken ( audience )
audience = audience or ASAPAudience
local t = os.time ( )
local err
local exp_key = ' asap_exp. ' .. audience
local token_key = ' asap_token. ' .. audience
local exp = jwtKeyCache : get ( exp_key )
local token = jwtKeyCache : get ( token_key )
--if we find a token and it isn't too far from expiry, then use it
if token ~= nil and exp ~= nil then
exp = tonumber ( exp )
if ( exp - t ) > ASAPTTL_THRESHOLD then
return token
end
end
--expiry is the current time plus TTL
exp = t + ASAPTTL
local payload = {
iss = ASAPIssuer ,
aud = audience ,
nbf = t ,
exp = exp ,
}
-- encode
local alg = " RS256 "
token , err = jwt.encode ( payload , ASAPKey , alg , { kid = ASAPKeyId } )
if not err then
token = ' Bearer ' .. token
jwtKeyCache : set ( exp_key , exp )
jwtKeyCache : set ( token_key , token )
return token
else
return ' '
end
end
2020-07-20 16:51:07 +00:00
local function sendIq ( participant , action , requestId , time , position , token )
local iqId = uuid_gen ( ) ;
local from = module : get_host ( ) ;
local outStanza = st.iq ( { type = ' set ' , from = from , to = participant , id = iqId } ) : tag ( " jibri-queue " ,
{ xmlns = ' http://jitsi.org/protocol/jibri-queue ' , requestId = requestId , action = action } ) ;
2020-07-17 20:19:25 +00:00
2020-07-20 16:51:07 +00:00
if token then
outStanza : tag ( " token " ) : text ( token ) : up ( )
end
if time then
2020-08-10 20:21:56 +00:00
outStanza : tag ( " time " ) : text ( tostring ( time ) ) : up ( )
2020-07-20 16:51:07 +00:00
end
if position then
2020-08-10 20:21:56 +00:00
outStanza : tag ( " position " ) : text ( tostring ( position ) ) : up ( )
2020-07-20 16:51:07 +00:00
end
2020-08-14 19:13:57 +00:00
2020-07-17 20:19:25 +00:00
module : send ( outStanza ) ;
end
2020-06-29 23:11:41 +00:00
local function cb ( content_ , code_ , response_ , request_ )
if code_ == 200 or code_ == 204 then
module : log ( " debug " , " URL Callback: Code %s, Content %s, Request (host %s, path %s, body %s), Response: %s " ,
code_ , content_ , request_.host , request_.path , inspect ( request_.body ) , inspect ( response_ ) ) ;
else
module : log ( " warn " , " URL Callback non successful: Code %s, Content %s, Request (%s), Response: %s " ,
code_ , content_ , inspect ( request_ ) , inspect ( response_ ) ) ;
end
end
2020-07-17 20:19:25 +00:00
local function sendEvent ( type , room_address , participant , requestId , replyIq , replyError )
2020-06-29 23:11:41 +00:00
local event_ts = round ( socket.gettime ( ) * 1000 ) ;
2020-07-14 20:50:34 +00:00
local node , host , resource , target_subdomain = room_jid_split_subdomain ( room_address ) ;
local room_param = ' ' ;
if target_subdomain then
room_param = target_subdomain .. ' / ' .. node ;
else
room_param = node ;
end
2020-06-29 23:11:41 +00:00
local out_event = {
[ " conference " ] = room_address ,
2020-07-17 20:19:25 +00:00
[ " roomParam " ] = room_param ,
[ " eventType " ] = type ,
2020-06-29 23:11:41 +00:00
[ " participant " ] = participant ,
2020-07-17 20:19:25 +00:00
[ " externalApiUrl " ] = external_api_url .. " /jibriqueue/update " ,
[ " requestId " ] = requestId ,
2020-08-06 22:12:31 +00:00
[ " region " ] = JibriRegion ,
2020-06-29 23:11:41 +00:00
}
module : log ( " debug " , " Sending event %s " , inspect ( out_event ) ) ;
local headers = http_headers or { }
headers [ ' Authorization ' ] = generateToken ( )
module : log ( " debug " , " Sending headers %s " , inspect ( headers ) ) ;
2020-07-22 20:24:08 +00:00
local requestURL = queueServiceURL .. " /job/recording "
if type == " LeaveQueue " then
requestURL = requestURL .. " /cancel "
end
local request = http.request ( requestURL , {
2020-06-29 23:11:41 +00:00
headers = headers ,
method = " POST " ,
body = json.encode ( out_event )
2020-07-17 20:19:25 +00:00
} , function ( content_ , code_ , response_ , request_ )
if code_ == 200 or code_ == 204 then
module : log ( " debug " , " URL Callback: Code %s, Content %s, Request (host %s, path %s, body %s), Response: %s " ,
code_ , content_ , request_.host , request_.path , inspect ( request_.body ) , inspect ( response_ ) ) ;
2020-08-13 21:41:42 +00:00
if ( replyIq ) then
module : log ( " debug " , " sending reply IQ %s " , inspect ( replyIq ) ) ;
module : send ( replyIq ) ;
end
2020-07-17 20:19:25 +00:00
else
module : log ( " warn " , " URL Callback non successful: Code %s, Content %s, Request (%s), Response: %s " ,
code_ , content_ , inspect ( request_ ) , inspect ( response_ ) ) ;
2020-08-13 21:41:42 +00:00
if ( replyError ) then
module : log ( " warn " , " sending reply error IQ %s " , inspect ( replyError ) ) ;
module : send ( replyError ) ;
end
2020-07-17 20:19:25 +00:00
end
end ) ;
2020-06-29 23:11:41 +00:00
end
2020-08-14 19:13:57 +00:00
function clearRoomQueueByOccupant ( room , occupant )
room.jibriQueue [ occupant.jid ] = nil ;
end
function addRoomQueueByOccupant ( room , occupant , requestId )
room.jibriQueue [ occupant.jid ] = requestId ;
end
2020-07-13 22:04:48 +00:00
-- receives iq from client currently connected to the room
function on_iq ( event )
2020-07-17 20:19:25 +00:00
local requestId ;
2020-06-29 23:11:41 +00:00
-- Check the type of the incoming stanza to avoid loops:
if event.stanza . attr.type == " error " then
return ; -- We do not want to reply to these, so leave.
end
2020-07-13 22:04:48 +00:00
if event.stanza . attr.to == module : get_host ( ) then
if event.stanza . attr.type == " set " then
2020-07-17 20:19:25 +00:00
local reply = st.reply ( event.stanza ) ;
local replyError = st.error_reply ( event.stanza , ' cancel ' , ' internal-server-error ' , " Queue Server Error " ) ;
2020-07-13 22:04:48 +00:00
local jibriQueue
2020-07-14 20:50:34 +00:00
= event.stanza : get_child ( ' jibri-queue ' , ' http://jitsi.org/protocol/jibri-queue ' ) ;
2020-07-13 22:04:48 +00:00
if jibriQueue then
2020-08-13 21:41:42 +00:00
module : log ( " debug " , " Received Jibri Queue Request: %s " , inspect ( jibriQueue ) ) ;
2020-07-17 20:19:25 +00:00
2020-07-13 22:04:48 +00:00
local roomAddress = jibriQueue.attr . room ;
local room = get_room_from_jid ( room_jid_match_rewrite ( roomAddress ) ) ;
if not room then
2020-07-14 20:50:34 +00:00
module : log ( " warn " , " No room found %s " , roomAddress ) ;
2020-07-13 22:04:48 +00:00
return false ;
end
local from = event.stanza . attr.from ;
local occupant = room : get_occupant_by_real_jid ( from ) ;
if not occupant then
2020-07-14 20:50:34 +00:00
module : log ( " warn " , " No occupant %s found for %s " , from , roomAddress ) ;
2020-07-13 22:04:48 +00:00
return false ;
end
2020-07-14 20:50:34 +00:00
2020-07-17 20:19:25 +00:00
local action = jibriQueue.attr . action ;
if action == ' join ' then
-- join action, so send event out
requestId = uuid_gen ( ) ;
2020-08-13 21:41:42 +00:00
module : log ( " debug " , " Received join queue request for jid %s occupant %s requestId %s " , roomAddress , occupant.jid , requestId ) ;
2020-07-14 20:50:34 +00:00
2020-07-17 20:19:25 +00:00
-- now handle new jibri queue message
2020-08-14 19:13:57 +00:00
addRoomQueueByOccupant ( room , occupant , requestId ) ;
2020-07-17 20:19:25 +00:00
reply : add_child ( st.stanza ( " jibri-queue " , { xmlns = ' http://jitsi.org/protocol/jibri-queue ' , requestId = requestId } ) ) : up ( )
replyError : add_child ( st.stanza ( " jibri-queue " , { xmlns = ' http://jitsi.org/protocol/jibri-queue ' , requestId = requestId } ) ) : up ( )
2020-08-13 21:41:42 +00:00
module : log ( " debug " , " Sending JoinQueue event for jid %s occupant %s reply %s " , roomAddress , occupant.jid , inspect ( reply ) ) ;
2020-07-17 20:19:25 +00:00
sendEvent ( ' JoinQueue ' , roomAddress , occupant.jid , requestId , reply , replyError ) ;
end
if action == ' leave ' then
requestId = jibriQueue.attr . requestId ;
2020-08-13 21:41:42 +00:00
module : log ( " debug " , " Received leave queue request for jid %s occupant %s requestId %s " , roomAddress , occupant.jid , requestId ) ;
2020-07-17 20:19:25 +00:00
-- TODO: check that requestId is the same as cached value
2020-08-14 19:13:57 +00:00
clearRoomQueueByOccupant ( room , occupant ) ;
2020-07-17 20:19:25 +00:00
reply : add_child ( st.stanza ( " jibri-queue " , { xmlns = ' http://jitsi.org/protocol/jibri-queue ' , requestId = requestId } ) ) : up ( )
replyError : add_child ( st.stanza ( " jibri-queue " , { xmlns = ' http://jitsi.org/protocol/jibri-queue ' , requestId = requestId } ) ) : up ( )
2020-08-13 21:41:42 +00:00
module : log ( " debug " , " Sending LeaveQueue event for jid %s occupant %s reply %s " , roomAddress , occupant.jid , inspect ( reply ) ) ;
2020-07-17 20:19:25 +00:00
sendEvent ( ' LeaveQueue ' , roomAddress , occupant.jid , requestId , reply , replyError ) ;
end
2020-07-14 20:50:34 +00:00
else
2020-07-17 20:19:25 +00:00
module : log ( " warn " , " Jibri Queue Stanza missing child %s " , inspect ( event.stanza ) )
2020-07-13 22:04:48 +00:00
end
2020-06-29 23:11:41 +00:00
end
end
return true
end
2020-07-14 20:50:34 +00:00
-- create recorder queue cache for the room
function room_created ( event )
2020-06-29 23:11:41 +00:00
local room = event.room ;
if is_healthcheck_room ( room.jid ) then
return ;
end
2020-07-14 20:50:34 +00:00
room.jibriQueue = { } ;
end
2020-06-29 23:11:41 +00:00
2020-07-14 20:50:34 +00:00
-- Conference ended, clear all queue cache jids
function room_destroyed ( event )
local room = event.room ;
if is_healthcheck_room ( room.jid ) then
return ;
end
for jid , x in pairs ( room.jibriQueue ) do
if x then
2020-07-17 20:19:25 +00:00
sendEvent ( ' LeaveQueue ' , internal_room_jid_match_rewrite ( room.jid ) , jid , x ) ;
2020-07-14 20:50:34 +00:00
end
end
end
-- Occupant left remove it from the queue if it joined the queue
function occupant_leaving ( event )
local room = event.room ;
if is_healthcheck_room ( room.jid ) then
return ;
end
local occupant = event.occupant ;
2020-07-17 20:19:25 +00:00
local requestId = room.jibriQueue [ occupant.jid ] ;
2020-07-14 20:50:34 +00:00
-- check if user has cached queue request
2020-07-17 20:19:25 +00:00
if requestId then
2020-07-14 20:50:34 +00:00
-- remove occupant from queue cache, signal backend
room.jibriQueue [ occupant.jid ] = nil ;
2020-07-17 20:19:25 +00:00
sendEvent ( ' LeaveQueue ' , internal_room_jid_match_rewrite ( room.jid ) , occupant.jid , requestId ) ;
2020-07-14 20:50:34 +00:00
end
2020-06-29 23:11:41 +00:00
end
2020-07-13 22:04:48 +00:00
module : hook ( " iq/host " , on_iq ) ;
2020-06-29 23:11:41 +00:00
-- executed on every host added internally in prosody, including components
function process_host ( host )
if host == muc_component_host then -- the conference muc component
2020-08-13 21:41:42 +00:00
module : log ( " debug " , " Hook to muc events on %s " , host ) ;
2020-06-29 23:11:41 +00:00
local muc_module = module : context ( host ) ;
2020-07-14 20:50:34 +00:00
muc_module : hook ( " muc-room-created " , room_created , - 1 ) ;
-- muc_module:hook("muc-occupant-joined", occupant_joined, -1);
muc_module : hook ( " muc-occupant-pre-leave " , occupant_leaving , - 1 ) ;
muc_module : hook ( " muc-room-destroyed " , room_destroyed , - 1 ) ;
2020-06-29 23:11:41 +00:00
end
end
if prosody.hosts [ muc_component_host ] == nil then
2020-08-13 21:41:42 +00:00
module : log ( " debug " , " No muc component found, will listen for it: %s " , muc_component_host )
2020-06-29 23:11:41 +00:00
-- when a host or component is added
prosody.events . add_handler ( " host-activated " , process_host ) ;
else
process_host ( muc_component_host ) ;
end
module : log ( " info " , " Loading jibri_queue_component " ) ;
2020-06-29 23:20:04 +00:00
--- Verifies room name, domain name with the values in the token
-- @param token the token we received
-- @param room_name the room name
-- @param group name of the group (optional)
-- @param session the session to use for storing token specific fields
-- @return true if values are ok or false otherwise
2020-08-07 17:10:00 +00:00
function verify_token ( token , room_jid , session )
2020-06-29 23:20:04 +00:00
if disableTokenVerification then
return true ;
end
-- if not disableTokenVerification 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
session.auth_token = token ;
2020-08-07 17:10:00 +00:00
local verified , reason , message = token_util : process_and_verify_token ( session ) ;
2020-06-29 23:20:04 +00:00
if not verified then
2020-08-07 17:10:00 +00:00
log ( " warn " , " not a valid token %s: %s " , tostring ( reason ) , tostring ( message ) ) ;
2020-08-12 19:43:34 +00:00
log ( " debug " , " invalid token %s " , token ) ;
2020-06-29 23:20:04 +00:00
return false ;
end
return true ;
end
--- Handles request for updating jibri queue status
-- @param event the http event, holds the request query
-- @return GET response, containing a json with response details
2020-06-29 23:46:15 +00:00
function handle_update_jibri_queue ( event )
2020-07-17 02:48:52 +00:00
local body = json.decode ( event.request . body ) ;
2020-06-29 23:20:04 +00:00
2020-08-13 21:41:42 +00:00
module : log ( " debug " , " Update Jibri Queue Event Received: %s " , inspect ( body ) ) ;
2020-07-20 16:51:07 +00:00
2020-08-14 19:13:57 +00:00
local token = event.request . headers [ " authorization " ] ;
2020-07-17 02:48:52 +00:00
if not token then
2020-08-14 19:13:57 +00:00
token = ' '
else
local prefixStart , prefixEnd = token : find ( " Bearer " ) ;
if prefixStart ~= 1 then
module : log ( " error " , " REST event: Invalid authorization header format. The header must start with the string 'Bearer ' " ) ;
return 403
2020-07-17 02:48:52 +00:00
end
2020-08-14 19:13:57 +00:00
token = token : sub ( prefixEnd + 1 ) ;
2020-07-17 02:48:52 +00:00
end
2020-08-14 19:13:57 +00:00
2020-07-17 02:48:52 +00:00
local user_jid = body [ " participant " ] ;
local roomAddress = body [ " conference " ] ;
local userJWT = body [ " token " ] ;
2020-07-20 16:51:07 +00:00
local action = body [ " action " ] ;
local time = body [ " time " ] ;
local position = body [ " position " ] ;
local requestId = body [ " requestId " ] ;
2020-07-17 02:48:52 +00:00
2020-08-14 19:13:57 +00:00
if not action then
if userJWT then
action = ' token ' ;
else
action = ' info ' ;
end
end
2020-08-07 17:10:00 +00:00
local room_jid = room_jid_match_rewrite ( roomAddress ) ;
if not verify_token ( token , room_jid , { } ) then
2020-08-13 21:41:42 +00:00
log ( " error " , " REST event: Invalid token for room %s to route action %s for requestId %s " , roomAddress , action , requestId ) ;
2020-06-29 23:20:04 +00:00
return { status_code = 403 ; } ;
end
2020-08-07 17:10:00 +00:00
local room = get_room_from_jid ( room_jid ) ;
2020-06-29 23:20:04 +00:00
if ( not room ) then
2020-08-13 21:41:42 +00:00
log ( " error " , " REST event: no room found %s to route action %s for requestId %s " , roomAddress , action , requestId ) ;
2020-06-29 23:20:04 +00:00
return { status_code = 404 ; } ;
end
2020-06-29 23:46:15 +00:00
local occupant = room : get_occupant_by_real_jid ( user_jid ) ;
if not occupant then
2020-08-13 21:41:42 +00:00
log ( " warn " , " REST event: No occupant %s found for %s to route action %s for requestId %s " , user_jid , roomAddress , action , requestId ) ;
2020-06-29 23:20:04 +00:00
return { status_code = 404 ; } ;
end
2020-07-20 16:51:07 +00:00
if not room.jibriQueue [ occupant.jid ] then
2020-08-13 21:41:42 +00:00
log ( " warn " , " REST event: No queue request found for occupant %s in conference %s to route action %s for requestId %s " , occupant.jid , room.jid , action , requestId )
2020-07-20 16:51:07 +00:00
return { status_code = 404 ; } ;
end
2020-06-29 23:20:04 +00:00
2020-07-20 16:51:07 +00:00
if not requestId then
requestId = room.jibriQueue [ occupant.jid ] ;
end
2020-08-14 19:13:57 +00:00
if action == ' token ' and userJWT then
log ( " debug " , " REST event: Token received for occupant %s in conference %s requestId %s, clearing room queue " ) ;
clearRoomQueueByOccupant ( room , occupant ) ;
end
log ( " debug " , " REST event: Sending update for occupant %s in conference %s to route action %s for requestId %s " , occupant.jid , room.jid , action , requestId ) ;
2020-07-20 16:51:07 +00:00
sendIq ( occupant.jid , action , requestId , time , position , userJWT ) ;
2020-06-29 23:20:04 +00:00
return { status_code = 200 ; } ;
end
module : depends ( " http " ) ;
module : provides ( " http " , {
default_path = " / " ;
name = " jibriqueue " ;
route = {
2020-07-20 16:51:07 +00:00
[ " POST /jibriqueue/update " ] = function ( event ) return async_handler_wrapper ( event , handle_update_jibri_queue ) end ;
2020-06-29 23:20:04 +00:00
} ;
} ) ;
2020-08-14 19:13:57 +00:00
module : hook_global ( ' config-reloaded ' , reload_config ) ;