浏览代码

feat(visitors): Propagate moderator role to visitor nodes.

Features that depend on presence and moderator role will start working for visitors (like follow-me).
factor2
damencho 10 个月前
父节点
当前提交
b0ffc2cd69
共有 2 个文件被更改,包括 87 次插入12 次删除
  1. 48
    9
      resources/prosody-plugins/mod_fmuc.lua
  2. 39
    3
      resources/prosody-plugins/mod_visitors.lua

+ 48
- 9
resources/prosody-plugins/mod_fmuc.lua 查看文件

@@ -14,7 +14,8 @@ local jid = require 'util.jid';
14 14
 local st = require 'util.stanza';
15 15
 local new_id = require 'util.id'.medium;
16 16
 local filters = require 'util.filters';
17
-local array = require"util.array";
17
+local array = require 'util.array';
18
+local set = require 'util.set';
18 19
 
19 20
 local util = module:require 'util';
20 21
 local ends_with = util.ends_with;
@@ -69,13 +70,11 @@ end
69 70
 
70 71
 local function send_transcriptions_update(room)
71 72
     -- let's notify main prosody
72
-    local lang_array = array{};
73
+    local lang_array = array();
73 74
     local count = 0;
74 75
 
75 76
     for k, v in pairs(room._transcription_languages) do
76
-        if not lang_array[v] then
77
-            lang_array:push(v);
78
-        end
77
+        lang_array:push(v);
79 78
         count = count + 1;
80 79
     end
81 80
 
@@ -90,7 +89,7 @@ local function send_transcriptions_update(room)
90 89
                          room = jid.join(jid.node(room.jid), muc_domain_prefix..'.'..main_domain) })
91 90
       :tag('transcription-languages', {
92 91
         xmlns = 'jitsi:visitors',
93
-        langs = lang_array:sort():concat(','),
92
+        langs = lang_array:unique():sort():concat(','),
94 93
         count = tostring(count)
95 94
       }):up());
96 95
 end
