mirror of
https://git.lapiole.org/dani/ansible-roles.git
synced 2025-08-02 23:05:41 +02:00
Update to 2025-06-16 16:00
This commit is contained in:
@@ -10,25 +10,36 @@
|
||||
-- Component "metadata.jitmeet.example.com" "room_metadata_component"
|
||||
-- muc_component = "conference.jitmeet.example.com"
|
||||
-- breakout_rooms_component = "breakout.jitmeet.example.com"
|
||||
|
||||
local filters = require 'util.filters';
|
||||
local jid_node = require 'util.jid'.node;
|
||||
local json = require 'cjson.safe';
|
||||
local st = require 'util.stanza';
|
||||
local jid = require 'util.jid';
|
||||
|
||||
local util = module:require 'util';
|
||||
local is_admin = util.is_admin;
|
||||
local is_healthcheck_room = util.is_healthcheck_room;
|
||||
local get_room_from_jid = util.get_room_from_jid;
|
||||
local room_jid_match_rewrite = util.room_jid_match_rewrite;
|
||||
local internal_room_jid_match_rewrite = util.internal_room_jid_match_rewrite;
|
||||
local process_host_module = util.process_host_module;
|
||||
local table_shallow_copy = util.table_shallow_copy;
|
||||
local table_add = util.table_add;
|
||||
|
||||
local MUC_NS = 'http://jabber.org/protocol/muc';
|
||||
local COMPONENT_IDENTITY_TYPE = 'room_metadata';
|
||||
local FORM_KEY = 'muc#roominfo_jitsimetadata';
|
||||
|
||||
local muc_component_host = module:get_option_string('muc_component');
|
||||
|
||||
if muc_component_host == nil then
|
||||
module:log("error", "No muc_component specified. No muc to operate on!");
|
||||
module:log('error', 'No muc_component specified. No muc to operate on!');
|
||||
return;
|
||||
end
|
||||
|
||||
local muc_domain_base = module:get_option_string('muc_mapper_domain_base');
|
||||
if not muc_domain_base then
|
||||
module:log('warn', 'No muc_domain_base option set.');
|
||||
return;
|
||||
end
|
||||
|
||||
@@ -40,10 +51,13 @@ local main_muc_module;
|
||||
|
||||
-- Utility functions
|
||||
|
||||
function getMetadataJSON(room)
|
||||
-- Returns json string with the metadata for the room.
|
||||
-- @param room The room object.
|
||||
-- @param metadata Optional metadata to use instead of the room's jitsiMetadata.
|
||||
function getMetadataJSON(room, metadata)
|
||||
local res, error = json.encode({
|
||||
type = COMPONENT_IDENTITY_TYPE,
|
||||
metadata = room.jitsiMetadata or {}
|
||||
metadata = metadata or room.jitsiMetadata or {}
|
||||
});
|
||||
|
||||
if not res then
|
||||
@@ -53,28 +67,52 @@ function getMetadataJSON(room)
|
||||
return res;
|
||||
end
|
||||
|
||||
-- Putting the information on the config form / disco-info allows us to save
|
||||
-- an extra message to users who join later.
|
||||
function getFormData(room)
|
||||
return {
|
||||
name = FORM_KEY;
|
||||
type = 'text-multi';
|
||||
label = 'Room metadata';
|
||||
value = getMetadataJSON(room);
|
||||
};
|
||||
end
|
||||
|
||||
function broadcastMetadata(room)
|
||||
local json_msg = getMetadataJSON(room);
|
||||
|
||||
if not json_msg then
|
||||
return;
|
||||
end
|
||||
|
||||
for _, occupant in room:each_occupant() do
|
||||
send_json_msg(occupant.jid, internal_room_jid_match_rewrite(room.jid), json_msg)
|
||||
send_metadata(occupant, room, json_msg)
|
||||
end
|
||||
end
|
||||
|
||||
function send_json_msg(to_jid, room_jid, json_msg)
|
||||
local stanza = st.message({ from = module.host; to = to_jid; })
|
||||
:tag('json-message', { xmlns = 'http://jitsi.org/jitmeet', room = room_jid }):text(json_msg):up();
|
||||
function send_metadata(occupant, room, json_msg)
|
||||
if not json_msg or is_admin(occupant.bare_jid) then
|
||||
local metadata_to_send = room.jitsiMetadata or {};
|
||||
|
||||
-- we want to send the main meeting participants only to jicofo
|
||||
if is_admin(occupant.bare_jid) then
|
||||
local participants = {};
|
||||
|
||||
if room._data.mainMeetingParticipants then
|
||||
table_add(participants, room._data.mainMeetingParticipants);
|
||||
end
|
||||
|
||||
if room._data.moderator_id then
|
||||
table.insert(participants, room._data.moderator_id);
|
||||
end
|
||||
|
||||
if room._data.moderators then
|
||||
table_add(participants, room._data.moderators);
|
||||
end
|
||||
|
||||
if #participants > 0 then
|
||||
metadata_to_send = table_shallow_copy(metadata_to_send);
|
||||
metadata_to_send.mainMeetingParticipants = participants;
|
||||
end
|
||||
end
|
||||
|
||||
json_msg = getMetadataJSON(room, metadata_to_send);
|
||||
end
|
||||
|
||||
local stanza = st.message({ from = module.host; to = occupant.jid; })
|
||||
:tag('json-message', {
|
||||
xmlns = 'http://jitsi.org/jitmeet',
|
||||
room = internal_room_jid_match_rewrite(room.jid)
|
||||
}):text(json_msg):up();
|
||||
module:send(stanza);
|
||||
end
|
||||
|
||||
@@ -84,12 +122,14 @@ function room_created(event)
|
||||
local room = event.room;
|
||||
|
||||
if is_healthcheck_room(room.jid) then
|
||||
return ;
|
||||
return;
|
||||
end
|
||||
|
||||
if not room.jitsiMetadata then
|
||||
room.jitsiMetadata = {};
|
||||
end
|
||||
|
||||
room.sent_initial_metadata = {};
|
||||
end
|
||||
|
||||
function on_message(event)
|
||||
@@ -129,11 +169,6 @@ function on_message(event)
|
||||
return false;
|
||||
end
|
||||
|
||||
if occupant.role ~= 'moderator' then
|
||||
module:log('warn', 'Occupant %s is not moderator and not allowed this operation for %s', from, room.jid);
|
||||
return false;
|
||||
end
|
||||
|
||||
local jsonData, error = json.decode(messageText);
|
||||
if jsonData == nil then -- invalid JSON
|
||||
module:log("error", "Invalid JSON message: %s error:%s", messageText, error);
|
||||
@@ -145,6 +180,19 @@ function on_message(event)
|
||||
return false;
|
||||
end
|
||||
|
||||
if occupant.role ~= 'moderator' then
|
||||
-- will return a non nil filtered data to use, if it is nil, it is not allowed
|
||||
local res = module:context(muc_domain_base):fire_event('jitsi-metadata-allow-moderation',
|
||||
{ room = room; actor = occupant; key = jsonData.key ; data = jsonData.data; session = session; });
|
||||
|
||||
if not res then
|
||||
module:log('warn', 'Occupant %s is not moderator and not allowed this operation for %s', from, room.jid);
|
||||
return false;
|
||||
end
|
||||
|
||||
jsonData.data = res;
|
||||
end
|
||||
|
||||
room.jitsiMetadata[jsonData.key] = jsonData.data;
|
||||
|
||||
broadcastMetadata(room);
|
||||
@@ -169,21 +217,39 @@ function process_main_muc_loaded(main_muc, host_module)
|
||||
|
||||
host_module:hook("muc-room-created", room_created, -1);
|
||||
|
||||
host_module:hook('muc-disco#info', function (event)
|
||||
local room = event.room;
|
||||
|
||||
table.insert(event.form, getFormData(room));
|
||||
end);
|
||||
|
||||
host_module:hook("muc-config-form", function(event)
|
||||
local room = event.room;
|
||||
|
||||
table.insert(event.form, getFormData(room));
|
||||
end);
|
||||
-- The room metadata was updated internally (from another module).
|
||||
host_module:hook("room-metadata-changed", function(event)
|
||||
broadcastMetadata(event.room);
|
||||
end);
|
||||
|
||||
-- TODO: Once clients update to read/write metadata for startMuted policy we can drop this
|
||||
-- this is to convert presence settings from old clients to metadata
|
||||
host_module:hook('muc-broadcast-presence', function (event)
|
||||
local actor, occupant, room, stanza, x = event.actor, event.occupant, event.room, event.stanza, event.x;
|
||||
|
||||
if is_healthcheck_room(room.jid) or occupant.role ~= 'moderator' then
|
||||
return;
|
||||
end
|
||||
|
||||
local startMuted = stanza:get_child('startmuted', 'http://jitsi.org/jitmeet/start-muted');
|
||||
|
||||
if not startMuted then
|
||||
return;
|
||||
end
|
||||
|
||||
if not room.jitsiMetadata then
|
||||
room.jitsiMetadata = {};
|
||||
end
|
||||
|
||||
local startMutedMetadata = room.jitsiMetadata.startMuted or {};
|
||||
|
||||
startMutedMetadata.audio = startMuted.attr.audio == 'true';
|
||||
startMutedMetadata.video = startMuted.attr.video == 'true';
|
||||
|
||||
room.jitsiMetadata.startMuted = startMutedMetadata;
|
||||
|
||||
host_module:fire_event('room-metadata-changed', { room = room; });
|
||||
end);
|
||||
end
|
||||
|
||||
-- process or waits to process the main muc component
|
||||
@@ -208,18 +274,6 @@ function process_breakout_muc_loaded(breakout_muc, host_module)
|
||||
module:log("info", "Hook to muc events on %s", breakout_rooms_component_host);
|
||||
|
||||
host_module:hook("muc-room-created", room_created, -1);
|
||||
|
||||
host_module:hook('muc-disco#info', function (event)
|
||||
local room = event.room;
|
||||
|
||||
table.insert(event.form, getFormData(room));
|
||||
end);
|
||||
|
||||
host_module:hook("muc-config-form", function(event)
|
||||
local room = event.room;
|
||||
|
||||
table.insert(event.form, getFormData(room));
|
||||
end);
|
||||
end
|
||||
|
||||
if breakout_rooms_component_host then
|
||||
@@ -238,3 +292,53 @@ if breakout_rooms_component_host then
|
||||
end
|
||||
end);
|
||||
end
|
||||
|
||||
-- Send a message update for metadata before sending the first self presence
|
||||
function filter_stanza(stanza, session)
|
||||
if not stanza.attr or not stanza.attr.to or stanza.name ~= 'presence'
|
||||
or stanza.attr.type == 'unavailable' or ends_with(stanza.attr.from, '/focus') then
|
||||
return stanza;
|
||||
end
|
||||
|
||||
local bare_to = jid.bare(stanza.attr.to);
|
||||
local muc_x = stanza:get_child('x', MUC_NS..'#user');
|
||||
if not muc_x or not presence_check_status(muc_x, '110') then
|
||||
return stanza;
|
||||
end
|
||||
|
||||
local room = get_room_from_jid(room_jid_match_rewrite(jid.bare(stanza.attr.from)));
|
||||
|
||||
if not room or not room.sent_initial_metadata or is_healthcheck_room(room.jid) then
|
||||
return stanza;
|
||||
end
|
||||
|
||||
if room.sent_initial_metadata[bare_to] then
|
||||
return stanza;
|
||||
end
|
||||
|
||||
local occupant;
|
||||
for _, o in room:each_occupant() do
|
||||
if o.bare_jid == bare_to then
|
||||
occupant = o;
|
||||
end
|
||||
end
|
||||
|
||||
if not occupant then
|
||||
module:log('warn', 'No occupant %s found for %s', bare_to, room.jid);
|
||||
return stanza;
|
||||
end
|
||||
|
||||
room.sent_initial_metadata[bare_to] = true;
|
||||
|
||||
send_metadata(occupant, room);
|
||||
|
||||
return stanza;
|
||||
end
|
||||
function filter_session(session)
|
||||
-- domain mapper is filtering on default priority 0
|
||||
-- allowners is -1 and we need it after that, permissions is -2
|
||||
filters.add_filter(session, 'stanzas/out', filter_stanza, -3);
|
||||
end
|
||||
|
||||
-- enable filtering presences
|
||||
filters.add_filter_hook(filter_session);
|
||||
|
Reference in New Issue
Block a user