Parcourir la source

fix: Prosody modules - drop unused and duplicate code and drop chatty debug statements (#8027)

* chore: Updates mod_smacks.lua version to latest.

https://hg.prosody.im/prosody-modules/file/db75772afb28/mod_smacks/mod_smacks.lua

* Drop unused modules.

* Update docs.

* Move utility functions away from domain mapper.

* Remove some chatty debug log messages.

* Drops not needed patch for mod_websocket.
master
Дамян Минков il y a 5 ans
Parent
révision
9f65ae52f1
Aucun compte lié à l'adresse e-mail de l'auteur

+ 0
- 5
resources/prosody-plugins/mod_jibri_queue.lua Voir le fichier

@@ -1,5 +0,0 @@
1
-local jibri_queue_component
2
-    = module:get_option_string(
3
-        "jibri_queue_component", "jibriqueue"..module.host);
4
-
5
-module:add_identity("component", "jibri-queue", jibri_queue_component);

+ 0
- 545
resources/prosody-plugins/mod_jibri_queue_component.lua Voir le fichier

@@ -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);

+ 10
- 72
resources/prosody-plugins/mod_muc_domain_mapper.lua Voir le fichier

@@ -7,99 +7,32 @@ local jid = require "util.jid";
7 7
 
8 8
 local filters = require "util.filters";
9 9
 
10
-local muc_domain_prefix = module:get_option_string("muc_mapper_domain_prefix", "conference");
11
-
12 10
 local muc_domain_base = module:get_option_string("muc_mapper_domain_base");
13 11
 if not muc_domain_base then
14 12
     module:log("warn", "No 'muc_mapper_domain_base' option set, disabling muc_mapper plugin inactive");
15 13
     return
16 14
 end
17 15
 
18
-local muc_domain = module:get_option_string("muc_mapper_domain", muc_domain_prefix.."."..muc_domain_base);
19
-
20
-local escaped_muc_domain_base = muc_domain_base:gsub("%p", "%%%1");
21
-local escaped_muc_domain_prefix = muc_domain_prefix:gsub("%p", "%%%1");
22
-local target_subdomain_pattern = "^"..escaped_muc_domain_prefix..".([^%.]+)%."..escaped_muc_domain_base;
23
-
24
-local roomless_iqs = {};
25
-
26
-if not muc_domain then
27
-    module:log("warn", "No 'muc_mapper_domain' option set, disabling muc_mapper plugin inactive");
28
-    return
29
-end
30
-
31
-
32
-local function match_rewrite_to_jid(room_jid, stanza)
33
-    local node, host, resource = jid.split(room_jid);
34
-    local target_subdomain = host and host:match(target_subdomain_pattern);
35
-    if not target_subdomain then
36
-        module:log("debug", "No need to rewrite out 'to' %s", room_jid);
37
-        return room_jid;
38
-    end
39
-    -- Ok, rewrite room_jid  address to new format
40
-    local new_node, new_host, new_resource;
41
-    if node then
42
-        new_node, new_host, new_resource = "["..target_subdomain.."]"..node, muc_domain, resource;
43
-    else
44
-        module:log("debug", "No room name provided so rewriting only host 'to' %s", room_jid);
45
-        new_host, new_resource = muc_domain, resource;
46
-
47
-        if (stanza.attr and stanza.attr.id) then
48
-            roomless_iqs[stanza.attr.id] = stanza.attr.to;
49
-        end
50
-    end
51
-    room_jid = jid.join(new_node, new_host, new_resource);
52
-    module:log("debug", "Rewrote to %s", room_jid);
53
-    return room_jid
54
-end
55
-
56
-local function match_rewrite_from_jid(room_jid, stanza)
57
-    local node, host, resource = jid.split(room_jid);
58
-    if host ~= muc_domain or not node then
59
-        module:log("debug", "No need to rewrite %s (not from the MUC host) %s, %s", room_jid, stanza.attr.id, roomless_iqs[stanza.attr.id]);
60
-
61
-        if (stanza.attr and stanza.attr.id and roomless_iqs[stanza.attr.id]) then
62
-            local result = roomless_iqs[stanza.attr.id];
63
-            roomless_iqs[stanza.attr.id] = nil;
64
-            return result;
65
-        end
66
-
67
-        return room_jid;
68
-    end
69
-    local target_subdomain, target_node = node:match("^%[([^%]]+)%](.+)$");
70
-    if not (target_node and target_subdomain) then
71
-        module:log("debug", "Not rewriting... unexpected node format: %s", node);
72
-        return room_jid;
73
-    end
74
-    -- Ok, rewrite room_jid address to pretty format
75
-    local new_node, new_host, new_resource = target_node, muc_domain_prefix..".".. target_subdomain.."."..muc_domain_base, resource;
76
-    room_jid = jid.join(new_node, new_host, new_resource);
77
-    module:log("debug", "Rewrote to %s", room_jid);
78
-    return room_jid
79
-end
80
-
16
+local util = module:require "util";
17
+local room_jid_match_rewrite = util.room_jid_match_rewrite;
18
+local internal_room_jid_match_rewrite = util.internal_room_jid_match_rewrite;
81 19
 
