mirror of
https://git.lapiole.org/dani/ansible-roles.git
synced 2025-06-29 14:33:19 +02:00
202 lines
7.4 KiB
Lua
202 lines
7.4 KiB
Lua
![]() |
-- this is auto loaded by meeting_id
|
||
|
local filters = require 'util.filters';
|
||
|
local jid = require 'util.jid';
|
||
|
|
||
|
local util = module:require 'util';
|
||
|
local is_admin = util.is_admin;
|
||
|
local get_room_from_jid = util.get_room_from_jid;
|
||
|
local is_healthcheck_room = util.is_healthcheck_room;
|
||
|
local room_jid_match_rewrite = util.room_jid_match_rewrite;
|
||
|
local ends_with = util.ends_with;
|
||
|
local presence_check_status = util.presence_check_status;
|
||
|
|
||
|
local MUC_NS = 'http://jabber.org/protocol/muc';
|
||
|
|
||
|
local muc_domain_prefix = module:get_option_string('muc_mapper_domain_prefix', 'conference');
|
||
|
|
||
|
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.');
|
||
|
return ;
|
||
|
end
|
||
|
|
||
|
-- only the visitor prosody has main_domain setting
|
||
|
local is_visitor_prosody = module:get_option_string('main_domain') ~= nil;
|
||
|
|
||
|
-- load it only on the main muc component as it is loaded by muc_meeting_id which is loaded and for the breakout room muc
|
||
|
if muc_domain_prefix..'.'..muc_domain_base ~= module.host or is_visitor_prosody then
|
||
|
return;
|
||
|
end
|
||
|
|
||
|
local sessions = prosody.full_sessions;
|
||
|
local default_permissions;
|
||
|
|
||
|
local function load_config()
|
||
|
default_permissions = module:get_option('jitsi_default_permissions', {
|
||
|
livestreaming = true;
|
||
|
recording = true;
|
||
|
transcription = true;
|
||
|
['outbound-call'] = true;
|
||
|
['create-polls'] = true;
|
||
|
['send-groupchat'] = true;
|
||
|
flip = true;
|
||
|
});
|
||
|
end
|
||
|
load_config();
|
||
|
|
||
|
function process_set_affiliation(event)
|
||
|
local actor, affiliation, jid, previous_affiliation, room
|
||
|
= event.actor, event.affiliation, event.jid, event.previous_affiliation, event.room;
|
||
|
local actor_session = sessions[actor];
|
||
|
|
||
|
if is_admin(jid) or is_healthcheck_room(room.jid) or not actor or not previous_affiliation
|
||
|
or not actor_session or not actor_session.jitsi_meet_context_features then
|
||
|
return;
|
||
|
end
|
||
|
|
||
|
local occupant;
|
||
|
for _, o in room:each_occupant() do
|
||
|
if o.bare_jid == jid then
|
||
|
occupant = o;
|
||
|
end
|
||
|
end
|
||
|
|
||
|
if not occupant then
|
||
|
return;
|
||
|
end
|
||
|
|
||
|
local occupant_session = sessions[occupant.jid];
|
||
|
if not occupant_session then
|
||
|
return;
|
||
|
end
|
||
|
|
||
|
if previous_affiliation == 'none' and affiliation == 'owner' then
|
||
|
occupant_session.granted_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;
|
||
|
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;
|
||
|
|
||
|
-- on revoke
|
||
|
if not session.auth_token then
|
||
|
occupant_session.jitsi_meet_context_features = nil;
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
-- Detects when sending self-presence because of role change
|
||
|
-- we can end up here because of the following cases:
|
||
|
-- 1. user joins the room and is granted moderator by another moderator or jicofo
|
||
|
-- 2. Some module changes the role of the user by using set_affiliation method
|
||
|
-- In cases where authentication is 'anonymous', 'jitsi-anonymous', 'internal_hashed', 'internal_plain', 'cyrus' we
|
||
|
-- want to send default permissions all to indicate UI that everything is allowed (to not relay on the UI to check
|
||
|
-- is participant moderator or not), to allow finer control over the permissions.
|
||
|
-- In case the authentication is 'token' based we want to send permissions only if the token of the user does not include
|
||
|
-- features in the user.context.
|
||
|
-- In case of allowners we want to send the permissions, no matter of the authentication method.
|
||
|
-- In case permissions were granted we want to send the granted permissions in all cases except when the user is
|
||
|
-- using token that has features pre-defined (authentication is 'token').
|
||
|
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);
|
||
|
if is_admin(bare_to) then
|
||
|
return stanza;
|
||
|
end
|
||
|
|
||
|
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 is_healthcheck_room(room.jid) then
|
||
|
return stanza;
|
||
|
end
|
||
|
|
||
|
if not room.send_default_permissions_to then
|
||
|
room.send_default_permissions_to = {};
|
||
|
end
|
||
|
|
||
|
if not session.force_permissions_update then
|
||
|
if session.auth_token and session.jitsi_meet_context_features then -- token and features are set so skip
|
||
|
room.send_default_permissions_to[bare_to] = nil;
|
||
|
return stanza;
|
||
|
end
|
||
|
|
||
|
-- we are sending permissions only when becoming a member
|
||
|
local is_moderator = false;
|
||
|
for item in muc_x:childtags('item') do
|
||
|
if item.attr.role == 'moderator' then
|
||
|
is_moderator = true;
|
||
|
break;
|
||
|
end
|
||
|
end
|
||
|
|
||
|
if not is_moderator then
|
||
|
return stanza;
|
||
|
end
|
||
|
|
||
|
if not room.send_default_permissions_to[bare_to] then
|
||
|
return stanza;
|
||
|
end
|
||
|
end
|
||
|
|
||
|
session.force_permissions_update = false;
|
||
|
|
||
|
local permissions_to_send
|
||
|
= session.jitsi_meet_context_features or session.granted_jitsi_meet_context_features or default_permissions;
|
||
|
|
||
|
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
|
||
|
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();
|
||
|
|
||
|
return stanza;
|
||
|
end
|
||
|
|
||
|
-- we need to indicate that we will send permissions if we need to
|
||
|
-- we need to handle granted features and stuff in the pre-set hook so they are unavailable
|
||
|
-- when the self presence is set, so we can update the client, the checks
|
||
|
-- whether the actor is allowed to set the affiliation are done before pre-set hook is fired
|
||
|
module:hook('muc-pre-set-affiliation', function(event)
|
||
|
local jid, room = event.jid, event.room;
|
||
|
|
||
|
if not room.send_default_permissions_to then
|
||
|
room.send_default_permissions_to = {};
|
||
|
end
|
||
|
room.send_default_permissions_to[jid] = true;
|
||
|
|
||
|
process_set_affiliation(event);
|
||
|
end);
|
||
|
|
||
|
function filter_session(session)
|
||
|
-- domain mapper is filtering on default priority 0
|
||
|
-- allowners is -1 and we need it after that
|
||
|
filters.add_filter(session, 'stanzas/out', filter_stanza, -2);
|
||
|
end
|
||
|
|
||
|
-- enable filtering presences
|
||
|
filters.add_filter_hook(filter_session);
|