mirror of
https://git.lapiole.org/dani/ansible-roles.git
synced 2025-08-02 23:05:41 +02:00
Update to 2025-07-28 13:00
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
---
|
||||
|
||||
# Version of consul to deploy
|
||||
consul_version: 1.21.2
|
||||
consul_version: 1.21.3
|
||||
# URL from where the consul archive will be downloaded
|
||||
consul_archive_url: https://releases.hashicorp.com/consul/{{ consul_version }}/consul_{{ consul_version }}_linux_amd64.zip
|
||||
# Expected sha256 of the archive
|
||||
consul_archive_sha256: 07a738cc8f7937f28d1418e8f289b28445e82d5cbd0aabdbcf2b5a0cacf26a29
|
||||
consul_archive_sha256: ba20631037a5f63f70b0351c0875887a66c0a0d3feac2d255a768c9eb8c95e8b
|
||||
|
@@ -1,11 +1,11 @@
|
||||
---
|
||||
|
||||
# Version of consul-template to install
|
||||
consul_tpl_version: 0.41.0
|
||||
consul_tpl_version: 0.41.1
|
||||
# URL of the archive
|
||||
consul_tpl_archive_url: https://releases.hashicorp.com/consul-template/{{ consul_tpl_version }}/consul-template_{{ consul_tpl_version }}_linux_amd64.zip
|
||||
# Expected sha256 of the archive
|
||||
consul_tpl_archive_sha256: 64e732cdd75a778ea6a5e16b32792a1effc88963d37e73f0088a115ea790938f
|
||||
consul_tpl_archive_sha256: ab68e09642437dcc5b6e9a572a1924d3969e4fe131f50a1a3a4f782d7a21f530
|
||||
|
||||
# Root dir where consul-template will be installed
|
||||
consul_tpl_root_dir: /opt/consul_template
|
||||
|
@@ -16,5 +16,6 @@ transforms:
|
||||
if (.file == "/var/log/httpd/error_log"){
|
||||
.http = parse_apache_log!(.message, format:"error")
|
||||
}
|
||||
.timestamp = parse_timestamp(del(.http.timestamp), format: "%d/%h/%Y:%H:%M:%S %z") ?? now()
|
||||
.service = "httpd"
|
||||
.group = "web"
|
||||
|
@@ -9,16 +9,16 @@ jitsi_user: jitsi
|
||||
jitsi_web_src_ip:
|
||||
- 0.0.0.0/0
|
||||
|
||||
jitsi_version: 10314
|
||||
jitsi_version: 10431
|
||||
|
||||
jitsi_jicofo_archive_url: https://github.com/jitsi/jicofo/archive/refs/tags/stable/jitsi-meet_{{ jitsi_version }}.tar.gz
|
||||
jitsi_jicofo_archive_sha256: 0e081653d525462bfa1358ff6a25b091636792c4ac4a4fbf0b6235951d7cc4ac
|
||||
jitsi_jicofo_archive_sha256: 5a575f97a4f5f24b2406712cd25196083ac33535bde998d72bb0acf07d727592
|
||||
|
||||
# Jigasi has no release, nor tags, so use master
|
||||
jitsi_jigasi_archive_url: https://github.com/jitsi/jigasi/archive/refs/heads/master.tar.gz
|
||||
|
||||
jitsi_meet_archive_url: https://github.com/jitsi/jitsi-meet/archive/refs/tags/stable/jitsi-meet_{{ jitsi_version }}.tar.gz
|
||||
jitsi_meet_archive_sha256: 04770928b232fb794206083f9f4cdfe24112ce8dd57e84c253380afb39ebc5d3
|
||||
jitsi_meet_archive_sha256: 7402386e8ecb77ef3f6029b169aa07e6a56011d59ac0cb7019bfa1fdb3d8fcb3
|
||||
|
||||
jitsi_excalidraw_version: 2025.2.2
|
||||
jitsi_excalidraw_archive_url: https://github.com/jitsi/excalidraw-backend/archive/refs/tags/{{ jitsi_excalidraw_version }}.tar.gz
|
||||
|
@@ -1,6 +1,6 @@
|
||||
local avmoderation_component = module:get_option_string('av_moderation_component', 'avmoderation.'..module.host);
|
||||
-- TODO: Remove this file after several stable releases when people update their configs
|
||||
module:log('warn', 'mod_av_moderation is deprecated and will be removed in a future release. '
|
||||
.. 'Please update your config by removing this module from the list of loaded modules.');
|
||||
|
||||
-- Advertise AV Moderation so client can pick up the address and use it
|
||||
module:add_identity('component', 'av_moderation', avmoderation_component);
|
||||
|
||||
module:depends("jitsi_session");
|
||||
module:depends('jitsi_session');
|
||||
module:depends('features_identity');
|
||||
|
@@ -5,6 +5,7 @@ local internal_room_jid_match_rewrite = util.internal_room_jid_match_rewrite;
|
||||
local room_jid_match_rewrite = util.room_jid_match_rewrite;
|
||||
local process_host_module = util.process_host_module;
|
||||
local table_shallow_copy = util.table_shallow_copy;
|
||||
local is_admin = util.is_admin;
|
||||
local array = require "util.array";
|
||||
local json = require 'cjson.safe';
|
||||
local st = require 'util.stanza';
|
||||
@@ -15,6 +16,12 @@ if muc_component_host == nil then
|
||||
return;
|
||||
end
|
||||
|
||||
local main_virtual_host = module:get_option_string('muc_mapper_domain_base');
|
||||
if not main_virtual_host then
|
||||
module:log('warn', 'No "muc_mapper_domain_base" option set, disabling AV moderation.');
|
||||
return ;
|
||||
end
|
||||
|
||||
module:log('info', 'Starting av_moderation for %s', muc_component_host);
|
||||
|
||||
-- Returns the index of the given element in the table
|
||||
@@ -84,7 +91,7 @@ function notify_whitelist_change(jid, moderators, room, mediaType, removed)
|
||||
body_json.mediaType = mediaType;
|
||||
|
||||
-- sanitize, make sure we don't have an empty array as it will encode it as {} not as []
|
||||
for _,mediaType in pairs({'audio', 'video'}) do
|
||||
for _,mediaType in pairs({'audio', 'video', 'desktop'}) do
|
||||
if body_json.whitelists[mediaType] and #body_json.whitelists[mediaType] == 0 then
|
||||
body_json.whitelists[mediaType] = nil;
|
||||
end
|
||||
@@ -145,6 +152,36 @@ function notify_jid_approved(jid, from, room, mediaType)
|
||||
send_json_message(jid, json_message);
|
||||
end
|
||||
|
||||
function start_av_moderation(room, mediaType, occupant)
|
||||
if not room.av_moderation then
|
||||
room.av_moderation = {};
|
||||
room.av_moderation_actors = {};
|
||||
end
|
||||
room.av_moderation[mediaType] = array();
|
||||
|
||||
-- add all current moderators to the new whitelist
|
||||
for _, room_occupant in room:each_occupant() do
|
||||
if room_occupant.role == 'moderator' and not ends_with(room_occupant.nick, '/focus') then
|
||||
room.av_moderation[mediaType]:push(internal_room_jid_match_rewrite(room_occupant.nick));
|
||||
end
|
||||
end
|
||||
|
||||
-- We want to set startMuted policy in metadata, in case of new participants are joining to respect
|
||||
-- it, that will be enforced by jicofo
|
||||
local startMutedMetadata = room.jitsiMetadata.startMuted or {};
|
||||
|
||||
-- We want to keep the previous value of startMuted for this mediaType if av moderation is disabled
|
||||
-- to be able to restore
|
||||
local av_moderation_startMuted_restore = room.av_moderation_startMuted_restore or {};
|
||||
av_moderation_startMuted_restore[mediaType] = startMutedMetadata[mediaType];
|
||||
room.av_moderation_startMuted_restore = av_moderation_startMuted_restore;
|
||||
|
||||
startMutedMetadata[mediaType] = true;
|
||||
room.jitsiMetadata.startMuted = startMutedMetadata;
|
||||
|
||||
room.av_moderation_actors[mediaType] = occupant.nick;
|
||||
end
|
||||
|
||||
-- receives messages from clients to the component sending A/V moderation enable/disable commands or adding
|
||||
-- jids to the whitelist
|
||||
function on_message(event)
|
||||
@@ -185,7 +222,7 @@ function on_message(event)
|
||||
|
||||
local mediaType = moderation_command.attr.mediaType;
|
||||
if mediaType then
|
||||
if mediaType ~= 'audio' and mediaType ~= 'video' then
|
||||
if mediaType ~= 'audio' and mediaType ~= 'video' and mediaType ~= 'desktop' then
|
||||
module:log('warn', 'Wrong mediaType %s for %s', mediaType, room.jid);
|
||||
return false;
|
||||
end
|
||||
@@ -202,26 +239,7 @@ function on_message(event)
|
||||
module:log('warn', 'Concurrent moderator enable/disable request or something is out of sync');
|
||||
return true;
|
||||
else
|
||||
if not room.av_moderation then
|
||||
room.av_moderation = {};
|
||||
room.av_moderation_actors = {};
|
||||
end
|
||||
room.av_moderation[mediaType] = array{};
|
||||
|
||||
-- We want to set startMuted policy in metadata, in case of new participants are joining to respect
|
||||
-- it, that will be enforced by jicofo
|
||||
local startMutedMetadata = room.jitsiMetadata.startMuted or {};
|
||||
|
||||
-- We want to keep the previous value of startMuted for this mediaType if av moderation is disabled
|
||||
-- to be able to restore
|
||||
local av_moderation_startMuted_restore = room.av_moderation_startMuted_restore or {};
|
||||
av_moderation_startMuted_restore = startMutedMetadata[mediaType];
|
||||
room.av_moderation_startMuted_restore = av_moderation_startMuted_restore;
|
||||
|
||||
startMutedMetadata[mediaType] = true;
|
||||
room.jitsiMetadata.startMuted = startMutedMetadata;
|
||||
|
||||
room.av_moderation_actors[mediaType] = occupant.nick;
|
||||
start_av_moderation(room, mediaType, occupant);
|
||||
end
|
||||
else
|
||||
enabled = false;
|
||||
@@ -251,6 +269,12 @@ function on_message(event)
|
||||
|
||||
-- send message to all occupants
|
||||
notify_occupants_enable(nil, enabled, room, occupant.nick, mediaType);
|
||||
|
||||
if enabled then
|
||||
-- inform all moderators for the newly created whitelist
|
||||
notify_whitelist_change(nil, true, room, mediaType);
|
||||
end
|
||||
|
||||
return true;
|
||||
elseif moderation_command.attr.jidToWhitelist then
|
||||
local occupant_jid = moderation_command.attr.jidToWhitelist;
|
||||
@@ -311,12 +335,32 @@ end
|
||||
function occupant_joined(event)
|
||||
local room, occupant = event.room, event.occupant;
|
||||
|
||||
if is_healthcheck_room(room.jid) then
|
||||
if is_healthcheck_room(room.jid) or is_admin(occupant.bare_jid) then
|
||||
return;
|
||||
end
|
||||
|
||||
-- when first moderator joins if av_can_unmute from password preset is set to false, we enable av moderation for both
|
||||
-- audio and video, and set the first moderator as the actor that enabled it
|
||||
if room._data.av_can_unmute ~= nil
|
||||
and not room._data.av_first_moderator_joined
|
||||
|
||||
-- occupant.role is not reflecting the actual role after set_affiliation is used in same occupant_joined event
|
||||
and room:get_role(occupant.nick) == 'moderator' then
|
||||
|
||||
if not room._data.av_can_unmute then
|
||||
for _,mediaType in pairs({'audio', 'video', 'desktop'}) do
|
||||
start_av_moderation(room, mediaType, occupant);
|
||||
|
||||
notify_occupants_enable(nil, true, room, occupant.nick, mediaType);
|
||||
end
|
||||
|
||||
room._data.av_first_moderator_joined = true;
|
||||
return;
|
||||
end
|
||||
end
|
||||
|
||||
if room.av_moderation then
|
||||
for _,mediaType in pairs({'audio', 'video'}) do
|
||||
for _,mediaType in pairs({'audio', 'video', 'desktop'}) do
|
||||
if room.av_moderation[mediaType] then
|
||||
notify_occupants_enable(
|
||||
occupant.jid, true, room, room.av_moderation_actors[mediaType], mediaType);
|
||||
@@ -326,9 +370,13 @@ function occupant_joined(event)
|
||||
-- NOTE for some reason event.occupant.role is not reflecting the actual occupant role (when changed
|
||||
-- from allowners module) but iterating over room occupants returns the correct role
|
||||
for _, room_occupant in room:each_occupant() do
|
||||
-- if moderator send the whitelist
|
||||
if room_occupant.nick == occupant.nick and room_occupant.role == 'moderator' then
|
||||
notify_whitelist_change(room_occupant.jid, false, room);
|
||||
-- if it is a moderator, send the whitelist to every moderator
|
||||
if room_occupant.nick == occupant.nick and room_occupant.role == 'moderator' then
|
||||
for _,mediaType in pairs({'audio', 'video', 'desktop'}) do
|
||||
if room.av_moderation[mediaType] then
|
||||
notify_whitelist_change(nil, true, room, mediaType);
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -336,14 +384,30 @@ end
|
||||
|
||||
-- when a occupant was granted moderator we need to update him with the whitelist
|
||||
function occupant_affiliation_changed(event)
|
||||
local room = event.room;
|
||||
if not room.av_moderation or is_healthcheck_room(room.jid) or is_admin(event.jid)
|
||||
or event.affiliation ~= 'owner' then
|
||||
return;
|
||||
end
|
||||
|
||||
-- in any enabled media type add the new moderator to the whitelist
|
||||
for _, room_occupant in room:each_occupant() do
|
||||
if room_occupant.bare_jid == event.jid then
|
||||
for _,mediaType in pairs({'audio', 'video', 'desktop'}) do
|
||||
if room.av_moderation[mediaType] then
|
||||
room.av_moderation[mediaType]:push(internal_room_jid_match_rewrite(room_occupant.nick));
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- the actor can be nil if is coming from allowners or similar module we want to skip it here
|
||||
-- as we will handle it in occupant_joined
|
||||
if event.actor and event.affiliation == 'owner' and event.room.av_moderation then
|
||||
local room = event.room;
|
||||
-- event.jid is the bare jid of participant
|
||||
for _, occupant in room:each_occupant() do
|
||||
if occupant.bare_jid == event.jid then
|
||||
notify_whitelist_change(occupant.jid, false, room);
|
||||
if event.actor and event.affiliation == 'owner' then
|
||||
-- notify all moderators for the new grant moderator and the change in whitelists
|
||||
for _,mediaType in pairs({'audio', 'video', 'desktop'}) do
|
||||
if room.av_moderation[mediaType] then
|
||||
notify_whitelist_change(nil, true, room, mediaType);
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -357,3 +421,9 @@ process_host_module(muc_component_host, function(host_module, host)
|
||||
host_module:hook('muc-occupant-joined', occupant_joined, -2); -- make sure it runs after allowners or similar
|
||||
host_module:hook('muc-set-affiliation', occupant_affiliation_changed, -1);
|
||||
end);
|
||||
|
||||
process_host_module(main_virtual_host, function(host_module)
|
||||
module:context(host_module.host):fire_event('jitsi-add-identity', {
|
||||
name = 'av_moderation'; host = module.host;
|
||||
});
|
||||
end);
|
||||
|
@@ -1,24 +1,21 @@
|
||||
-- This module is added under the main virtual host domain
|
||||
--
|
||||
-- VirtualHost "jitmeet.example.com"
|
||||
-- modules_enabled = {
|
||||
-- "end_conference"
|
||||
-- }
|
||||
-- end_conference_component = "endconference.jitmeet.example.com"
|
||||
--
|
||||
-- Component "endconference.jitmeet.example.com" "end_conference"
|
||||
-- muc_component = muc.jitmeet.example.com
|
||||
--
|
||||
local get_room_by_name_and_subdomain = module:require 'util'.get_room_by_name_and_subdomain;
|
||||
local util = module:require 'util';
|
||||
local get_room_by_name_and_subdomain = util.get_room_by_name_and_subdomain;
|
||||
local process_host_module = util.process_host_module;
|
||||
|
||||
local END_CONFERENCE_REASON = 'The meeting has been terminated';
|
||||
|
||||
-- Since this file serves as both the host module and the component, we rely on the assumption that
|
||||
-- end_conference_component var would only be define for the host and not in the end_conference component
|
||||
-- TODO: Remove this if block after several stable releases when people update their configs
|
||||
local end_conference_component = module:get_option_string('end_conference_component');
|
||||
if end_conference_component then
|
||||
-- Advertise end conference so client can pick up the address and use it
|
||||
module:add_identity('component', 'end_conference', end_conference_component);
|
||||
module:log('warn', 'Please update your config by removing muc_end_conference module from '
|
||||
.. 'the list of loaded modules in the main virtual host.');
|
||||
module:depends("features_identity");
|
||||
return; -- nothing left to do if called as host module
|
||||
end
|
||||
|
||||
@@ -32,6 +29,12 @@ if muc_component_host == nil then
|
||||
return;
|
||||
end
|
||||
|
||||
local main_virtual_host = module:get_option_string('muc_mapper_domain_base');
|
||||
if not main_virtual_host then
|
||||
module:log('warn', 'No "muc_mapper_domain_base" option set, disabling end conference component.');
|
||||
return ;
|
||||
end
|
||||
|
||||
module:log('info', 'Starting end_conference for %s', muc_component_host);
|
||||
|
||||
-- receives messages from clients to the component to end a conference
|
||||
@@ -84,3 +87,9 @@ end
|
||||
|
||||
-- we will receive messages from the clients
|
||||
module:hook('message/host', on_message);
|
||||
|
||||
process_host_module(main_virtual_host, function(host_module)
|
||||
module:context(host_module.host):fire_event('jitsi-add-identity', {
|
||||
name = 'end_conference'; host = module.host;
|
||||
});
|
||||
end);
|
||||
|
@@ -0,0 +1,8 @@
|
||||
-- Other components can use the event 'jitsi-add-identity' to attach identity which
|
||||
-- will be advertised by the main virtual host and discovered by clients.
|
||||
-- With this we avoid having an almost empty module to just add identity with an extra config
|
||||
|
||||
module:hook('jitsi-add-identity', function(event)
|
||||
module:log('info', 'Adding identity %s for host %s', event.name, event.host);
|
||||
module:add_identity('component', event.name, event.host);
|
||||
end);
|
245
roles/jitsi/files/prosody/modules/mod_filesharing_component.lua
Normal file
245
roles/jitsi/files/prosody/modules/mod_filesharing_component.lua
Normal file
@@ -0,0 +1,245 @@
|
||||
local json = require 'cjson.safe';
|
||||
local jid = require 'util.jid';
|
||||
local st = require 'util.stanza';
|
||||
|
||||
local util = module:require 'util';
|
||||
local internal_room_jid_match_rewrite = util.internal_room_jid_match_rewrite;
|
||||
local is_admin = util.is_admin;
|
||||
local process_host_module = util.process_host_module;
|
||||
|
||||
local FILE_SHARING_IDENTITY_TYPE = 'file-sharing';
|
||||
local JSON_TYPE_ADD_FILE = 'add';
|
||||
local JSON_TYPE_REMOVE_FILE = 'remove';
|
||||
local JSON_TYPE_LIST_FILES = 'list';
|
||||
local NICK_NS = 'http://jabber.org/protocol/nick';
|
||||
|
||||
-- this is the main virtual host of the main prosody that this vnode serves
|
||||
local main_domain = module:get_option_string('main_domain');
|
||||
-- only the visitor prosody has main_domain setting
|
||||
local is_visitor_prosody = main_domain ~= nil;
|
||||
|
||||
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!');
|
||||
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, disabling file sharing component.");
|
||||
return ;
|
||||
end
|
||||
|
||||
-- receives messages from clients to the component sending file sharing commands for adding or removing files
|
||||
function on_message(event)
|
||||
local session, stanza = event.origin, event.stanza;
|
||||
|
||||
-- Check the type of the incoming stanza to avoid loops:
|
||||
if stanza.attr.type == 'error' then
|
||||
return; -- We do not want to reply to these, so leave.
|
||||
end
|
||||
|
||||
if not session or not session.jitsi_web_query_room then
|
||||
return false;
|
||||
end
|
||||
|
||||
local message = stanza:get_child(FILE_SHARING_IDENTITY_TYPE, 'http://jitsi.org/jitmeet');
|
||||
|
||||
if not message then
|
||||
return false;
|
||||
end
|
||||
|
||||
-- get room name with tenant and find room
|
||||
local room = get_room_by_name_and_subdomain(session.jitsi_web_query_room, session.jitsi_web_query_prefix);
|
||||
|
||||
if not room then
|
||||
module:log('warn', 'No room found for %s/%s', session.jitsi_web_query_prefix, session.jitsi_web_query_room);
|
||||
return false;
|
||||
end
|
||||
|
||||
-- check that the participant sending the message is an occupant in the room
|
||||
local from = stanza.attr.from;
|
||||
local occupant = room:get_occupant_by_real_jid(from);
|
||||
|
||||
if not occupant then
|
||||
module:log('warn', 'No occupant %s found for %s', from, room.jid);
|
||||
return false;
|
||||
end
|
||||
|
||||
if not is_feature_allowed(
|
||||
'file-upload',
|
||||
session.jitsi_meet_context_features,
|
||||
room:get_affiliation(stanza.attr.from) == 'owner') then
|
||||
session.send(st.error_reply(stanza, 'auth', 'forbidden'));
|
||||
return true;
|
||||
end
|
||||
|
||||
if message.attr.type == JSON_TYPE_ADD_FILE then
|
||||
local msg_obj, error = json.decode(message:get_text());
|
||||
|
||||
if error then
|
||||
module:log('error','Error decoding data error:%s %s', error, stanza);
|
||||
return false;
|
||||
end
|
||||
|
||||
if not msg_obj.fileId then
|
||||
module:log('error', 'Error missing required field: %s', stanza);
|
||||
return false;
|
||||
end
|
||||
|
||||
-- make sure we overwrite data for sender so we avoid spoofing
|
||||
msg_obj.authorParticipantId = jid.resource(occupant.nick);
|
||||
msg_obj.authorParticipantJid = from;
|
||||
|
||||
local nick_element = occupant:get_presence():get_child('nick', NICK_NS);
|
||||
if nick_element then
|
||||
msg_obj.authorParticipantName = nick_element:get_text();
|
||||
else
|
||||
msg_obj.authorParticipantName = 'anonymous';
|
||||
end
|
||||
msg_obj.conferenceFullName = internal_room_jid_match_rewrite(room.jid);
|
||||
|
||||
module:context(muc_domain_base):fire_event('jitsi-filesharing-add', {
|
||||
room = room; file = msg_obj; actor = occupant.nick;
|
||||
});
|
||||
|
||||
module:context(muc_domain_base):fire_event('jitsi-filesharing-updated', {
|
||||
room = room;
|
||||
});
|
||||
|
||||
return true;
|
||||
elseif message.attr.type == JSON_TYPE_REMOVE_FILE then
|
||||
if not message.attr.fileId then
|
||||
module:log('error', 'Error missing required field: %s', stanza);
|
||||
return true;
|
||||
end
|
||||
|
||||
module:context(muc_domain_base):fire_event('jitsi-filesharing-remove', {
|
||||
room = room; id = message.attr.fileId; actor = occupant.nick;
|
||||
});
|
||||
|
||||
module:context(muc_domain_base):fire_event('jitsi-filesharing-updated', {
|
||||
room = room;
|
||||
});
|
||||
|
||||
return true;
|
||||
else
|
||||
-- return error.
|
||||
return false;
|
||||
end
|
||||
end
|
||||
|
||||
-- handles new occupants to inform them about any file shared by other participants
|
||||
function occupant_joined(event)
|
||||
local room, occupant = event.room, event.occupant;
|
||||
|
||||
-- healthcheck rooms does not have shared files
|
||||
if not room.jitsi_shared_files
|
||||
or is_admin(occupant.bare_jid)
|
||||
or not room.jitsi_shared_files
|
||||
or next(room.jitsi_shared_files) == nil then
|
||||
return;
|
||||
end
|
||||
|
||||
|
||||
-- send file list to the new occupant
|
||||
local json_msg, error = json.encode({
|
||||
type = FILE_SHARING_IDENTITY_TYPE,
|
||||
event = JSON_TYPE_LIST_FILES,
|
||||
files = room.jitsi_shared_files
|
||||
});
|
||||
|
||||
local stanza = st.message({ from = module.host; to = occupant.jid; })
|
||||
:tag('json-message', { xmlns = 'http://jitsi.org/jitmeet' })
|
||||
:text(json_msg):up();
|
||||
|
||||
module:send(stanza);
|
||||
end
|
||||
|
||||
process_host_module(muc_component_host, function(host_module, host)
|
||||
module:log('info','Hook to muc events on %s', host);
|
||||
host_module:hook('muc-occupant-joined', occupant_joined, -10); -- make sure it runs after allowners or similar
|
||||
end);
|
||||
|
||||
-- we will receive messages from the clients
|
||||
module:hook('message/host', on_message);
|
||||
|
||||
process_host_module(muc_domain_base, function(host_module, host)
|
||||
module:context(muc_domain_base):fire_event('jitsi-add-identity', {
|
||||
name = FILE_SHARING_IDENTITY_TYPE; host = module.host;
|
||||
});
|
||||
module:context(muc_domain_base):hook('jitsi-filesharing-add', function(event)
|
||||
local actor, file, room = event.actor, event.file, event.room;
|
||||
|
||||
if not room.jitsi_shared_files then
|
||||
room.jitsi_shared_files = {};
|
||||
end
|
||||
|
||||
room.jitsi_shared_files[file.fileId] = file;
|
||||
|
||||
local json_msg, error = json.encode({
|
||||
type = FILE_SHARING_IDENTITY_TYPE,
|
||||
event = JSON_TYPE_ADD_FILE,
|
||||
file = file
|
||||
});
|
||||
|
||||
if not json_msg then
|
||||
module:log('error', 'skip sending add request room:%s error:%s', room.jid, error);
|
||||
return false
|
||||
end
|
||||
|
||||
local stanza = st.message({ from = module.host; }):tag('json-message', { xmlns = 'http://jitsi.org/jitmeet' })
|
||||
:text(json_msg):up();
|
||||
|
||||
-- send add file to all occupants except jicofo and sender
|
||||
-- if this is visitor prosody send it only to visitors
|
||||
for _, room_occupant in room:each_occupant() do
|
||||
local send_event = not is_admin(room_occupant.bare_jid) and room_occupant.nick ~= actor;
|
||||
if is_visitor_prosody then
|
||||
send_event = room_occupant.role == 'visitor';
|
||||
end
|
||||
if send_event then
|
||||
local to_send = st.clone(stanza);
|
||||
to_send.attr.to = room_occupant.jid;
|
||||
module:send(to_send);
|
||||
end
|
||||
end
|
||||
end);
|
||||
module:context(muc_domain_base):hook('jitsi-filesharing-remove', function(event)
|
||||
local actor, id, room = event.actor, event.id, event.room;
|
||||
|
||||
if not room.jitsi_shared_files then
|
||||
return;
|
||||
end
|
||||
|
||||
room.jitsi_shared_files[id] = nil;
|
||||
|
||||
local json_msg, error = json.encode({
|
||||
type = FILE_SHARING_IDENTITY_TYPE,
|
||||
event = JSON_TYPE_REMOVE_FILE,
|
||||
fileId = id
|
||||
});
|
||||
|
||||
if not json_msg then
|
||||
module:log('error', 'skip sending remove request room:%s error:%s', room.jid, error);
|
||||
return false
|
||||
end
|
||||
|
||||
local stanza = st.message({ from = module.host; }):tag('json-message', { xmlns = 'http://jitsi.org/jitmeet' })
|
||||
:text(json_msg):up();
|
||||
|
||||
-- send remove file to all occupants except jicofo and sender
|
||||
-- if this is visitor prosody send it only to visitors
|
||||
for _, room_occupant in room:each_occupant() do
|
||||
local send_event = not is_admin(room_occupant.bare_jid) and room_occupant.nick ~= actor;
|
||||
if is_visitor_prosody then
|
||||
send_event = room_occupant.role == 'visitor';
|
||||
end
|
||||
if send_event then
|
||||
local to_send = st.clone(stanza);
|
||||
to_send.attr.to = room_occupant.jid;
|
||||
module:send(to_send);
|
||||
end
|
||||
end
|
||||
end);
|
||||
end);
|
@@ -38,7 +38,6 @@ module:hook("pre-iq/full", function(event)
|
||||
local is_allowed = is_feature_allowed(
|
||||
feature,
|
||||
session.jitsi_meet_context_features,
|
||||
session.granted_jitsi_meet_context_features,
|
||||
occupant.role == 'moderator');
|
||||
|
||||
if jibri.attr.action == 'start' or jibri.attr.action == 'stop' then
|
||||
|
@@ -107,7 +107,6 @@ module:hook("pre-iq/full", function(event)
|
||||
local is_session_allowed = is_feature_allowed(
|
||||
feature,
|
||||
session.jitsi_meet_context_features,
|
||||
session.granted_jitsi_meet_context_features,
|
||||
room:get_affiliation(stanza.attr.from) == 'owner');
|
||||
|
||||
if roomName == nil
|
||||
|
@@ -16,6 +16,7 @@ local new_id = require 'util.id'.medium;
|
||||
local filters = require 'util.filters';
|
||||
local array = require 'util.array';
|
||||
local set = require 'util.set';
|
||||
local json = require 'cjson.safe';
|
||||
|
||||
local util = module:require 'util';
|
||||
local is_admin = util.is_admin;
|
||||
@@ -27,6 +28,7 @@ local get_focus_occupant = util.get_focus_occupant;
|
||||
local internal_room_jid_match_rewrite = util.internal_room_jid_match_rewrite;
|
||||
local presence_check_status = util.presence_check_status;
|
||||
local respond_iq_result = util.respond_iq_result;
|
||||
local table_compare = util.table_compare;
|
||||
|
||||
local PARTICIPANT_PROP_RAISE_HAND = 'jitsi_participant_raisedHand';
|
||||
local PARTICIPANT_PROP_REQUEST_TRANSCRIPTION = 'jitsi_participant_requestingTranscription';
|
||||
@@ -672,6 +674,29 @@ local function iq_from_main_handler(event)
|
||||
end
|
||||
end
|
||||
|
||||
local files = node:get_child('files');
|
||||
if files then
|
||||
local received_files = {};
|
||||
for _, child in ipairs(files.tags) do
|
||||
if child.name == 'file' then
|
||||
received_files[child.attr.id] = json.decode(child:get_text());
|
||||
end
|
||||
end
|
||||
|
||||
-- fire events so file sharing component will add/remove files and will notify clients
|
||||
local removed, added = table_compare(room.jitsi_shared_files or {}, received_files)
|
||||
for _, id in ipairs(removed) do
|
||||
module:context(local_domain):fire_event('jitsi-filesharing-remove', {
|
||||
room = room; id = id;
|
||||
});
|
||||
end
|
||||
for _, id in ipairs(added) do
|
||||
module:context(local_domain):fire_event('jitsi-filesharing-add', {
|
||||
room = room; file = received_files[id];
|
||||
});
|
||||
end
|
||||
end
|
||||
|
||||
if fire_jicofo_unlock then
|
||||
-- everything is connected allow participants to join
|
||||
module:fire_event('jicofo-unlock-room', { room = room; fmuc_fired = true; });
|
||||
|
@@ -16,7 +16,7 @@ local muc_domain_prefix = module:get_option_string('muc_mapper_domain_prefix', '
|
||||
|
||||
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, disabling kick check endpoint.');
|
||||
module:log('warn', 'No "muc_domain_base" option set, disabling module.');
|
||||
return ;
|
||||
end
|
||||
|
||||
@@ -71,15 +71,16 @@ function process_set_affiliation(event)
|
||||
end
|
||||
|
||||
if previous_affiliation == 'none' and affiliation == 'owner' then
|
||||
occupant_session.granted_jitsi_meet_context_features = actor_session.jitsi_meet_context_features;
|
||||
occupant_session.jitsi_meet_context_features = actor_session.jitsi_meet_context_features;
|
||||
if actor_session.jitsi_meet_context_user then
|
||||
occupant_session.granted_jitsi_meet_context_user_id = actor_session.jitsi_meet_context_user['id']
|
||||
or actor_session.granted_jitsi_meet_context_user_id;
|
||||
end
|
||||
occupant_session.granted_jitsi_meet_context_group_id = actor_session.jitsi_meet_context_group
|
||||
or actor_session.granted_jitsi_meet_context_group_id;
|
||||
-- even if token and features are set we may want to re-send permissions
|
||||
occupant_session.force_permissions_update = true;
|
||||
elseif previous_affiliation == 'owner' and ( affiliation == 'member' or affiliation == 'none' ) then
|
||||
occupant_session.granted_jitsi_meet_context_features = nil;
|
||||
occupant_session.granted_jitsi_meet_context_user_id = nil;
|
||||
occupant_session.granted_jitsi_meet_context_group_id = nil;
|
||||
|
||||
@@ -154,22 +155,16 @@ function filter_stanza(stanza, session)
|
||||
|
||||
session.force_permissions_update = false;
|
||||
|
||||
local permissions_to_send
|
||||
= session.jitsi_meet_context_features or session.granted_jitsi_meet_context_features or default_permissions;
|
||||
if not session.jitsi_meet_context_features then
|
||||
session.jitsi_meet_context_features = default_permissions;
|
||||
end
|
||||
|
||||
room.send_default_permissions_to[bare_to] = nil;
|
||||
|
||||
if not session.granted_jitsi_meet_context_features and not session.jitsi_meet_context_features then
|
||||
session.jitsi_meet_context_features = {};
|
||||
end
|
||||
|
||||
stanza:tag('permissions', { xmlns='http://jitsi.org/jitmeet' });
|
||||
for k, v in pairs(permissions_to_send) do
|
||||
for k, v in pairs(session.jitsi_meet_context_features) do
|
||||
local val = tostring(v);
|
||||
stanza:tag('p', { name = k, val = val }):up();
|
||||
if session.jitsi_meet_context_features then
|
||||
session.jitsi_meet_context_features[k] = val;
|
||||
end
|
||||
end
|
||||
stanza:up();
|
||||
|
||||
|
@@ -23,7 +23,7 @@ load_config();
|
||||
-- List of the bare_jids of all occupants that are currently joining (went through pre-join) and will be promoted
|
||||
-- as moderators. As pre-join (where added) and joined event (where removed) happen one after another this list should
|
||||
-- have length of 1
|
||||
local joining_moderator_participants = {};
|
||||
local joining_moderator_participants = module:shared('moderators/joining_moderator_participants');
|
||||
|
||||
module:hook("muc-room-created", function(event)
|
||||
local room = event.room;
|
||||
|
56
roles/jitsi/files/prosody/modules/mod_muc_displayname.lua
Normal file
56
roles/jitsi/files/prosody/modules/mod_muc_displayname.lua
Normal file
@@ -0,0 +1,56 @@
|
||||
--- This module removes identity information from presence stanzas when the
|
||||
--- hideDisplayNameForAll or hideDisplayNameForGuests options are enabled
|
||||
--- for a room.
|
||||
|
||||
--- To be enabled under the main muc component
|
||||
local filters = require 'util.filters';
|
||||
local st = require 'util.stanza';
|
||||
|
||||
local util = module:require 'util';
|
||||
local filter_identity_from_presence = util.filter_identity_from_presence;
|
||||
local get_room_by_name_and_subdomain = util.get_room_by_name_and_subdomain;
|
||||
local is_admin = util.is_admin;
|
||||
local ends_with = util.ends_with;
|
||||
local internal_room_jid_match_rewrite = util.internal_room_jid_match_rewrite;
|
||||
|
||||
-- we need to get the shared resource for joining moderators, as participants are marked as moderators
|
||||
-- after joining which is after the filter for stanza/out, but we need to know will this participant be a moderator
|
||||
local joining_moderator_participants = module:shared('moderators/joining_moderator_participants');
|
||||
|
||||
--- Filter presence sent to non-moderator members of a room when the hideDisplayNameForGuests option is set.
|
||||
function filter_stanza_out(stanza, session)
|
||||
if stanza.name ~= 'presence' or stanza.attr.type == 'error'
|
||||
or stanza.attr.type == 'unavailable' or ends_with(stanza.attr.from, '/focus') then
|
||||
return stanza;
|
||||
end
|
||||
|
||||
local room = get_room_by_name_and_subdomain(session.jitsi_web_query_room, session.jitsi_web_query_prefix);
|
||||
local shouldFilter = false;
|
||||
|
||||
if room and (room._data.hideDisplayNameForGuests == true or room._data.hideDisplayNameForAll == true) then
|
||||
local occupant = room:get_occupant_by_real_jid(stanza.attr.to);
|
||||
-- don't touch self-presence
|
||||
if occupant and stanza.attr.from ~= internal_room_jid_match_rewrite(occupant.nick) then
|
||||
local isModerator = (occupant.role == 'moderator' or joining_moderator_participants[occupant.bare_jid]);
|
||||
shouldFilter = room._data.hideDisplayNameForAll or not isModerator;
|
||||
end
|
||||
end
|
||||
|
||||
if shouldFilter then
|
||||
return filter_identity_from_presence(stanza);
|
||||
else
|
||||
return stanza;
|
||||
end
|
||||
end
|
||||
|
||||
function filter_session(session)
|
||||
filters.add_filter(session, 'stanzas/out', filter_stanza_out, -100);
|
||||
end
|
||||
|
||||
function module.load()
|
||||
filters.add_filter_hook(filter_session);
|
||||
end
|
||||
|
||||
function module.unload()
|
||||
filters.remove_filter_hook(filter_session);
|
||||
end
|
@@ -184,7 +184,8 @@ module:hook('message/bare', function(event)
|
||||
return;
|
||||
end
|
||||
|
||||
local json_message = stanza:get_child_text('json-message', 'http://jitsi.org/jitmeet');
|
||||
local json_message = stanza:get_child_text('json-message', 'http://jitsi.org/jitmeet')
|
||||
or stanza:get_child_text('json-message');
|
||||
if not json_message then
|
||||
return;
|
||||
end
|
||||
|
@@ -17,7 +17,7 @@ local disable_auto_owners = module:get_option_boolean('wait_for_host_disable_aut
|
||||
|
||||
local muc_domain_base = module:get_option_string('muc_mapper_domain_base');
|
||||
if not muc_domain_base then
|
||||
module:log('warn', "No 'muc_mapper_domain_base' option set, disabling muc_mapper plugin inactive");
|
||||
module:log('warn', "No 'muc_mapper_domain_base' option set, disabling module");
|
||||
return
|
||||
end
|
||||
|
||||
|
@@ -1,10 +1,6 @@
|
||||
-- Generic room metadata
|
||||
-- See mod_room_metadata_component.lua
|
||||
|
||||
local COMPONENT_IDENTITY_TYPE = 'room_metadata';
|
||||
local room_metadata_component_host = module:get_option_string('room_metadata_component', 'metadata.'..module.host);
|
||||
-- TODO: Remove this file after several stable releases when people update their configs
|
||||
module:log('warn', 'mod_room_metadata is deprecated and will be removed in a future release. '
|
||||
.. 'Please update your config by removing this module from the list of loaded modules.');
|
||||
|
||||
module:depends("jitsi_session");
|
||||
|
||||
-- Advertise the component so clients can pick up the address and use it
|
||||
module:add_identity('component', COMPONENT_IDENTITY_TYPE, room_metadata_component_host);
|
||||
module:depends("features_identity");
|
||||
|
@@ -1,18 +1,12 @@
|
||||
-- This module implements a generic metadata storage system for rooms.
|
||||
--
|
||||
-- VirtualHost "jitmeet.example.com"
|
||||
-- modules_enabled = {
|
||||
-- "room_metadata"
|
||||
-- }
|
||||
-- room_metadata_component = "metadata.jitmeet.example.com"
|
||||
-- main_muc = "conference.jitmeet.example.com"
|
||||
--
|
||||
-- Component "metadata.jitmeet.example.com" "room_metadata_component"
|
||||
-- muc_component = "conference.jitmeet.example.com"
|
||||
-- breakout_rooms_component = "breakout.jitmeet.example.com"
|
||||
local array = require 'util.array';
|
||||
local filters = require 'util.filters';
|
||||
local jid_node = require 'util.jid'.node;
|
||||
local json = require 'cjson.safe';
|
||||
local json = require 'util.json';
|
||||
local st = require 'util.stanza';
|
||||
local jid = require 'util.jid';
|
||||
|
||||
@@ -25,6 +19,7 @@ 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 table_equals = util.table_equals;
|
||||
|
||||
local MUC_NS = 'http://jabber.org/protocol/muc';
|
||||
local COMPONENT_IDENTITY_TYPE = 'room_metadata';
|
||||
@@ -37,9 +32,9 @@ if muc_component_host == nil then
|
||||
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.');
|
||||
local main_virtual_host = module:get_option_string('muc_mapper_domain_base');
|
||||
if not main_virtual_host then
|
||||
module:log('warn', 'No muc_mapper_domain_base option set.');
|
||||
return;
|
||||
end
|
||||
|
||||
@@ -85,24 +80,25 @@ function send_metadata(occupant, room, json_msg)
|
||||
|
||||
-- we want to send the main meeting participants only to jicofo
|
||||
if is_admin(occupant.bare_jid) then
|
||||
local participants = {};
|
||||
local participants;
|
||||
local moderators = array();
|
||||
|
||||
if room._data.mainMeetingParticipants then
|
||||
table_add(participants, room._data.mainMeetingParticipants);
|
||||
if room._data.participants then
|
||||
participants = array();
|
||||
participants:append(room._data.participants);
|
||||
end
|
||||
|
||||
if room._data.moderator_id then
|
||||
table.insert(participants, room._data.moderator_id);
|
||||
moderators:push(room._data.moderator_id);
|
||||
end
|
||||
|
||||
if room._data.moderators then
|
||||
table_add(participants, room._data.moderators);
|
||||
moderators:append(room._data.moderators);
|
||||
end
|
||||
|
||||
if #participants > 0 then
|
||||
metadata_to_send = table_shallow_copy(metadata_to_send);
|
||||
metadata_to_send.mainMeetingParticipants = participants;
|
||||
end
|
||||
metadata_to_send = table_shallow_copy(metadata_to_send);
|
||||
metadata_to_send.participants = participants;
|
||||
metadata_to_send.moderators = moderators;
|
||||
end
|
||||
|
||||
json_msg = getMetadataJSON(room, metadata_to_send);
|
||||
@@ -182,7 +178,7 @@ function on_message(event)
|
||||
|
||||
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',
|
||||
local res = module:context(main_virtual_host):fire_event('jitsi-metadata-allow-moderation',
|
||||
{ room = room; actor = occupant; key = jsonData.key ; data = jsonData.data; session = session; });
|
||||
|
||||
if not res then
|
||||
@@ -193,12 +189,15 @@ function on_message(event)
|
||||
jsonData.data = res;
|
||||
end
|
||||
|
||||
room.jitsiMetadata[jsonData.key] = jsonData.data;
|
||||
local old_value = room.jitsiMetadata[jsonData.key];
|
||||
if not table_equals(old_value, jsonData.data) then
|
||||
room.jitsiMetadata[jsonData.key] = jsonData.data;
|
||||
|
||||
broadcastMetadata(room);
|
||||
broadcastMetadata(room);
|
||||
|
||||
-- fire and event for the change
|
||||
main_muc_module:fire_event('jitsi-metadata-updated', { room = room; actor = occupant; key = jsonData.key; });
|
||||
-- fire and event for the change
|
||||
main_muc_module:fire_event('jitsi-metadata-updated', { room = room; actor = occupant; key = jsonData.key; });
|
||||
end
|
||||
|
||||
return true;
|
||||
end
|
||||
@@ -243,12 +242,24 @@ function process_main_muc_loaded(main_muc, host_module)
|
||||
|
||||
local startMutedMetadata = room.jitsiMetadata.startMuted or {};
|
||||
|
||||
startMutedMetadata.audio = startMuted.attr.audio == 'true';
|
||||
startMutedMetadata.video = startMuted.attr.video == 'true';
|
||||
local audioNewValue = startMuted.attr.audio == 'true';
|
||||
local videoNewValue = startMuted.attr.video == 'true';
|
||||
local send_update = false;
|
||||
|
||||
room.jitsiMetadata.startMuted = startMutedMetadata;
|
||||
if startMutedMetadata.audio ~= audioNewValue then
|
||||
startMutedMetadata.audio = audioNewValue;
|
||||
send_update = true;
|
||||
end
|
||||
if startMutedMetadata.video ~= videoNewValue then
|
||||
startMutedMetadata.video = videoNewValue;
|
||||
send_update = true;
|
||||
end
|
||||
|
||||
host_module:fire_event('room-metadata-changed', { room = room; });
|
||||
if send_update then
|
||||
room.jitsiMetadata.startMuted = startMutedMetadata;
|
||||
|
||||
host_module:fire_event('room-metadata-changed', { room = room; });
|
||||
end
|
||||
end);
|
||||
end
|
||||
|
||||
@@ -342,3 +353,9 @@ end
|
||||
|
||||
-- enable filtering presences
|
||||
filters.add_filter_hook(filter_session);
|
||||
|
||||
process_host_module(main_virtual_host, function(host_module)
|
||||
module:context(host_module.host):fire_event('jitsi-add-identity', {
|
||||
name = 'room_metadata'; host = module.host;
|
||||
});
|
||||
end);
|
||||
|
@@ -62,19 +62,19 @@ function generateToken(session, audience, room, occupant)
|
||||
exp = exp,
|
||||
sub = session.jitsi_web_query_prefix or module.host,
|
||||
context = {
|
||||
group = session.jitsi_meet_context_group or session.granted_jitsi_meet_context_group,
|
||||
group = session.jitsi_meet_context_group or session.granted_jitsi_meet_context_group_id,
|
||||
user = session.jitsi_meet_context_user or {
|
||||
id = session.full_jid,
|
||||
name = presence:get_child_text('nick', 'http://jabber.org/protocol/nick'),
|
||||
email = presence:get_child_text("email") or nil,
|
||||
nick = jid.resource(occupant.nick)
|
||||
},
|
||||
features = session.jitsi_meet_context_features or session.granted_jitsi_meet_context_features
|
||||
features = session.jitsi_meet_context_features
|
||||
},
|
||||
room = session.jitsi_web_query_room,
|
||||
meeting_id = room._data.meetingId,
|
||||
granted_from = session.granted_jitsi_meet_context_user_id,
|
||||
customer_id = id or session.jitsi_meet_context_group or session.granted_jitsi_meet_context_group,
|
||||
customer_id = id or session.jitsi_meet_context_group or session.granted_jitsi_meet_context_group_id,
|
||||
backend_region = server_region_name,
|
||||
user_region = session.user_region
|
||||
};
|
||||
@@ -115,6 +115,8 @@ module:hook('external_service/credentials', function (event)
|
||||
password = generateToken(session, host, room, occupant);
|
||||
expires = os.time() + options.ttl_seconds;
|
||||
restricted = true;
|
||||
transport = 'https';
|
||||
port = 443;
|
||||
});
|
||||
end
|
||||
end
|
||||
|
@@ -1,6 +1,6 @@
|
||||
local speakerstats_component
|
||||
= module:get_option_string("speakerstats_component", "speakerstats."..module.host);
|
||||
-- TODO: Remove this file after several stable releases when people update their configs
|
||||
module:log('warn', 'mod_speakerstats is deprecated and will be removed in a future release. '
|
||||
.. 'Please update your config by removing this module from the list of loaded modules.');
|
||||
|
||||
-- Advertise speaker stats so client can pick up the address and start sending
|
||||
-- dominant speaker events
|
||||
module:add_identity("component", "speakerstats", speakerstats_component);
|
||||
module:depends('jitsi_session');
|
||||
module:depends('features_identity');
|
||||
|
@@ -20,13 +20,13 @@ if not have_async then
|
||||
end
|
||||
|
||||
local muc_component_host = module:get_option_string("muc_component");
|
||||
local muc_domain_base = module:get_option_string("muc_mapper_domain_base");
|
||||
local main_virtual_host = module:get_option_string("muc_mapper_domain_base");
|
||||
|
||||
if muc_component_host == nil or muc_domain_base == nil then
|
||||
if muc_component_host == nil or main_virtual_host == nil then
|
||||
module:log("error", "No muc_component specified. No muc to operate on!");
|
||||
return;
|
||||
end
|
||||
local breakout_room_component_host = "breakout." .. muc_domain_base;
|
||||
local breakout_room_component_host = "breakout." .. main_virtual_host;
|
||||
|
||||
module:log("info", "Starting speakerstats for %s", muc_component_host);
|
||||
|
||||
@@ -376,3 +376,9 @@ process_host_module(breakout_room_component_host, function(host_module, host)
|
||||
end);
|
||||
end
|
||||
end);
|
||||
|
||||
process_host_module(main_virtual_host, function(host_module)
|
||||
module:context(host_module.host):fire_event('jitsi-add-identity', {
|
||||
name = 'speakerstats'; host = module.host;
|
||||
});
|
||||
end);
|
||||
|
@@ -12,10 +12,15 @@ local st = require 'util.stanza';
|
||||
local jid = require 'util.jid';
|
||||
local new_id = require 'util.id'.medium;
|
||||
local util = module:require 'util';
|
||||
local filter_identity_from_presence = util.filter_identity_from_presence;
|
||||
local is_admin = util.is_admin;
|
||||
local presence_check_status = util.presence_check_status;
|
||||
local process_host_module = util.process_host_module;
|
||||
local is_transcriber_jigasi = util.is_transcriber_jigasi;
|
||||
local json = require 'cjson.safe';
|
||||
|
||||
-- Debug flag
|
||||
local DEBUG = false;
|
||||
|
||||
local MUC_NS = 'http://jabber.org/protocol/muc';
|
||||
|
||||
@@ -78,6 +83,17 @@ local function send_visitors_iq(conference_service, room, type)
|
||||
end
|
||||
|
||||
visitors_iq:up();
|
||||
|
||||
-- files that are shared in the room
|
||||
if room.jitsi_shared_files then
|
||||
visitors_iq:tag('files', { xmlns = 'jitsi:visitors' });
|
||||
for k, v in pairs(room.jitsi_shared_files) do
|
||||
visitors_iq:tag('file', {
|
||||
id = k
|
||||
}):text(json.encode(v)):up();
|
||||
end
|
||||
visitors_iq:up();
|
||||
end
|
||||
end
|
||||
|
||||
visitors_iq:up();
|
||||
@@ -85,6 +101,25 @@ local function send_visitors_iq(conference_service, room, type)
|
||||
module:send(visitors_iq);
|
||||
end
|
||||
|
||||
-- Filter out identity information (nick name, email, etc) from a presence stanza,
|
||||
-- if the hideDisplayNameForGuests option for the room is set (note that the
|
||||
-- hideDisplayNameForAll option is implemented in a diffrent way and does not
|
||||
-- require filtering here)
|
||||
-- This is applied to presence of main room participants before it is sent out to
|
||||
-- vnodes.
|
||||
local function filter_stanza_nick_if_needed(stanza, room)
|
||||
if not stanza or stanza.name ~= 'presence' or stanza.attr.type == 'error' or stanza.attr.type == 'unavailable' then
|
||||
return stanza;
|
||||
end
|
||||
|
||||
-- if hideDisplayNameForGuests we want to drop any display name from the presence stanza
|
||||
if room and (room._data.hideDisplayNameForGuests or room._data.hideDisplayNameForAll) then
|
||||
return filter_identity_from_presence(stanza);
|
||||
end
|
||||
|
||||
return stanza;
|
||||
end
|
||||
|
||||
-- an event received from visitors component, which receives iqs from jicofo
|
||||
local function connect_vnode(event)
|
||||
local room, vnode = event.room, event.vnode;
|
||||
@@ -111,7 +146,7 @@ local function connect_vnode(event)
|
||||
|
||||
for _, o in room:each_occupant() do
|
||||
if not is_admin(o.bare_jid) then
|
||||
local fmuc_pr = st.clone(o:get_presence());
|
||||
local fmuc_pr = filter_stanza_nick_if_needed(st.clone(o:get_presence()), room);
|
||||
local user, _, res = jid.split(o.nick);
|
||||
fmuc_pr.attr.to = jid.join(user, conference_service , res);
|
||||
fmuc_pr.attr.from = o.jid;
|
||||
@@ -194,7 +229,8 @@ end, 900);
|
||||
process_host_module(main_muc_component_config, function(host_module, host)
|
||||
-- detects presence change in a main participant and propagate it to the used visitor nodes
|
||||
host_module:hook('muc-occupant-pre-change', function (event)
|
||||
local room, stanza, occupant = event.room, event.stanza, event.dest_occupant;
|
||||
local room, stanzaEv, occupant = event.room, event.stanza, event.dest_occupant;
|
||||
local stanza = filter_stanza_nick_if_needed(stanzaEv, room);
|
||||
|
||||
-- filter focus and configured domains (used for jibri and transcribers)
|
||||
if is_admin(stanza.attr.from) or visitors_nodes[room.jid] == nil
|
||||
@@ -215,7 +251,8 @@ process_host_module(main_muc_component_config, function(host_module, host)
|
||||
|
||||
-- when a main participant leaves inform the visitor nodes
|
||||
host_module:hook('muc-occupant-left', function (event)
|
||||
local room, stanza, occupant = event.room, event.stanza, event.occupant;
|
||||
local room, stanzaEv, occupant = event.room, event.stanza, event.occupant;
|
||||
local stanza = filter_stanza_nick_if_needed(stanzaEv, room);
|
||||
|
||||
-- ignore configured domains (jibri and transcribers)
|
||||
if is_admin(occupant.bare_jid) or visitors_nodes[room.jid] == nil or visitors_nodes[room.jid].nodes == nil
|
||||
@@ -258,7 +295,8 @@ process_host_module(main_muc_component_config, function(host_module, host)
|
||||
|
||||
-- detects new participants joining main room and sending them to the visitor nodes
|
||||
host_module:hook('muc-occupant-joined', function (event)
|
||||
local room, stanza, occupant = event.room, event.stanza, event.occupant;
|
||||
local room, stanzaEv, occupant = event.room, event.stanza, event.occupant;
|
||||
local stanza = filter_stanza_nick_if_needed(stanzaEv, room);
|
||||
|
||||
-- filter focus, ignore configured domains (jibri and transcribers)
|
||||
if is_admin(stanza.attr.from) or visitors_nodes[room.jid] == nil
|
||||
@@ -282,7 +320,8 @@ process_host_module(main_muc_component_config, function(host_module, host)
|
||||
end);
|
||||
-- forwards messages from main participants to vnodes
|
||||
host_module:hook('muc-occupant-groupchat', function(event)
|
||||
local room, stanza, occupant = event.room, event.stanza, event.occupant;
|
||||
local room, stanzaEv, occupant = event.room, event.stanza, event.occupant;
|
||||
local stanza = filter_stanza_nick_if_needed(stanzaEv, room);
|
||||
|
||||
-- filter sending messages from transcribers/jibris to visitors
|
||||
if not visitors_nodes[room.jid] then
|
||||
@@ -302,7 +341,8 @@ process_host_module(main_muc_component_config, function(host_module, host)
|
||||
-- receiving messages from visitor nodes and forward them to local main participants
|
||||
-- and forward them to the rest of visitor nodes
|
||||
host_module:hook('muc-occupant-groupchat', function(event)
|
||||
local occupant, room, stanza = event.occupant, event.room, event.stanza;
|
||||
local occupant, room, stanzaEv = event.occupant, event.room, event.stanza;
|
||||
local stanza = filter_stanza_nick_if_needed(stanzaEv, room);
|
||||
local to = stanza.attr.to;
|
||||
local from = stanza.attr.from;
|
||||
local from_vnode = jid.host(from);
|
||||
@@ -370,23 +410,17 @@ process_host_module(main_muc_component_config, function(host_module, host)
|
||||
end, -2);
|
||||
end);
|
||||
|
||||
module:hook('jitsi-lobby-enabled', function(event)
|
||||
local function update_vnodes_for_room(event)
|
||||
local room = event.room;
|
||||
if visitors_nodes[room.jid] then
|
||||
-- we need to update all vnodes
|
||||
local vnodes = visitors_nodes[room.jid].nodes;
|
||||
for conference_service in pairs(vnodes) do
|
||||
send_visitors_iq(conference_service, room, 'update');
|
||||
if visitors_nodes[room.jid] then
|
||||
-- we need to update all vnodes
|
||||
local vnodes = visitors_nodes[room.jid].nodes;
|
||||
for conference_service in pairs(vnodes) do
|
||||
send_visitors_iq(conference_service, room, 'update');
|
||||
end
|
||||
end
|
||||
end
|
||||
end);
|
||||
module:hook('jitsi-lobby-disabled', function(event)
|
||||
local room = event.room;
|
||||
if visitors_nodes[room.jid] then
|
||||
-- we need to update all vnodes
|
||||
local vnodes = visitors_nodes[room.jid].nodes;
|
||||
for conference_service in pairs(vnodes) do
|
||||
send_visitors_iq(conference_service, room, 'update');
|
||||
end
|
||||
end
|
||||
end);
|
||||
end
|
||||
|
||||
module:hook('jitsi-lobby-enabled', update_vnodes_for_room);
|
||||
module:hook('jitsi-lobby-disabled', update_vnodes_for_room);
|
||||
module:hook('jitsi-filesharing-updated', update_vnodes_for_room);
|
||||
|
@@ -23,6 +23,9 @@ local new_id = require 'util.id'.medium;
|
||||
local json = require 'cjson.safe';
|
||||
local inspect = require 'inspect';
|
||||
|
||||
-- Debug flag
|
||||
local DEBUG = false;
|
||||
|
||||
-- will be initialized once the main virtual host module is initialized
|
||||
local token_util;
|
||||
|
||||
@@ -63,6 +66,17 @@ local visitors_promotion_requests = {};
|
||||
local cache = require 'util.cache';
|
||||
local sent_iq_cache = cache.new(200);
|
||||
|
||||
-- Function to get visitors room metadata
|
||||
local function get_visitors_room_metadata(room)
|
||||
if not room.jitsiMetadata then
|
||||
room.jitsiMetadata = {};
|
||||
end
|
||||
if not room.jitsiMetadata.visitors then
|
||||
room.jitsiMetadata.visitors = {};
|
||||
end
|
||||
return room.jitsiMetadata.visitors;
|
||||
end
|
||||
|
||||
-- Sends a json-message to the destination jid
|
||||
-- @param to_jid the destination jid
|
||||
-- @param json_message the message content to send
|
||||
@@ -73,9 +87,14 @@ function send_json_message(to_jid, json_message)
|
||||
end
|
||||
|
||||
local function request_promotion_received(room, from_jid, from_vnode, nick, time, user_id, group_id, force_promote_requested)
|
||||
if DEBUG then
|
||||
module:log('debug', 'Received promotion request from %s for room %s, nick: %s, time: %s, user_id: %s, group_id: %s, force_promote_requested: %s',
|
||||
from_jid, room.jid, nick, time, user_id, group_id, force_promote_requested);
|
||||
end
|
||||
|
||||
-- if visitors is enabled for the room
|
||||
if visitors_promotion_map[room.jid] then
|
||||
local force_promote = auto_allow_promotion;
|
||||
local force_promote = auto_allow_promotion or get_visitors_room_metadata(room).autoPromote;
|
||||
if not force_promote and force_promote_requested == 'true' then
|
||||
-- Let's do the force_promote checks if requested
|
||||
-- if it is vpaas meeting we trust the moderator computation from visitor node (value of force_promote_requested)
|
||||
@@ -231,16 +250,6 @@ function get_visitors_languages(room)
|
||||
return count, languages:sort():concat(',');
|
||||
end
|
||||
|
||||
local function get_visitors_room_metadata(room)
|
||||
if not room.jitsiMetadata then
|
||||
room.jitsiMetadata = {};
|
||||
end
|
||||
if not room.jitsiMetadata.visitors then
|
||||
room.jitsiMetadata.visitors = {};
|
||||
end
|
||||
return room.jitsiMetadata.visitors;
|
||||
end
|
||||
|
||||
-- listens for iq request for promotion and forward it to moderators in the meeting for approval
|
||||
-- or auto-allow it if such the config is set enabling it
|
||||
local function stanza_handler(event)
|
||||
@@ -250,6 +259,10 @@ local function stanza_handler(event)
|
||||
return;
|
||||
end
|
||||
|
||||
if DEBUG then
|
||||
module:log('debug', 'Received stanza %s from %s', stanza, origin.full_jid);
|
||||
end
|
||||
|
||||
if stanza.attr.type == 'result' and sent_iq_cache:get(stanza.attr.id) then
|
||||
sent_iq_cache:set(stanza.attr.id, nil);
|
||||
return true;
|
||||
@@ -367,6 +380,11 @@ local function process_promotion_response(room, id, approved)
|
||||
return;
|
||||
end
|
||||
|
||||
if DEBUG then
|
||||
module:log('debug', 'Processing promotion response for room %s, id %s, approved %s',
|
||||
room.jid, id, approved);
|
||||
end
|
||||
|
||||
-- lets reply to participant that requested promotion
|
||||
local username = new_id():lower();
|
||||
visitors_promotion_map[room.jid][username] = {
|
||||
@@ -400,13 +418,24 @@ end
|
||||
-- if room metadata does not have visitors.live set to `true` and there are no occupants in the meeting
|
||||
-- it will skip calling goLive endpoint
|
||||
local function go_live(room)
|
||||
|
||||
if DEBUG then
|
||||
module:log('debug', 'Checking if room %s is live', room.jid);
|
||||
end
|
||||
|
||||
if room._jitsi_go_live_sent then
|
||||
if DEBUG then
|
||||
module:log('debug', 'Room %s already sent go live request, skipping', room.jid);
|
||||
end
|
||||
return;
|
||||
end
|
||||
|
||||
-- if missing we assume room is live, only skip if it is marked explicitly as false
|
||||
if room.jitsiMetadata and room.jitsiMetadata.visitors
|
||||
and room.jitsiMetadata.visitors.live ~= nil and room.jitsiMetadata.visitors.live == false then
|
||||
if DEBUG then
|
||||
module:log('debug', 'Room %s is not live, skipping go live request', room.jid);
|
||||
end
|
||||
return;
|
||||
end
|
||||
|
||||
@@ -420,6 +449,9 @@ local function go_live(room)
|
||||
|
||||
-- when there is an occupant then go live
|
||||
if not has_occupant then
|
||||
if DEBUG then
|
||||
module:log('debug', 'Room %s has no occupants, skipping go live request', room.jid);
|
||||
end
|
||||
return;
|
||||
end
|
||||
|
||||
@@ -461,6 +493,10 @@ process_host_module(muc_domain_prefix..'.'..muc_domain_base, function(host_modul
|
||||
local room, stanza, occupant, session = event.room, event.stanza, event.occupant, event.origin;
|
||||
|
||||
if is_healthcheck_room(room.jid) or is_admin(occupant.bare_jid) then
|
||||
if DEBUG then
|
||||
module:log('debug', 'Skipping visitor checks for healthcheck room %s or admin %s',
|
||||
room.jid, occupant.bare_jid);
|
||||
end
|
||||
return;
|
||||
end
|
||||
|
||||
@@ -472,12 +508,20 @@ process_host_module(muc_domain_prefix..'.'..muc_domain_base, function(host_modul
|
||||
join:tag('password', { xmlns = MUC_NS }):text(room:get_password());
|
||||
end
|
||||
|
||||
-- we skip any checks when auto-allow is enabled
|
||||
if auto_allow_promotion
|
||||
local is_live = get_visitors_room_metadata(room).live;
|
||||
|
||||
-- we skip any checks when auto-allow is enabled and room is live
|
||||
if (auto_allow_promotion or get_visitors_room_metadata(room).autoPromote and (is_live or is_live == nil))
|
||||
or ignore_list:contains(jid.host(stanza.attr.from)) -- jibri or other domains to ignore
|
||||
or is_sip_jigasi(stanza)
|
||||
or is_sip_jibri_join(stanza) then
|
||||
return;
|
||||
or is_sip_jibri_join(stanza)
|
||||
or table_find(room._data.moderators, session.jitsi_meet_context_user and session.jitsi_meet_context_user.id)
|
||||
or (room._data.moderator_id and room._data.moderator_id == (session.jitsi_meet_context_user and session.jitsi_meet_context_user.id))
|
||||
or table_find(room._data.participants, session.jitsi_meet_context_user and session.jitsi_meet_context_user.id) then
|
||||
if DEBUG then
|
||||
module:log('debug', 'Auto-allowing visitor %s in room %s', stanza.attr.from, room.jid);
|
||||
end
|
||||
return;
|
||||
end
|
||||
|
||||
if visitors_promotion_map[room.jid] then
|
||||
@@ -514,6 +558,16 @@ process_host_module(muc_domain_prefix..'.'..muc_domain_base, function(host_modul
|
||||
:tag('no-main-participants', { xmlns = 'jitsi:visitors' }));
|
||||
return true;
|
||||
end
|
||||
elseif room._data.participants then
|
||||
-- This is non jaas room which has a list of participants allowed to participate in the main room
|
||||
-- but this occupant is not one of them and the room is either not live or has no participants joined
|
||||
session.log('warn',
|
||||
'Deny user join in the main not live meeting, not in the list of main participants');
|
||||
session.send(st.error_reply(
|
||||
stanza, 'cancel', 'not-allowed',
|
||||
'Tried to join the main (not live or without main participants) room')
|
||||
:tag('not-live-room', { xmlns = 'jitsi:visitors' }));
|
||||
return true;
|
||||
end
|
||||
|
||||
end, 7); -- after muc_meeting_id, the logic for not joining before jicofo
|
||||
@@ -525,8 +579,16 @@ process_host_module(muc_domain_prefix..'.'..muc_domain_base, function(host_modul
|
||||
host_module:hook('muc-occupant-joined', function (event)
|
||||
local room, occupant = event.room, event.occupant;
|
||||
|
||||
if DEBUG then
|
||||
module:log('debug', 'Occupant %s joined room %s', occupant.jid, room.jid);
|
||||
end
|
||||
|
||||
if is_healthcheck_room(room.jid) or is_admin(occupant.bare_jid) or occupant.role ~= 'moderator' -- luacheck: ignore
|
||||
or not visitors_promotion_requests[event.room.jid] then
|
||||
if DEBUG then
|
||||
module:log('debug', 'Skipping visitor checks for healthcheck room %s or admin %s or not moderator %s',
|
||||
room.jid, occupant.bare_jid, occupant.role);
|
||||
end
|
||||
return;
|
||||
end
|
||||
|
||||
|
@@ -259,13 +259,10 @@ end
|
||||
-- Utility function to check whether feature is present and enabled. Allow
|
||||
-- a feature if there are features present in the session(coming from
|
||||
-- the token) and the value of the feature is true.
|
||||
-- If features are missing but we have granted_features check that
|
||||
-- if features are missing from the token we check whether it is moderator
|
||||
function is_feature_allowed(ft, features, granted_features, is_moderator)
|
||||
function is_feature_allowed(ft, features, is_moderator)
|
||||
if features then
|
||||
return features[ft] == "true" or features[ft] == true;
|
||||
elseif granted_features then
|
||||
return granted_features[ft] == "true" or granted_features[ft] == true;
|
||||
else
|
||||
return is_moderator;
|
||||
end
|
||||
@@ -585,7 +582,7 @@ function process_host_module(name, callback)
|
||||
module:log('info', 'No host/component found, will wait for it: %s', name)
|
||||
|
||||
-- when a host or component is added
|
||||
prosody.events.add_handler('host-activated', process_host);
|
||||
prosody.events.add_handler('host-activated', process_host, -100); -- make sure everything is loaded
|
||||
else
|
||||
process_host(name);
|
||||
end
|
||||
@@ -600,7 +597,7 @@ function table_shallow_copy(t)
|
||||
end
|
||||
|
||||
local function table_find(tab, val)
|
||||
if not tab then
|
||||
if not tab or val == nil then
|
||||
return nil
|
||||
end
|
||||
|
||||
@@ -619,6 +616,44 @@ local function table_add(t1, t2)
|
||||
end
|
||||
end
|
||||
|
||||
-- Returns as a first result the removed items and as a second the added items
|
||||
local function table_compare(old_table, new_table)
|
||||
local removed = {}
|
||||
local added = {}
|
||||
local modified = {}
|
||||
|
||||
-- Find removed items (in old but not in new)
|
||||
for id, value in pairs(old_table) do
|
||||
if new_table[id] == nil then
|
||||
table.insert(removed, id)
|
||||
elseif new_table[id] ~= value then
|
||||
table.insert(modified, id)
|
||||
end
|
||||
end
|
||||
|
||||
-- Find added items (in new but not in old)
|
||||
for id, _ in pairs(new_table) do
|
||||
if old_table[id] == nil then
|
||||
table.insert(added, id)
|
||||
end
|
||||
end
|
||||
|
||||
return removed, added, modified
|
||||
end
|
||||
|
||||
local function table_equals(t1, t2)
|
||||
if t1 == nil then
|
||||
return t2 == nil;
|
||||
end
|
||||
if t2 == nil then
|
||||
return t1 == nil;
|
||||
end
|
||||
|
||||
local removed, added, modified = table_compare(t1, t2);
|
||||
|
||||
return next(removed) == nil and next(added) == nil and next(modified) == nil
|
||||
end
|
||||
|
||||
-- Splits a string using delimiter
|
||||
function split_string(str, delimiter)
|
||||
str = str .. delimiter;
|
||||
@@ -666,11 +701,35 @@ local function is_admin(_jid)
|
||||
return false;
|
||||
end
|
||||
|
||||
-- Filter out identity information (nick name, email, etc) from a presence stanza.
|
||||
local function filter_identity_from_presence(orig_stanza)
|
||||
local stanza = st.clone(orig_stanza);
|
||||
|
||||
stanza:remove_children('nick', 'http://jabber.org/protocol/nick');
|
||||
stanza:remove_children('email');
|
||||
stanza:remove_children('stats-id');
|
||||
local identity = stanza:get_child('identity');
|
||||
if identity then
|
||||
local user = identity:get_child('user');
|
||||
local name = identity:get_child('name');
|
||||
if user then
|
||||
user:remove_children('email');
|
||||
user:remove_children('name');
|
||||
end
|
||||
if name then
|
||||
name:remove_children('name'); -- Remove name with no namespace
|
||||
end
|
||||
end
|
||||
|
||||
return stanza;
|
||||
end
|
||||
|
||||
return {
|
||||
OUTBOUND_SIP_JIBRI_PREFIXES = OUTBOUND_SIP_JIBRI_PREFIXES;
|
||||
INBOUND_SIP_JIBRI_PREFIXES = INBOUND_SIP_JIBRI_PREFIXES;
|
||||
RECORDER_PREFIXES = RECORDER_PREFIXES;
|
||||
extract_subdomain = extract_subdomain;
|
||||
filter_identity_from_presence = filter_identity_from_presence;
|
||||
is_admin = is_admin;
|
||||
is_feature_allowed = is_feature_allowed;
|
||||
is_jibri = is_jibri;
|
||||
@@ -700,6 +759,8 @@ return {
|
||||
starts_with = starts_with;
|
||||
starts_with_one_of = starts_with_one_of;
|
||||
table_add = table_add;
|
||||
table_compare = table_compare;
|
||||
table_shallow_copy = table_shallow_copy;
|
||||
table_find = table_find;
|
||||
table_equals = table_equals;
|
||||
};
|
||||
|
@@ -3,9 +3,9 @@
|
||||
jitsi_root_dir: /opt/jitsi
|
||||
jitsi_user: jitsi
|
||||
|
||||
jitsi_videobridge_version: "{{ jitsi_version | default('10314') }}"
|
||||
jitsi_videobridge_version: "{{ jitsi_version | default('10431') }}"
|
||||
jitsi_videobridge_archive_url: https://github.com/jitsi/jitsi-videobridge/archive/refs/tags/stable/jitsi-meet_{{ jitsi_videobridge_version }}.tar.gz
|
||||
jitsi_videobridge_archive_sha256: 55ffb62de63c7280b4e2a6c25045da9c6f3e07c20f28d1b697510231ae56f8bf
|
||||
jitsi_videobridge_archive_sha256: 57d29c7d24c5f0657efbadabd54d3efa34c587a05c7a2196dca5e3c56141b44a
|
||||
|
||||
jitsi_videobridge_rtp_port: 10000
|
||||
jitsi_videobridge_src_ip:
|
||||
|
@@ -31,6 +31,8 @@ metabase_db_server: "{{ (metabase_db_engine == 'mysql') | ternary(mysql_server,
|
||||
metabase_db_port: "{{ (metabase_db_engine == 'mysql') | ternary('3306', '5432') }}"
|
||||
metabase_db_name: metabase
|
||||
metabase_db_user: metabase
|
||||
# Should ansible try to create user and db on the server. If false, the user and the database must already exist
|
||||
metabase_db_create: true
|
||||
# A random pass will be generated and stored in the meta dir if not defined
|
||||
# metabase_db_pass: S3cr3t.
|
||||
|
||||
|
@@ -92,10 +92,14 @@
|
||||
- db_user: "{{ metabase_db_user }}"
|
||||
- db_server: "{{ metabase_db_server }}"
|
||||
- db_pass: "{{ metabase_db_pass }}"
|
||||
when: metabase_db_engine == 'mysql'
|
||||
when:
|
||||
- metabase_db_engine == 'mysql'
|
||||
- metabase_db_create
|
||||
tags: metabase
|
||||
|
||||
- when: metabase_db_engine == 'postgres'
|
||||
- when:
|
||||
- metabase_db_engine == 'postgres'
|
||||
- metabase_db_create
|
||||
block:
|
||||
- name: Install postgresql client
|
||||
package: name=postgresql16
|
||||
|
@@ -34,4 +34,4 @@
|
||||
|
||||
- name: Create vector config dir
|
||||
file: path=/etc/vector/conf.d state=directory
|
||||
tags: log,mkdir
|
||||
tags: log,mkdir,vector
|
||||
|
@@ -18,5 +18,6 @@ transforms:
|
||||
} else if (.file == "/var/log/nginx/error.log"){
|
||||
.http = parse_nginx_log!(.message, format:"error")
|
||||
}
|
||||
.timestamp = parse_timestamp(del(.http.timestamp), format: "%d/%h/%Y:%H:%M:%S %z") ?? now()
|
||||
.service = "nginx"
|
||||
.group = "web"
|
||||
|
@@ -1,3 +1,3 @@
|
||||
---
|
||||
|
||||
nodejs_major_version: 18
|
||||
nodejs_major_version: 22
|
||||
|
@@ -1,7 +1,7 @@
|
||||
[nodejs]
|
||||
baseurl = https://rpm.nodesource.com/pub_{{ nodejs_major_version }}.x/el/{{ ansible_distribution_major_version }}/$basearch
|
||||
baseurl = https://rpm.nodesource.com/pub_{{ nodejs_major_version }}.x/nodistro/nodejs/$basearch
|
||||
gpgcheck = 1
|
||||
gpgkey = https://rpm.nodesource.com/pub/el/NODESOURCE-GPG-SIGNING-KEY-EL
|
||||
gpgkey = https://rpm.nodesource.com/gpgkey/ns-operations-public.key
|
||||
name = Node.js Packages for Enterprise Linux
|
||||
{% if ansible_os_family == 'RedHat' and ansible_distribution_major_version is version('8', '>=') %}
|
||||
# Workaround a bug in dnf which would make the default module mask
|
||||
|
@@ -17,4 +17,5 @@ transforms:
|
||||
.message = string!(.message)
|
||||
if (is_json(.message)) {
|
||||
.samba = parse_json!(.message)
|
||||
.timestamp = parse_timestamp(del(.samba.timestamp), format: "%FT%H:%M:%S%.f%z") ?? now()
|
||||
}
|
||||
|
@@ -25,3 +25,5 @@
|
||||
- include_tasks: cleanup.yml
|
||||
tags: always
|
||||
|
||||
- include_tasks: vector.yml
|
||||
tags: always
|
||||
|
5
roles/vault/tasks/vector.yml
Normal file
5
roles/vault/tasks/vector.yml
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
|
||||
- name: Deploy vector configuration
|
||||
template: src=vector.yml dest=/etc/vector/conf.d/vault.yml
|
||||
tags: log,vault,vector
|
18
roles/vault/templates/vector.yml
Normal file
18
roles/vault/templates/vector.yml
Normal file
@@ -0,0 +1,18 @@
|
||||
---
|
||||
|
||||
sources:
|
||||
in_logs_vault:
|
||||
type: file
|
||||
include:
|
||||
- /opt/vault/log/audit.json
|
||||
|
||||
transforms:
|
||||
format_logs_vault:
|
||||
type: remap
|
||||
inputs: ["in_logs_vault"]
|
||||
source: |
|
||||
.message = string!(.message)
|
||||
if (is_json(.message)) {
|
||||
.vault = parse_json!(.message)
|
||||
.timestamp = parse_timestamp(del(.vault.time), format: "%FT%H:%M:%S%.fZ", timezone: "UTC") ?? now()
|
||||
}
|
@@ -1,7 +1,7 @@
|
||||
# Version of Vault to install
|
||||
vault_version: 1.20.0
|
||||
vault_version: 1.20.1
|
||||
# URL of the archive
|
||||
vault_archive_url: https://releases.hashicorp.com/vault/{{ vault_version }}/vault_{{ vault_version }}_linux_amd64.zip
|
||||
# Expected sha256 of the archive
|
||||
vault_archive_sha256: 25e9f1f9a6dd9866219d6a37c6d1af1d26d0e73aa95a4e755188751de133dea7
|
||||
vault_archive_sha256: e3ce3e678421c0d56f726952ab100875168c2e1eb1db751ed5a2b25b6b2ea96f
|
||||
|
||||
|
Reference in New Issue
Block a user