82 20
 -- We must filter stanzas in order to hook in to all incoming and outgoing messaging which skips the stanza routers
83 21
 function filter_stanza(stanza)
84 22
     if stanza.name == "message" or stanza.name == "iq" or stanza.name == "presence" then
85
-        module:log("debug", "Filtering stanza type %s  to %s from %s",stanza.name,stanza.attr.to,stanza.attr.from);
23
+        -- module:log("debug", "Filtering stanza type %s  to %s from %s",stanza.name,stanza.attr.to,stanza.attr.from);
86 24
         if stanza.name == "iq" then
87 25
             local conf = stanza:get_child('conference')
88 26
             if conf then
89
-                module:log("debug", "Filtering stanza conference %s to %s from %s",conf.attr.room,stanza.attr.to,stanza.attr.from);
90
-                conf.attr.room = match_rewrite_to_jid(conf.attr.room, stanza)
27
+                -- module:log("debug", "Filtering stanza conference %s to %s from %s",conf.attr.room,stanza.attr.to,stanza.attr.from);
28
+                conf.attr.room = room_jid_match_rewrite(conf.attr.room, stanza)
91 29
             end
92 30
         end
93 31
         if stanza.attr.to then
94
-            stanza.attr.to = match_rewrite_to_jid(stanza.attr.to, stanza)
32
+            stanza.attr.to = room_jid_match_rewrite(stanza.attr.to, stanza)
95 33
         end
96 34
         if stanza.attr.from then
97
-            stanza.attr.from = match_rewrite_from_jid(stanza.attr.from, stanza)
35
+            stanza.attr.from = internal_room_jid_match_rewrite(stanza.attr.from, stanza)
98 36
         end
99 37
     end
100 38
     return stanza;
@@ -107,7 +40,6 @@ end
107 40
 
108 41
 function filter_session(session)
109 42
     module:log("warn", "Session filters applied");
110 43
     filters.add_filter(session, "stanzas/out", filter_stanza);
111 44
 end
112 45
 
@@ -128,14 +60,14 @@ end
128 60
 local function outgoing_stanza_rewriter(event)
129 61
     local stanza = event.stanza;
130 62
     if stanza.attr.to then
131
-        stanza.attr.to = match_rewrite_to_jid(stanza.attr.to, stanza)
63
+        stanza.attr.to = room_jid_match_rewrite(stanza.attr.to, stanza)
132 64
     end
133 65
 end
134 66
 
135 67
 local function incoming_stanza_rewriter(event)
136 68
     local stanza = event.stanza;
137 69
     if stanza.attr.from then
138
-        stanza.attr.from = match_rewrite_from_jid(stanza.attr.from, stanza)
70
+        stanza.attr.from = internal_room_jid_match_rewrite(stanza.attr.from, stanza)
139 71
     end
140 72
 end
141 73
 

+ 42
- 21
resources/prosody-plugins/mod_smacks.lua Voir le fichier

@@ -17,7 +17,7 @@ local cache = dep.softreq("util.cache");	-- only available in prosody 0.10+
17 17
 local uuid_generate = require "util.uuid".generate;
18 18
 local jid = require "util.jid";
19 19
 
20
-local t_insert, t_remove = table.insert, table.remove;
20
+local t_remove = table.remove;
21 21
 local math_min = math.min;
22 22
 local math_max = math.max;
23 23
 local os_time = os.time;
@@ -26,6 +26,7 @@ local add_filter = require "util.filters".add_filter;
26 26
 local timer = require "util.timer";
27 27
 local datetime = require "util.datetime";
28 28
 
29
+local xmlns_mam2 = "urn:xmpp:mam:2";
29 30
 local xmlns_sm2 = "urn:xmpp:sm:2";
30 31
 local xmlns_sm3 = "urn:xmpp:sm:3";
