Преглед изворни кода

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
 local st = require 'util.stanza';
14
 local st = require 'util.stanza';
15
 local new_id = require 'util.id'.medium;
15
 local new_id = require 'util.id'.medium;
16
 local filters = require 'util.filters';
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
 local util = module:require 'util';
20
 local util = module:require 'util';
20
 local ends_with = util.ends_with;
21
 local ends_with = util.ends_with;
69
 
70
 
70
 local function send_transcriptions_update(room)
71
 local function send_transcriptions_update(room)
71
     -- let's notify main prosody
72
     -- let's notify main prosody
72
-    local lang_array = array{};
73
+    local lang_array = array();
73
     local count = 0;
74
     local count = 0;
74
 
75
 
75
     for k, v in pairs(room._transcription_languages) do
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
         count = count + 1;
78
         count = count + 1;
80
     end
79
     end
81
 
80
 
90
                          room = jid.join(jid.node(room.jid), muc_domain_prefix..'.'..main_domain) })
89
                          room = jid.join(jid.node(room.jid), muc_domain_prefix..'.'..main_domain) })
91
       :tag('transcription-languages', {
90
       :tag('transcription-languages', {
92
         xmlns = 'jitsi:visitors',
91
         xmlns = 'jitsi:visitors',
93
-        langs = lang_array:sort():concat(','),
92
+        langs = lang_array:unique():sort():concat(','),
94
         count = tostring(count)
93
         count = tostring(count)
95
       }):up());
94
       }):up());
96
 end
95
 end
127
 module:hook('muc-occupant-pre-join', function (event)
126
 module:hook('muc-occupant-pre-join', function (event)
128
     local occupant, room, origin, stanza = event.occupant, event.room, event.origin, event.stanza;
127
     local occupant, room, origin, stanza = event.occupant, event.room, event.origin, event.stanza;
129
     local node, host = jid.split(occupant.bare_jid);
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
         if room._main_room_lobby_enabled then
137
         if room._main_room_lobby_enabled then
133
             origin.send(st.error_reply(stanza, 'cancel', 'not-allowed', 'Visitors not allowed while lobby is on!')
138
             origin.send(st.error_reply(stanza, 'cancel', 'not-allowed', 'Visitors not allowed while lobby is on!')
134
                 :tag('no-visitors-lobby', { xmlns = 'jitsi:visitors' }));
139
                 :tag('no-visitors-lobby', { xmlns = 'jitsi:visitors' }));
136
         else
141
         else
137
             occupant.role = 'visitor';
142
             occupant.role = 'visitor';
138
         end
143
         end
144
+    elseif room.moderators_list:contains(resource) then
145
+        -- remote participants, host is the main prosody
146
+        occupant.role = 'moderator';
139
     end
147
     end
140
 end, 3);
148
 end, 3);
141
 
149
 
399
     local room = get_room_from_jid(room_jid_match_rewrite(room_jid));
407
     local room = get_room_from_jid(room_jid_match_rewrite(room_jid));
400
 
408
 
401
     if not room then
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
         return;
411
         return;
404
     end
412
     end
405
 
413
 
546
     return true;
554
     return true;
547
 end);
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
 local function iq_from_main_handler(event)
566
 local function iq_from_main_handler(event)
550
     local origin, stanza = event.origin, event.stanza;
567
     local origin, stanza = event.origin, event.stanza;
551
 
568
 
577
     local room = get_room_from_jid(room_jid_match_rewrite(room_jid));
593
     local room = get_room_from_jid(room_jid_match_rewrite(room_jid));
578
 
594
 
579
     if not room then
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
         return;
597
         return;
582
     end
598
     end
583
 
599
 
625
         room._main_room_lobby_enabled = false;
641
         room._main_room_lobby_enabled = false;
626
     end
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
     if fire_jicofo_unlock then
666
     if fire_jicofo_unlock then
629
         -- everything is connected allow participants to join
667
         -- everything is connected allow participants to join
630
         module:fire_event('jicofo-unlock-room', { room = room; fmuc_fired = true; });
668
         module:fire_event('jicofo-unlock-room', { room = room; fmuc_fired = true; });

+ 39
- 3
resources/prosody-plugins/mod_visitors.lua Прегледај датотеку

58
     -- send iq informing the vnode that the connect is done and it will allow visitors to join
58
     -- send iq informing the vnode that the connect is done and it will allow visitors to join
59
     local iq_id = new_id();
59
     local iq_id = new_id();
60
     sent_iq_cache:set(iq_id, socket.gettime());
60
     sent_iq_cache:set(iq_id, socket.gettime());
61
-    local connect_done = st.iq({
61
+    local visitors_iq = st.iq({
62
         type = 'set',
62
         type = 'set',
63
         to = conference_service,
63
         to = conference_service,
64
         from = module.host,
64
         from = module.host,
71
         meetingId = room._data.meetingId,
71
         meetingId = room._data.meetingId,
72
         moderatorId = room._data.moderator_id, -- can be used from external modules to set single moderator for meetings
72
         moderatorId = room._data.moderator_id, -- can be used from external modules to set single moderator for meetings
73
         createdTimestamp = room.created_timestamp and tostring(room.created_timestamp) or nil
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
 end
91
 end
78
 
92
 
79
 -- an event received from visitors component, which receives iqs from jicofo
93
 -- an event received from visitors component, which receives iqs from jicofo
97
 
111
 
98
     local sent_main_participants = 0;
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
     for _, o in room:each_occupant() do
117
     for _, o in room:each_occupant() do
101
         if not is_admin(o.bare_jid) then
118
         if not is_admin(o.bare_jid) then
102
             local fmuc_pr = st.clone(o:get_presence());
119
             local fmuc_pr = st.clone(o:get_presence());
258
         local user, _, res = jid.split(occupant.nick);
275
         local user, _, res = jid.split(occupant.nick);
259
         -- a main participant we need to update all active visitor nodes
276
         -- a main participant we need to update all active visitor nodes
260
         for k in pairs(vnodes) do
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
             local fmuc_pr = st.clone(stanza);
282
             local fmuc_pr = st.clone(stanza);
262
             fmuc_pr.attr.to = jid.join(user, k, res);
283
             fmuc_pr.attr.to = jid.join(user, k, res);
263
             fmuc_pr.attr.from = occupant.jid;
284
             fmuc_pr.attr.from = occupant.jid;
332
             end
353
             end
333
         end
354
         end
334
     end, -100); -- we want to run last in order to check is the status code 104
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
 end);
371
 end);
336
 
372
 
337
 module:hook('jitsi-lobby-enabled', function(event)
373
 module:hook('jitsi-lobby-enabled', function(event)

Loading…
Откажи
Сачувај