|
@@ -1,559 +0,0 @@
|
1
|
|
-local st = require "util.stanza";
|
2
|
|
-local jid = require "util.jid";
|
3
|
|
-local http = require "net.http";
|
4
|
|
-local json = require "cjson";
|
5
|
|
-local inspect = require('inspect');
|
6
|
|
-local socket = require "socket";
|
7
|
|
-local uuid_gen = require "util.uuid".generate;
|
8
|
|
-local jwt = require "luajwtjitsi";
|
9
|
|
-local it = require "util.iterators";
|
10
|
|
-local neturl = require "net.url";
|
11
|
|
-local parse = neturl.parseQuery;
|
12
|
|
-
|
13
|
|
-local get_room_from_jid = module:require "util".get_room_from_jid;
|
14
|
|
-local room_jid_match_rewrite = module:require "util".room_jid_match_rewrite;
|
15
|
|
-local is_healthcheck_room = module:require "util".is_healthcheck_room;
|
16
|
|
-local room_jid_split_subdomain = module:require "util".room_jid_split_subdomain;
|
17
|
|
-local internal_room_jid_match_rewrite = module:require "util".internal_room_jid_match_rewrite;
|
18
|
|
-local async_handler_wrapper = module:require "util".async_handler_wrapper;
|
19
|
|
-
|
20
|
|
-local parentHostName = string.gmatch(tostring(module.host), "%w+.(%w.+)")();
|
21
|
|
-if parentHostName == nil then
|
22
|
|
- log("error", "Failed to start - unable to get parent hostname");
|
23
|
|
- return;
|
24
|
|
-end
|
25
|
|
-
|
26
|
|
-local parentCtx = module:context(parentHostName);
|
27
|
|
-if parentCtx == nil then
|
28
|
|
- log("error",
|
29
|
|
- "Failed to start - unable to get parent context for host: %s",
|
30
|
|
- tostring(parentHostName));
|
31
|
|
- return;
|
32
|
|
-end
|
33
|
|
-local token_util = module:require "token/util".new(parentCtx);
|
34
|
|
-
|
35
|
|
-local ASAPKeyServer;
|
36
|
|
-local ASAPKeyPath;
|
37
|
|
-local ASAPKeyId;
|
38
|
|
-local ASAPIssuer;
|
39
|
|
-local ASAPAudience;
|
40
|
|
-local ASAPAcceptedIssuers;
|
41
|
|
-local ASAPAcceptedAudiences;
|
42
|
|
-local ASAPTTL;
|
43
|
|
-local ASAPTTL_THRESHOLD;
|
44
|
|
-local ASAPKey;
|
45
|
|
-local JibriRegion;
|
46
|
|
-local disableTokenVerification;
|
47
|
|
-local muc_component_host;
|
48
|
|
-local external_api_url;
|
49
|
|
-local jwtKeyCacheSize;
|
50
|
|
-local jwtKeyCache;
|
51
|
|
-
|
52
|
|
-local function load_config()
|
53
|
|
- ASAPKeyServer = module:get_option_string("asap_key_server");
|
54
|
|
-
|
55
|
|
- if ASAPKeyServer then
|
56
|
|
- module:log("debug", "ASAP Public Key URL %s", ASAPKeyServer);
|
57
|
|
- token_util:set_asap_key_server(ASAPKeyServer);
|
58
|
|
- end
|
59
|
|
-
|
60
|
|
- ASAPKeyPath
|
61
|
|
- = module:get_option_string("asap_key_path", '/etc/prosody/certs/asap.key');
|
62
|
|
-
|
63
|
|
- ASAPKeyId
|
64
|
|
- = module:get_option_string("asap_key_id", 'jitsi');
|
65
|
|
-
|
66
|
|
- ASAPIssuer
|
67
|
|
- = module:get_option_string("asap_issuer", 'jitsi');
|
68
|
|
-
|
69
|
|
- ASAPAudience
|
70
|
|
- = module:get_option_string("asap_audience", 'jibri-queue');
|
71
|
|
-
|
72
|
|
- ASAPAcceptedIssuers
|
73
|
|
- = module:get_option_array('asap_accepted_issuers',{'jibri-queue'});
|
74
|
|
- module:log("debug", "ASAP Accepted Issuers %s", ASAPAcceptedIssuers);
|
75
|
|
- token_util:set_asap_accepted_issuers(ASAPAcceptedIssuers);
|
76
|
|
-
|
77
|
|
- ASAPAcceptedAudiences
|
78
|
|
- = module:get_option_array('asap_accepted_audiences',{'*'});
|
79
|
|
- module:log("debug", "ASAP Accepted Audiences %s", ASAPAcceptedAudiences);
|
80
|
|
- token_util:set_asap_accepted_audiences(ASAPAcceptedAudiences);
|
81
|
|
-
|
82
|
|
- -- do not require room to be set on tokens for jibri queue
|
83
|
|
- token_util:set_asap_require_room_claim(false);
|
84
|
|
-
|
85
|
|
- ASAPTTL
|
86
|
|
- = module:get_option_number("asap_ttl", 3600);
|
87
|
|
-
|
88
|
|
- ASAPTTL_THRESHOLD
|
89
|
|
- = module:get_option_number("asap_ttl_threshold", 600);
|
90
|
|
-
|
91
|
|
- queueServiceURL
|
92
|
|
- = module:get_option_string("jibri_queue_url");
|
93
|
|
-
|
94
|
|
- JibriRegion
|
95
|
|
- = module:get_option_string("jibri_region", 'default');
|
96
|
|
-
|
97
|
|
- -- option to enable/disable token verifications
|
98
|
|
- disableTokenVerification
|
99
|
|
- = module:get_option_boolean("disable_jibri_queue_token_verification", false);
|
100
|
|
-
|
101
|
|
- muc_component_host
|
102
|
|
- = module:get_option_string("muc_component");
|
103
|
|
-
|
104
|
|
- external_api_url = module:get_option_string("external_api_url",tostring(parentHostName));
|
105
|
|
- module:log("debug", "External advertised API URL", external_api_url);
|
106
|
|
-
|
107
|
|
-
|
108
|
|
- -- TODO: Figure out a less arbitrary default cache size.
|
109
|
|
- jwtKeyCacheSize
|
110
|
|
- = module:get_option_number("jwt_pubkey_cache_size", 128);
|
111
|
|
- jwtKeyCache = require"util.cache".new(jwtKeyCacheSize);
|
112
|
|
-
|
113
|
|
- if queueServiceURL == nil then
|
114
|
|
- log("error", "No jibri_queue_url specified. No service to contact!");
|
115
|
|
- return;
|
116
|
|
- end
|
117
|
|
-
|
118
|
|
- if muc_component_host == nil then
|
119
|
|
- log("error", "No muc_component specified. No muc to operate on for jibri queue!");
|
120
|
|
- return;
|
121
|
|
- end
|
122
|
|
-
|
123
|
|
- -- Read ASAP key once on module startup
|
124
|
|
- local f = io.open(ASAPKeyPath, "r");
|
125
|
|
- if f then
|
126
|
|
- ASAPKey = f:read("*all");
|
127
|
|
- f:close();
|
128
|
|
- if not ASAPKey then
|
129
|
|
- module:log("warn", "No ASAP Key read from %s, disabling jibri queue component plugin", ASAPKeyPath);
|
130
|
|
- return
|
131
|
|
- end
|
132
|
|
- else
|
133
|
|
- module:log("warn", "Error reading ASAP Key %s, disabling jibri queue component plugin", ASAPKeyPath);
|
134
|
|
- return
|
135
|
|
- end
|
136
|
|
-
|
137
|
|
- return true;
|
138
|
|
-end
|
139
|
|
-
|
140
|
|
-local function reload_config()
|
141
|
|
- module:log("info", "Reloading configuration for jibri queue component");
|
142
|
|
- local config_success = load_config();
|
143
|
|
-
|
144
|
|
- -- clear ASAP public key cache on config reload
|
145
|
|
- token_util:clear_asap_cache();
|
146
|
|
-
|
147
|
|
- if not config_success then
|
148
|
|
- log("error", "Unsuccessful reconfiguration, jibri queue component may misbehave");
|
149
|
|
- end
|
150
|
|
-end
|
151
|
|
-
|
152
|
|
-local config_success = load_config();
|
153
|
|
-
|
154
|
|
-if not config_success then
|
155
|
|
- log("error", "Unsuccessful configuration step, jibri queue component disabled")
|
156
|
|
- return;
|
157
|
|
-end
|
158
|
|
-
|
159
|
|
-
|
160
|
|
-local http_headers = {
|
161
|
|
- ["User-Agent"] = "Prosody ("..prosody.version.."; "..prosody.platform..")",
|
162
|
|
- ["Content-Type"] = "application/json"
|
163
|
|
-};
|
164
|
|
-
|
165
|
|
-local have_async = pcall(require, "util.async");
|
166
|
|
-if not have_async then
|
167
|
|
- module:log("warn", "conference duration will not work with Prosody version 0.10 or less.");
|
168
|
|
- return;
|
169
|
|
-end
|
170
|
|
-
|
171
|
|
-
|
172
|
|
-log("info", "Starting jibri queue handling for %s", muc_component_host);
|
173
|
|
-
|
174
|
|
-local function round(num, numDecimalPlaces)
|
175
|
|
- local mult = 10^(numDecimalPlaces or 0)
|
176
|
|
- return math.floor(num * mult + 0.5) / mult
|
177
|
|
-end
|
178
|
|
-
|
179
|
|
-local function generateToken(audience)
|
180
|
|
- audience = audience or ASAPAudience
|
181
|
|
- local t = os.time()
|
182
|
|
- local err
|
183
|
|
- local exp_key = 'asap_exp.'..audience
|
184
|
|
- local token_key = 'asap_token.'..audience
|
185
|
|
- local exp = jwtKeyCache:get(exp_key)
|
186
|
|
- local token = jwtKeyCache:get(token_key)
|
187
|
|
-
|
188
|
|
- --if we find a token and it isn't too far from expiry, then use it
|
189
|
|
- if token ~= nil and exp ~= nil then
|
190
|
|
- exp = tonumber(exp)
|
191
|
|
- if (exp - t) > ASAPTTL_THRESHOLD then
|
192
|
|
- return token
|
193
|
|
- end
|
194
|
|
- end
|
195
|
|
-
|
196
|
|
- --expiry is the current time plus TTL
|
197
|
|
- exp = t + ASAPTTL
|
198
|
|
- local payload = {
|
199
|
|
- iss = ASAPIssuer,
|
200
|
|
- aud = audience,
|
201
|
|
- nbf = t,
|
202
|
|
- exp = exp,
|
203
|
|
- }
|
204
|
|
-
|
205
|
|
- -- encode
|
206
|
|
- local alg = "RS256"
|
207
|
|
- token, err = jwt.encode(payload, ASAPKey, alg, {kid = ASAPKeyId})
|
208
|
|
- if not err then
|
209
|
|
- token = 'Bearer '..token
|
210
|
|
- jwtKeyCache:set(exp_key,exp)
|
211
|
|
- jwtKeyCache:set(token_key,token)
|
212
|
|
- return token
|
213
|
|
- else
|
214
|
|
- return ''
|
215
|
|
- end
|
216
|
|
-end
|
217
|
|
-
|
218
|
|
-local function sendIq(participant,action,requestId,time,position,token)
|
219
|
|
- local iqId = uuid_gen();
|
220
|
|
- local from = module:get_host();
|
221
|
|
- local outStanza = st.iq({type = 'set', from = from, to = participant, id = iqId}):tag("jibri-queue",
|
222
|
|
- { xmlns = 'http://jitsi.org/protocol/jibri-queue', requestId = requestId, action = action });
|
223
|
|
-
|
224
|
|
- if token then
|
225
|
|
- outStanza:tag("token"):text(token):up()
|
226
|
|
- end
|
227
|
|
- if time then
|
228
|
|
- outStanza:tag("time"):text(tostring(time)):up()
|
229
|
|
- end
|
230
|
|
- if position then
|
231
|
|
- outStanza:tag("position"):text(tostring(position)):up()
|
232
|
|
- end
|
233
|
|
-
|
234
|
|
- module:send(outStanza);
|
235
|
|
-end
|
236
|
|
-
|
237
|
|
-local function cb(content_, code_, response_, request_)
|
238
|
|
- if code_ == 200 or code_ == 204 then
|
239
|
|
- module:log("debug", "URL Callback: Code %s, Content %s, Request (host %s, path %s, body %s), Response: %s",
|
240
|
|
- code_, content_, request_.host, request_.path, inspect(request_.body), inspect(response_));
|
241
|
|
- else
|
242
|
|
- module:log("warn", "URL Callback non successful: Code %s, Content %s, Request (%s), Response: %s",
|
243
|
|
- code_, content_, inspect(request_), inspect(response_));
|
244
|
|
- end
|
245
|
|
-end
|
246
|
|
-
|
247
|
|
-local function sendEvent(type,room_address,participant,requestId,replyIq,replyError)
|
248
|
|
- local event_ts = round(socket.gettime()*1000);
|
249
|
|
- local node, host, resource, target_subdomain = room_jid_split_subdomain(room_address);
|
250
|
|
- local room_param = '';
|
251
|
|
- if target_subdomain then
|
252
|
|
- room_param = target_subdomain..'/'..node;
|
253
|
|
- else
|
254
|
|
- room_param = node;
|
255
|
|
- end
|
256
|
|
-
|
257
|
|
- local out_event = {
|
258
|
|
- ["conference"] = room_address,
|
259
|
|
- ["roomParam"] = room_param,
|
260
|
|
- ["eventType"] = type,
|
261
|
|
- ["participant"] = participant,
|
262
|
|
- ["externalApiUrl"] = external_api_url.."/jibriqueue/update",
|
263
|
|
- ["requestId"] = requestId,
|
264
|
|
- ["region"] = JibriRegion,
|
265
|
|
- }
|
266
|
|
- module:log("debug","Sending event %s",inspect(out_event));
|
267
|
|
-
|
268
|
|
- local headers = http_headers or {}
|
269
|
|
- headers['Authorization'] = generateToken()
|
270
|
|
-
|
271
|
|
- module:log("debug","Sending headers %s",inspect(headers));
|
272
|
|
- local requestURL = queueServiceURL.."/job/recording"
|
273
|
|
- if type=="LeaveQueue" then
|
274
|
|
- requestURL = requestURL .."/cancel"
|
275
|
|
- end
|
276
|
|
- local request = http.request(requestURL, {
|
277
|
|
- headers = headers,
|
278
|
|
- method = "POST",
|
279
|
|
- body = json.encode(out_event)
|
280
|
|
- }, function (content_, code_, response_, request_)
|
281
|
|
- if code_ == 200 or code_ == 204 then
|
282
|
|
- module:log("debug", "URL Callback: Code %s, Content %s, Request (host %s, path %s, body %s), Response: %s",
|
283
|
|
- code_, content_, request_.host, request_.path, inspect(request_.body), inspect(response_));
|
284
|
|
- if (replyIq) then
|
285
|
|
- module:log("debug", "sending reply IQ %s",inspect(replyIq));
|
286
|
|
- module:send(replyIq);
|
287
|
|
- end
|
288
|
|
- else
|
289
|
|
- module:log("warn", "URL Callback non successful: Code %s, Content %s, Request (%s), Response: %s",
|
290
|
|
- code_, content_, inspect(request_), inspect(response_));
|
291
|
|
- if (replyError) then
|
292
|
|
- module:log("warn", "sending reply error IQ %s",inspect(replyError));
|
293
|
|
- module:send(replyError);
|
294
|
|
- end
|
295
|
|
- end
|
296
|
|
- end);
|
297
|
|
-end
|
298
|
|
-
|
299
|
|
-function clearRoomQueueByOccupant(room, occupant)
|
300
|
|
- room.jibriQueue[occupant.jid] = nil;
|
301
|
|
-end
|
302
|
|
-
|
303
|
|
-function addRoomQueueByOccupant(room, occupant, requestId)
|
304
|
|
- room.jibriQueue[occupant.jid] = requestId;
|
305
|
|
-end
|
306
|
|
-
|
307
|
|
-function on_iq(event)
|
308
|
|
- local requestId;
|
309
|
|
- -- Check the type of the incoming stanza to avoid loops:
|
310
|
|
- if event.stanza.attr.type == "error" then
|
311
|
|
- return; -- We do not want to reply to these, so leave.
|
312
|
|
- end
|
313
|
|
- if event.stanza.attr.to == module:get_host() then
|
314
|
|
- if event.stanza.attr.type == "set" then
|
315
|
|
- local reply = st.reply(event.stanza);
|
316
|
|
- local replyError = st.error_reply(event.stanza,'cancel','internal-server-error',"Queue Server Error");
|
317
|
|
-
|
318
|
|
- local jibriQueue
|
319
|
|
- = event.stanza:get_child('jibri-queue', 'http://jitsi.org/protocol/jibri-queue');
|
320
|
|
- if jibriQueue then
|
321
|
|
- module:log("debug", "Received Jibri Queue Request: %s ",inspect(jibriQueue));
|
322
|
|
-
|
323
|
|
- local roomAddress = jibriQueue.attr.room;
|
324
|
|
- local room = get_room_from_jid(room_jid_match_rewrite(roomAddress));
|
325
|
|
-
|
326
|
|
- if not room then
|
327
|
|
- module:log("warn", "No room found %s", roomAddress);
|
328
|
|
- return false;
|
329
|
|
- end
|
330
|
|
-
|
331
|
|
- local from = event.stanza.attr.from;
|
332
|
|
-
|
333
|
|
- local occupant = room:get_occupant_by_real_jid(from);
|
334
|
|
- if not occupant then
|
335
|
|
- module:log("warn", "No occupant %s found for %s", from, roomAddress);
|
336
|
|
- return false;
|
337
|
|
- end
|
338
|
|
-
|
339
|
|
- local action = jibriQueue.attr.action;
|
340
|
|
- if action == 'join' then
|
341
|
|
- -- join action, so send event out
|
342
|
|
- requestId = uuid_gen();
|
343
|
|
- module:log("debug","Received join queue request for jid %s occupant %s requestId %s",roomAddress,occupant.jid,requestId);
|
344
|
|
-
|
345
|
|
- -- now handle new jibri queue message
|
346
|
|
- addRoomQueueByOccupant(room, occupant, requestId);
|
347
|
|
- reply:add_child(st.stanza("jibri-queue", { xmlns = 'http://jitsi.org/protocol/jibri-queue', requestId = requestId})):up()
|
348
|
|
- replyError:add_child(st.stanza("jibri-queue", { xmlns = 'http://jitsi.org/protocol/jibri-queue', requestId = requestId})):up()
|
349
|
|
-
|
350
|
|
- module:log("debug","Sending JoinQueue event for jid %s occupant %s reply %s",roomAddress,occupant.jid,inspect(reply));
|
351
|
|
- sendEvent('JoinQueue',roomAddress,occupant.jid,requestId,reply,replyError);
|
352
|
|
- end
|
353
|
|
- if action == 'leave' then
|
354
|
|
- requestId = jibriQueue.attr.requestId;
|
355
|
|
- module:log("debug","Received leave queue request for jid %s occupant %s requestId %s",roomAddress,occupant.jid,requestId);
|
356
|
|
-
|
357
|
|
- -- TODO: check that requestId is the same as cached value
|
358
|
|
- clearRoomQueueByOccupant(room, occupant);
|
359
|
|
- reply:add_child(st.stanza("jibri-queue", { xmlns = 'http://jitsi.org/protocol/jibri-queue', requestId = requestId})):up()
|
360
|
|
- replyError:add_child(st.stanza("jibri-queue", { xmlns = 'http://jitsi.org/protocol/jibri-queue', requestId = requestId})):up()
|
361
|
|
-
|
362
|
|
- module:log("debug","Sending LeaveQueue event for jid %s occupant %s reply %s",roomAddress,occupant.jid,inspect(reply));
|
363
|
|
- sendEvent('LeaveQueue',roomAddress,occupant.jid,requestId,reply,replyError);
|
364
|
|
- end
|
365
|
|
- else
|
366
|
|
- module:log("warn","Jibri Queue Stanza missing child %s",inspect(event.stanza))
|
367
|
|
- end
|
368
|
|
- end
|
369
|
|
- end
|
370
|
|
- return true
|
371
|
|
-end
|
372
|
|
-
|
373
|
|
-function room_created(event)
|
374
|
|
- local room = event.room;
|
375
|
|
-
|
376
|
|
- if is_healthcheck_room(room.jid) then
|
377
|
|
- return;
|
378
|
|
- end
|
379
|
|
-
|
380
|
|
- room.jibriQueue = {};
|
381
|
|
-end
|
382
|
|
-
|
383
|
|
-function room_destroyed(event)
|
384
|
|
- local room = event.room;
|
385
|
|
-
|
386
|
|
- if is_healthcheck_room(room.jid) then
|
387
|
|
- return;
|
388
|
|
- end
|
389
|
|
- for jid, x in pairs(room.jibriQueue) do
|
390
|
|
- if x then
|
391
|
|
- sendEvent('LeaveQueue',internal_room_jid_match_rewrite(room.jid),jid,x);
|
392
|
|
- end
|
393
|
|
- end
|
394
|
|
-end
|
395
|
|
-
|
396
|
|
-function occupant_leaving(event)
|
397
|
|
- local room = event.room;
|
398
|
|
-
|
399
|
|
- if is_healthcheck_room(room.jid) then
|
400
|
|
- return;
|
401
|
|
- end
|
402
|
|
-
|
403
|
|
- local occupant = event.occupant;
|
404
|
|
- local requestId = room.jibriQueue[occupant.jid];
|
405
|
|
- -- check if user has cached queue request
|
406
|
|
- if requestId then
|
407
|
|
- -- remove occupant from queue cache, signal backend
|
408
|
|
- room.jibriQueue[occupant.jid] = nil;
|
409
|
|
- sendEvent('LeaveQueue',internal_room_jid_match_rewrite(room.jid),occupant.jid,requestId);
|
410
|
|
- end
|
411
|
|
-end
|
412
|
|
-
|
413
|
|
-module:hook("iq/host", on_iq);
|
414
|
|
-
|
415
|
|
-function process_host(host)
|
416
|
|
- if host == muc_component_host then -- the conference muc component
|
417
|
|
- module:log("debug","Hook to muc events on %s", host);
|
418
|
|
-
|
419
|
|
- local muc_module = module:context(host);
|
420
|
|
- muc_module:hook("muc-room-created", room_created, -1);
|
421
|
|
- -- muc_module:hook("muc-occupant-joined", occupant_joined, -1);
|
422
|
|
- muc_module:hook("muc-occupant-pre-leave", occupant_leaving, -1);
|
423
|
|
- muc_module:hook("muc-room-destroyed", room_destroyed, -1);
|
424
|
|
- end
|
425
|
|
-end
|
426
|
|
-
|
427
|
|
-if prosody.hosts[muc_component_host] == nil then
|
428
|
|
- module:log("debug","No muc component found, will listen for it: %s", muc_component_host)
|
429
|
|
-
|
430
|
|
- -- when a host or component is added
|
431
|
|
- prosody.events.add_handler("host-activated", process_host);
|
432
|
|
-else
|
433
|
|
- process_host(muc_component_host);
|
434
|
|
-end
|
435
|
|
-
|
436
|
|
-module:log("info", "Loading jibri_queue_component");
|
437
|
|
-
|
438
|
|
---- Verifies room name, domain name with the values in the token
|
439
|
|
-function verify_token(token, room_jid, session)
|
440
|
|
- if disableTokenVerification then
|
441
|
|
- return true;
|
442
|
|
- end
|
443
|
|
-
|
444
|
|
- -- if not disableTokenVerification and we do not have token
|
445
|
|
- -- stop here, cause the main virtual host can have guest access enabled
|
446
|
|
- -- (allowEmptyToken = true) and we will allow access to rooms info without
|
447
|
|
- -- a token
|
448
|
|
- if token == nil then
|
449
|
|
- log("warn", "no token provided");
|
450
|
|
- return false;
|
451
|
|
- end
|
452
|
|
-
|
453
|
|
- session.auth_token = token;
|
454
|
|
- local verified, reason, message = token_util:process_and_verify_token(session);
|
455
|
|
- if not verified then
|
456
|
|
- log("warn", "not a valid token %s: %s", tostring(reason), tostring(message));
|
457
|
|
- log("debug", "invalid token %s", token);
|
458
|
|
- return false;
|
459
|
|
- end
|
460
|
|
-
|
461
|
|
- return true;
|
462
|
|
-end
|
463
|
|
-
|
464
|
|
---- Handles request for updating jibri queue status
|
465
|
|
-function handle_update_jibri_queue(event)
|
466
|
|
- local body = json.decode(event.request.body);
|
467
|
|
-
|
468
|
|
- module:log("debug","Update Jibri Queue Event Received: %s",inspect(body));
|
469
|
|
-
|
470
|
|
- local token = event.request.headers["authorization"];
|
471
|
|
- if not token then
|
472
|
|
- token = ''
|
473
|
|
- else
|
474
|
|
- local prefixStart, prefixEnd = token:find("Bearer ");
|
475
|
|
- if prefixStart ~= 1 then
|
476
|
|
- module:log("error", "REST event: Invalid authorization header format. The header must start with the string 'Bearer '");
|
477
|
|
- return { status_code = 403; };
|
478
|
|
- end
|
479
|
|
- token = token:sub(prefixEnd + 1);
|
480
|
|
- end
|
481
|
|
-
|
482
|
|
- local user_jid = body["participant"];
|
483
|
|
- local roomAddress = body["conference"];
|
484
|
|
- local userJWT = body["token"];
|
485
|
|
- local action = body["action"];
|
486
|
|
- local time = body["time"];
|
487
|
|
- local position = body["position"];
|
488
|
|
- local requestId = body["requestId"];
|
489
|
|
-
|
490
|
|
- if not action then
|
491
|
|
- if userJWT then
|
492
|
|
- action = 'token';
|
493
|
|
- else
|
494
|
|
- action = 'info';
|
495
|
|
- end
|
496
|
|
- end
|
497
|
|
-
|
498
|
|
- local room_jid = room_jid_match_rewrite(roomAddress);
|
499
|
|
-
|
500
|
|
- if not verify_token(token, room_jid, {}) then
|
501
|
|
- log("error", "REST event: Invalid token for room %s to route action %s for requestId %s", roomAddress, action, requestId);
|
502
|
|
- return { status_code = 403; };
|
503
|
|
- end
|
504
|
|
-
|
505
|
|
- local room = get_room_from_jid(room_jid);
|
506
|
|
- if (not room) then
|
507
|
|
- log("error", "REST event: no room found %s to route action %s for requestId %s", roomAddress, action, requestId);
|
508
|
|
- return { status_code = 404; };
|
509
|
|
- end
|
510
|
|
-
|
511
|
|
- local occupant = room:get_occupant_by_real_jid(user_jid);
|
512
|
|
- if not occupant then
|
513
|
|
- log("warn", "REST event: No occupant %s found for %s to route action %s for requestId %s", user_jid, roomAddress, action, requestId);
|
514
|
|
- return { status_code = 404; };
|
515
|
|
- end
|
516
|
|
-
|
517
|
|
- if not room.jibriQueue[occupant.jid] then
|
518
|
|
- 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)
|
519
|
|
- return { status_code = 404; };
|
520
|
|
- end
|
521
|
|
-
|
522
|
|
- if not requestId then
|
523
|
|
- requestId = room.jibriQueue[occupant.jid];
|
524
|
|
- end
|
525
|
|
-
|
526
|
|
- if action == 'token' and userJWT then
|
527
|
|
- log("debug", "REST event: Token received for occupant %s in conference %s requestId %s, clearing room queue");
|
528
|
|
- clearRoomQueueByOccupant(room, occupant);
|
529
|
|
- end
|
530
|
|
-
|
531
|
|
- 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);
|
532
|
|
- sendIq(occupant.jid,action,requestId,time,position,userJWT);
|
533
|
|
- return { status_code = 200; };
|
534
|
|
-end
|
535
|
|
-
|
536
|
|
-module:depends("http");
|
537
|
|
-module:provides("http", {
|
538
|
|
- default_path = "/";
|
539
|
|
- name = "jibriqueue";
|
540
|
|
- route = {
|
541
|
|
- ["POST /jibriqueue/update"] = function (event) return async_handler_wrapper(event,handle_update_jibri_queue) end;
|
542
|
|
- };
|
543
|
|
-});
|
544
|
|
-
|
545
|
|
-module:hook_global('config-reloaded', reload_config);
|