31 32
 local xmlns_errors = "urn:ietf:params:xml:ns:xmpp-stanzas";
@@ -34,11 +35,11 @@ local xmlns_delay = "urn:xmpp:delay";
34 35
 local sm2_attr = { xmlns = xmlns_sm2 };
35 36
 local sm3_attr = { xmlns = xmlns_sm3 };
36 37
 
37
-local resume_timeout = module:get_option_number("smacks_hibernation_time", 300);
38
+local resume_timeout = module:get_option_number("smacks_hibernation_time", 600);
38 39
 local s2s_smacks = module:get_option_boolean("smacks_enabled_s2s", false);
39 40
 local s2s_resend = module:get_option_boolean("smacks_s2s_resend", false);
40 41
 local max_unacked_stanzas = module:get_option_number("smacks_max_unacked_stanzas", 0);
41
-local delayed_ack_timeout = module:get_option_number("smacks_max_ack_delay", 60);
42
+local delayed_ack_timeout = module:get_option_number("smacks_max_ack_delay", 30);
42 43
 local max_hibernated_sessions = module:get_option_number("smacks_max_hibernated_sessions", 10);
43 44
 local max_old_sessions = module:get_option_number("smacks_max_old_sessions", 10);
44 45
 local core_process_stanza = prosody.core_process_stanza;
@@ -200,8 +201,15 @@ local function request_ack_if_needed(session, force, reason)
200 201
 end
201 202
 
202 203
 local function outgoing_stanza_filter(stanza, session)
203
-	local is_stanza = stanza.attr and not stanza.attr.xmlns and not stanza.name:find":";
204
-	if is_stanza and not stanza._cached then -- Stanza in default stream namespace
204
+	-- XXX: Normally you wouldn't have to check the xmlns for a stanza as it's
205
+	-- supposed to be nil.
206
+	-- However, when using mod_smacks with mod_websocket, then mod_websocket's
207
+	-- stanzas/out filter can get called before this one and adds the xmlns.
208
+	local is_stanza = stanza.attr and
209
+		(not stanza.attr.xmlns or stanza.attr.xmlns == 'jabber:client')
210
+		and not stanza.name:find":";
211
+
212
+	if is_stanza and not stanza._cached then
205 213
 		local queue = session.outgoing_stanza_queue;
206 214
 		local cached_stanza = st.clone(stanza);
207 215
 		cached_stanza._cached = true;
@@ -400,12 +408,14 @@ local function handle_unacked_stanzas(session)
400 408
 		session.outgoing_stanza_queue = {};
401 409
 		for i=1,#queue do
402 410
 			if not module:fire_event("delivery/failure", { session = session, stanza = queue[i] }) then
403
-				local reply = st.reply(queue[i]);
404
-				if reply.attr.to ~= session.full_jid then
405
-					reply.attr.type = "error";
406
-					reply:tag("error", error_attr)
407
-						:tag("recipient-unavailable", {xmlns = "urn:ietf:params:xml:ns:xmpp-stanzas"});
408
-					core_process_stanza(session, reply);
411
+				if queue[i].attr.type ~= "error" then
412
+					local reply = st.reply(queue[i]);
413
+					if reply.attr.to ~= session.full_jid then
414
+						reply.attr.type = "error";
415
+						reply:tag("error", error_attr)
416
+							:tag("recipient-unavailable", {xmlns = "urn:ietf:params:xml:ns:xmpp-stanzas"});
417
+						core_process_stanza(session, reply);
418
+					end
409 419
 				end
410 420
 			end
411 421
 		end
@@ -413,37 +423,46 @@ local function handle_unacked_stanzas(session)
413 423
 end
414 424
 
415 425
 -- don't send delivery errors for messages which will be delivered by mam later on