@@ -127,8 +126,14 @@ end
127 126
 module:hook('muc-occupant-pre-join', function (event)
128 127
     local occupant, room, origin, stanza = event.occupant, event.room, event.origin, event.stanza;
129 128
     local node, host = jid.split(occupant.bare_jid);
129
+    local resource = jid.resource(occupant.nick);
130
+
131
+    if is_admin(occupant.bare_jid) then
132
+        return;
133
+    end
130 134
 
131
-    if prosody.hosts[host] and not is_admin(occupant.bare_jid) then
135
+    if prosody.hosts[host] then
136
+        -- local participants which host is defined in this prosody
132 137
         if room._main_room_lobby_enabled then
133 138
             origin.send(st.error_reply(stanza, 'cancel', 'not-allowed', 'Visitors not allowed while lobby is on!')
134 139
                 :tag('no-visitors-lobby', { xmlns = 'jitsi:visitors' }));
@@ -136,6 +141,9 @@ module:hook('muc-occupant-pre-join', function (event)
136 141
         else
137 142
             occupant.role = 'visitor';
138 143
         end
144
+    elseif room.moderators_list:contains(resource) then
145
+        -- remote participants, host is the main prosody
146
+        occupant.role = 'moderator';
139 147
     end
140 148
 end, 3);
141 149
 
@@ -399,7 +407,7 @@ local function stanza_handler(event)
399 407
     local room = get_room_from_jid(room_jid_match_rewrite(room_jid));
400 408
 
401 409
     if not room then
402
-        module:log('warn', 'No room found %s', room_jid);
410
+        module:log('warn', 'No room found %s in stanza_handler', room_jid);
403 411
         return;
404 412
     end
405 413
 
@@ -546,7 +554,15 @@ module:hook('jicofo-unlock-room', function(e)
546 554
     return true;
547 555
 end);
548 556
 
557
+-- handles incoming iq visitors stanzas
558
+-- connect - sent after sending all main participant's presences
559
+-- disconnect - sent when main room is destroyed or when we receive a 'disconnect-vnode' iq from jicofo
560
+-- update - sent on:
561
+--      * room secret is changed
562
+--      * lobby enabled or disabled
563
+--      * initially before connect to report currently joined moderators
564
+--      * moderator participant joins main room
565
+--      * a participant has been granted moderator rights
549 566
 local function iq_from_main_handler(event)
550 567
     local origin, stanza = event.origin, event.stanza;
551 568
 
@@ -577,7 +593,7 @@ local function iq_from_main_handler(event)
577 593
     local room = get_room_from_jid(room_jid_match_rewrite(room_jid));
578 594
 
579 595
     if not room then
580
-        module:log('warn', 'No room found %s', room_jid);
596
+        module:log('warn', 'No room found %s in iq_from_main_handler for:%s', room_jid, visitors_iq);
581 597
         return;
582 598
     end
583 599
 
@@ -625,6 +641,28 @@ local function iq_from_main_handler(event)
625 641
         room._main_room_lobby_enabled = false;
626 642
     end
627 643
 
644
+    -- read the moderators list
645
+    room.moderators_list = room.moderators_list or set.new();
646
+    local moderators = node:get_child('moderators');
647
+
648
+    if moderators then
649
+        for _, child in ipairs(moderators.tags) do
650
+            if child.name == 'item' then
651
+                room.moderators_list:add(child.attr.epId);
652
+            end
653
+        end
654
+
655
+        -- let's check current occupants roles and promote them if needed
656
+        -- we change only main participants which are not moderators, but participant
657
+        for _, o in room:each_occupant() do
658
+            if not is_admin(o.bare_jid)
659
+                and o.role == 'participant'
660
+                and room.moderators_list:contains(jid.resource(o.nick)) then
661
+                room:set_affiliation(true, o.bare_jid, 'owner');
662
+            end
663
+        end
664
+    end
665
+
628 666
     if fire_jicofo_unlock then
629 667
         -- everything is connected allow participants to join
630 668
         module:fire_event('jicofo-unlock-room', { room = room; fmuc_fired = true; });

+ 39
- 3
resources/prosody-plugins/mod_visitors.lua 查看文件

@@ -58,7 +58,7 @@ local function send_visitors_iq(conference_service, room, type)
58 58
     -- send iq informing the vnode that the connect is done and it will allow visitors to join
59 59
     local iq_id = new_id();
60 60
     sent_iq_cache:set(iq_id, socket.gettime());
61
-    local connect_done = st.iq({
61
+    local visitors_iq = st.iq({
62 62
         type = 'set',
63 63
         to = conference_service,
64 64
         from = module.host,
@@ -71,9 +71,23 @@ local function send_visitors_iq(conference_service, room, type)
71 71
         meetingId = room._data.meetingId,
72 72
         moderatorId = room._data.moderator_id, -- can be used from external modules to set single moderator for meetings
73 73
         createdTimestamp = room.created_timestamp and tostring(room.created_timestamp) or nil
74
-      }):up();
74
+      });
75 75
 
76
-      module:send(connect_done);
76
+    if type == 'update' then
77
+        visitors_iq:tag('moderators', { xmlns = 'jitsi:visitors' });
78
+
79
+        for _, o in room:each_occupant() do
80
+            if not is_admin(o.bare_jid) and o.role == 'moderator' then
81
+                visitors_iq:tag('item', { epId = jid.resource(o.nick) }):up();
82
+            end
83
+        end
84
+
85
+        visitors_iq:up();
86
+    end
87
+
88
+    visitors_iq:up();
89
+
90
+    module:send(visitors_iq);
77 91
 end
78 92
 
79 93
 -- an event received from visitors component, which receives iqs from jicofo
@@ -97,6 +111,9 @@ local function connect_vnode(event)
97 111
 
98 112
     local sent_main_participants = 0;
99 113
 
114
+    -- send update initially so we can report the moderators that will join
115
+    send_visitors_iq(conference_service, room, 'update');
116
+
100 117
     for _, o in room:each_occupant() do
101 118
         if not is_admin(o.bare_jid) then
102 119
             local fmuc_pr = st.clone(o:get_presence());
@@ -258,6 +275,10 @@ process_host_module(main_muc_component_config, function(host_module, host)
258 275
         local user, _, res = jid.split(occupant.nick);
259 276
         -- a main participant we need to update all active visitor nodes
260 277
         for k in pairs(vnodes) do
278
+            if occupant.role == 'moderator' then
279
+                -- first send that the participant is a moderator
280
+                send_visitors_iq(k, room, 'update');
281
+            end
261 282
             local fmuc_pr = st.clone(stanza);
262 283
             fmuc_pr.attr.to = jid.join(user, k, res);
263 284
             fmuc_pr.attr.from = occupant.jid;
@@ -332,6 +353,21 @@ process_host_module(main_muc_component_config, function(host_module, host)
332 353
             end
333 354
         end
334 355
     end, -100); -- we want to run last in order to check is the status code 104
356
+
357
+    host_module:hook('muc-set-affiliation', function (event)
358
+        if event.actor and not is_admin(event.actor) and event.affiliation == 'owner' then
359
+            local room = event.room;
360
+
361
+            if not visitors_nodes[room.jid] then
362
+                return;
363
+            end
364
+            -- we need to update all vnodes
365
+            local vnodes = visitors_nodes[room.jid].nodes;
366
+            for conference_service in pairs(vnodes) do
367
+                send_visitors_iq(conference_service, room, 'update');
368
+            end
369
+        end
370
+    end, -2);
335 371
 end);
336 372
 
337 373
 module:hook('jitsi-lobby-enabled', function(event)

正在加载...
取消
保存