426
+-- check if stanza was archived --> this will allow us to send back errors for stanzas not archived
427
+-- because the user configured the server to do so ("no-archive"-setting for one special contact for example)
428
+local function get_stanza_id(stanza, by_jid)
429
+	for tag in stanza:childtags("stanza-id", "urn:xmpp:sid:0") do
430
+		if tag.attr.by == by_jid then
431
+			return tag.attr.id;
432
+		end
433
+	end
434
+	return nil;
435
+end
416 436
 module:hook("delivery/failure", function(event)
417 437
 	local session, stanza = event.session, event.stanza;
418 438
 	-- Only deal with authenticated (c2s) sessions
419 439
 	if session.username then
420 440
 		if stanza.name == "message" and stanza.attr.xmlns == nil and
421 441
 				( stanza.attr.type == "chat" or ( stanza.attr.type or "normal" ) == "normal" ) then
442
+			-- don't store messages in offline store if they are mam results
443
+			local mam_result = stanza:get_child("result", xmlns_mam2);
444
+			if mam_result ~= nil then
445
+				return true;		-- stanza already "handled", don't send an error and don't add it to offline storage
446
+			end
422 447
 			-- do nothing here for normal messages and don't send out "message delivery errors",
423 448
 			-- because messages are already in MAM at this point (no need to frighten users)
424
-			if session.mam_requested and stanza._was_archived then
449
+			local stanza_id = get_stanza_id(stanza, jid.bare(session.full_jid));
450
+			if session.mam_requested and stanza_id ~= nil then
451
+				session.log("debug", "mod_smacks delivery/failure returning true for mam-handled stanza: mam-archive-id=%s", tostring(stanza_id));
425 452
 				return true;		-- stanza handled, don't send an error
426 453
 			end
427 454
 			-- store message in offline store, if this client does not use mam *and* was the last client online
428 455
 			local sessions = prosody.hosts[module.host].sessions[session.username] and
429 456
 					prosody.hosts[module.host].sessions[session.username].sessions or nil;
430 457
 			if sessions and next(sessions) == session.resource and next(sessions, session.resource) == nil then
431
-				module:fire_event("message/offline/handle", { origin = session, stanza = stanza } );
432
-				return true;		-- stanza handled, don't send an error
458
+				local ok = module:fire_event("message/offline/handle", { origin = session, stanza = stanza } );
459
+				session.log("debug", "mod_smacks delivery/failuere returning %s for offline-handled stanza", tostring(ok));
460
+				return ok;			-- if stanza was handled, don't send an error
433 461
 			end
434 462
 		end
435 463
 	end
436 464
 end);
437 465
 
438
-module:hook("archive-message-added", function(event)
439
-	local session, stanza, for_user, stanza_id  = event.origin, event.stanza, event.for_user, event.id;
440
-	if session then session.log("debug", "Marking stanza as archived, archive_id: %s, stanza: %s", tostring(stanza_id), tostring(stanza:top_tag())); end
441
-	if not session then module:log("debug", "Marking stanza as archived in unknown session, archive_id: %s, stanza: %s", tostring(stanza_id), tostring(stanza:top_tag())); end
442
-	stanza._was_archived = true;
443
-end);
444
-
445 466
 module:hook("pre-resource-unbind", function (event)
446 467
 	local session, err = event.session, event.error;
447 468
 	if session.smacks then

+ 1
- 2
resources/prosody-plugins/mod_speakerstats_component.lua Voir le fichier

@@ -93,8 +93,7 @@ end
93 93
 -- saves start time if it is new dominat speaker
94 94
 -- or calculates and accumulates time of speaking
95 95
 function SpeakerStats:setDominantSpeaker(isNowDominantSpeaker)
96
-    log("debug",
97
-        "set isDominant %s for %s", tostring(isNowDominantSpeaker), self.nick);
96
+    -- log("debug", "set isDominant %s for %s", tostring(isNowDominantSpeaker), self.nick);
98 97
 
99 98
     if not self:isDominantSpeaker() and isNowDominantSpeaker then
100 99
         self._dominantSpeakerStart = socket.gettime()*1000;

+ 0
- 101
resources/prosody-plugins/mod_websocket_smacks.patch Voir le fichier

@@ -1,101 +0,0 @@
1
---- mod_websocket.lua
2
-+++ mod_websocket.lua
3
-@@ -163,34 +163,34 @@ function handle_request(event)
4
- 		return 403;
5
- 	end
6
- 
7
--	local function websocket_close(code, message)
8
-+	local function websocket_close(conn, code, message)
9
- 		conn:write(build_close(code, message));
10
- 		conn:close();
11
- 	end
12
- 
13
- 	local dataBuffer;
14
--	local function handle_frame(frame)
15
-+	local function handle_frame(conn, frame)
16
- 		local opcode = frame.opcode;
17
- 		local length = frame.length;
18
- 		module:log("debug", "Websocket received frame: opcode=%0x, %i bytes", frame.opcode, #frame.data);
19
- 
20
- 		-- Error cases
21
- 		if frame.RSV1 or frame.RSV2 or frame.RSV3 then -- Reserved bits non zero
22
--			websocket_close(1002, "Reserved bits not zero");
23
-+			websocket_close(conn, 1002, "Reserved bits not zero");
24
- 			return false;
25
- 		end
26
- 
27
- 		if opcode == 0x8 then -- close frame
28
- 			if length == 1 then
29
--				websocket_close(1002, "Close frame with payload, but too short for status code");
30
-+				websocket_close(conn, 1002, "Close frame with payload, but too short for status code");
31
- 				return false;
32
- 			elseif length >= 2 then
33
- 				local status_code = parse_close(frame.data)
34
- 				if status_code < 1000 then
35
--					websocket_close(1002, "Closed with invalid status code");
36
-+					websocket_close(conn, 1002, "Closed with invalid status code");
37
- 					return false;
38
- 				elseif ((status_code > 1003 and status_code < 1007) or status_code > 1011) and status_code < 3000 then
39
--					websocket_close(1002, "Closed with reserved status code");
40
-+					websocket_close(conn, 1002, "Closed with reserved status code");
41
- 					return false;
42
- 				end
43
- 			end
44
-@@ -198,28 +198,28 @@ function handle_request(event)
45
- 
46
- 		if opcode >= 0x8 then
47
- 			if length > 125 then -- Control frame with too much payload
48
--				websocket_close(1002, "Payload too large");
49
-+				websocket_close(conn, 1002, "Payload too large");
50
- 				return false;
51
- 			end
52
- 
53
- 			if not frame.FIN then -- Fragmented control frame
54
--				websocket_close(1002, "Fragmented control frame");
55
-+				websocket_close(conn, 1002, "Fragmented control frame");
56
- 				return false;
57
- 			end
58
- 		end
59
- 
60
- 		if (opcode > 0x2 and opcode < 0x8) or (opcode > 0xA) then
61
--			websocket_close(1002, "Reserved opcode");
62
-+			websocket_close(conn, 1002, "Reserved opcode");
63
- 			return false;
64
- 		end
65
- 
66
- 		if opcode == 0x0 and not dataBuffer then
67
--			websocket_close(1002, "Unexpected continuation frame");
68
-+			websocket_close(conn, 1002, "Unexpected continuation frame");
69
- 			return false;
70
- 		end
71
- 
72
- 		if (opcode == 0x1 or opcode == 0x2) and dataBuffer then
73
--			websocket_close(1002, "Continuation frame expected");
74
-+			websocket_close(conn, 1002, "Continuation frame expected");
75
- 			return false;
76
- 		end
77
- 
78
-@@ -229,11 +229,11 @@ function handle_request(event)
79
- 		elseif opcode == 0x1 then -- Text frame
80
- 			dataBuffer = {frame.data};
81
- 		elseif opcode == 0x2 then -- Binary frame
82
--			websocket_close(1003, "Only text frames are supported");
83
-+			websocket_close(conn, 1003, "Only text frames are supported");
84
- 			return;
85
- 		elseif opcode == 0x8 then -- Close request
86
--			websocket_close(1000, "Goodbye");
87
--			return;
88
-+			websocket_close(conn, 1000, "Goodbye");
89
-+			return "";
90
- 		elseif opcode == 0x9 then -- Ping frame
91
- 			frame.opcode = 0xA;
92
- 			conn:write(build_frame(frame));
93
-@@ -276,7 +276,7 @@ function handle_request(event)
94
- 
95
- 		while frame do
96
- 			frameBuffer = frameBuffer:sub(length + 1);
97
--			local result = handle_frame(frame);
98
-+			local result = handle_frame(session.conn, frame);
99
- 			if not result then return; end
100
- 			cache[#cache+1] = filter_open_close(result);
101
- 			frame, length = parse_frame(frameBuffer);

+ 38
- 10
resources/prosody-plugins/util.lib.lua Voir le fichier

@@ -22,11 +22,15 @@ local muc_domain = module:get_option_string(
22 22
 local escaped_muc_domain_base = muc_domain_base:gsub("%p", "%%%1");
23 23
 local escaped_muc_domain_prefix = muc_domain_prefix:gsub("%p", "%%%1");
24 24
 -- The pattern used to extract the target subdomain
25
+-- (e.g. extract 'foo' from 'conference.foo.example.com')
25 26
 local target_subdomain_pattern
26 27
     = "^"..escaped_muc_domain_prefix..".([^%.]+)%."..escaped_muc_domain_base;
27 28
 
29
+-- table to store all incoming iqs without roomname in it, like discoinfo to the muc compoent
30
+local roomless_iqs = {};
31
+
28 32
 -- Utility function to split room JID to include room name and subdomain
33
+-- (e.g. from room1@conference.foo.example.com/res returns (room1, example.com, res, foo))
29 34
 local function room_jid_split_subdomain(room_jid)
30 35
     local node, host, resource = jid.split(room_jid);
31 36
     local target_subdomain = host and host:match(target_subdomain_pattern);
@@ -34,39 +38,57 @@ local function room_jid_split_subdomain(room_jid)
34 38
 end
35 39
 
36 40
 --- Utility function to check and convert a room JID from
41
+--- virtual room1@conference.foo.example.com to real [foo]room1@conference.example.com
37 42
 -- @param room_jid the room jid to match and rewrite if needed
38
-local function room_jid_match_rewrite(room_jid)
39
-    local node, host, resource, target_subdomain = room_jid_split_subdomain(room_jid);
43
+-- @param stanza the stanza
44
+-- @return returns room jid [foo]room1@conference.example.com when it has subdomain
45
+-- otherwise room1@conference.example.com(the room_jid value untouched)
46
+local function room_jid_match_rewrite(room_jid, stanza)
47
+    local node, _, resource, target_subdomain = room_jid_split_subdomain(room_jid);
40 48
     if not target_subdomain then
41
-        module:log("debug", "No need to rewrite out 'to' %s", room_jid);
49
+        -- module:log("debug", "No need to rewrite out 'to' %s", room_jid);
42 50
         return room_jid;
43 51
     end
44 52
     -- Ok, rewrite room_jid  address to new format
45
-    local new_node, new_host, new_resource
46
-        = "["..target_subdomain.."]"..node, muc_domain, resource;
53
+    local new_node, new_host, new_resource;
54
+    if node then
55
+        new_node, new_host, new_resource = "["..target_subdomain.."]"..node, muc_domain, resource;
56
+    else
57
+        -- module:log("debug", "No room name provided so rewriting only host 'to' %s", room_jid);
58
+        new_host, new_resource = muc_domain, resource;
59
+
60
+        if (stanza and stanza.attr and stanza.attr.id) then
61
+            roomless_iqs[stanza.attr.id] = stanza.attr.to;
62
+        end
63
+    end
47 64
     room_jid = jid.join(new_node, new_host, new_resource);
48
-    module:log("debug", "Rewrote to %s", room_jid);
65
+    -- module:log("debug", "Rewrote to %s", room_jid);
49 66
     return room_jid
50 67
 end
51 68
 
52
-local function internal_room_jid_match_rewrite(room_jid)
69
+-- Utility function to check and convert a room JID from real [foo]room1@muc.example.com to virtual room1@muc.foo.example.com
70
+local function internal_room_jid_match_rewrite(room_jid, stanza)
53 71
     local node, host, resource = jid.split(room_jid);
54 72
     if host ~= muc_domain or not node then
55
-        module:log("debug", "No need to rewrite %s (not from the MUC host)", room_jid);
73
+        -- module:log("debug", "No need to rewrite %s (not from the MUC host)", room_jid);
74
+
75
+        if (stanza and stanza.attr and stanza.attr.id and roomless_iqs[stanza.attr.id]) then
76
+            local result = roomless_iqs[stanza.attr.id];
77
+            roomless_iqs[stanza.attr.id] = nil;
78
+            return result;
79
+        end
80
+
56 81
         return room_jid;
57 82
     end
58 83
     local target_subdomain, target_node = node:match("^%[([^%]]+)%](.+)$");
59 84
     if not (target_node and target_subdomain) then
60
-        module:log("debug", "Not rewriting... unexpected node format: %s", node);
85
+        -- module:log("debug", "Not rewriting... unexpected node format: %s", node);
61 86
         return room_jid;
62 87
     end
63 88
     -- Ok, rewrite room_jid address to pretty format
64 89
     local new_node, new_host, new_resource = target_node, muc_domain_prefix..".".. target_subdomain.."."..muc_domain_base, resource;
65 90
     room_jid = jid.join(new_node, new_host, new_resource);
66
-    module:log("debug", "Rewrote to %s", room_jid);
91
+    -- module:log("debug", "Rewrote to %s", room_jid);
67 92
     return room_jid
68 93
 end
69 94
 
@@ -216,8 +238,8 @@ function is_healthcheck_room(room_jid)
216 238
     return false;
217 239
 end
218 240
 
241
+--- Utility function to make an http get request and
242
+--- retry @param retry number of times
219 243
 -- @param url endpoint to be called
220 244
 -- @param retry nr of retries, if retry is
221 245
 -- nil there will be no retries

Chargement…
Annuler
Enregistrer