Jitsi Token Moderation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Token moderation | |
-- this module looks for a field on incoming JWT tokens called "moderator". | |
-- If it is true the user is added to the room as a moderator, otherwise they are set to a normal user. | |
-- Note this may well break other affiliation based features like banning or login-based admins | |
local log = module._log; | |
local jid_bare = require "util.jid".bare; | |
local json = require "cjson"; | |
local basexx = require "basexx"; | |
local um_is_admin = require "core.usermanager".is_admin; | |
local function is_admin(jid) | |
return um_is_admin(jid, module.host); | |
end | |
log('info', 'Loaded token moderation plugin'); | |
-- Hook into room creation to add this wrapper to every new room | |
module:hook("muc-room-created", function(event) | |
log('info', 'room created, adding token moderation code'); | |
local room = event.room | |
local _set_affiliation = room.set_affiliation; | |
room.set_affiliation = function(room, actor, jid, affiliation, reason); | |
if actor == "token_plugin" then | |
return _set_affiliation(room, true, jid, affiliation, reason); | |
elseif affiliation == "owner" then | |
log('debug', 'set_affiliation: room=%s, actor=%s, jid=%s, affiliation=%s, reason=%s', room, actor, jid, affiliation, reason); | |
if string.match(tostring(actor), "focus@") then | |
log('debug', 'set_affiliation not acceptable, focus user'); | |
return nil, "modify", "not-acceptable"; | |
else | |
return _set_affiliation(room, actor, jid, affiliation, reason); | |
end; | |
else | |
return _set_affiliation(room, actor, jid, affiliation, reason); | |
end; | |
end; | |
end); | |
module:hook("muc-occupant-joined", function(event) | |
log('info', 'occupant joined, checking token for ownership'); | |
setupAffiliation(event.room, event.origin, event.stanza); | |
end); | |
function setupAffiliation(room, origin, stanza) | |
if origin.auth_token then | |
-- Extract token body and decode it | |
local dotFirst = origin.auth_token:find("%."); | |
if dotFirst then | |
local dotSecond = origin.auth_token:sub(dotFirst + 1):find("%."); | |
if dotSecond then | |
local bodyB64 = origin.auth_token:sub(dotFirst + 1, dotFirst + dotSecond - 1); | |
local body = json.decode(basexx.from_url64(bodyB64)); | |
local jid = jid_bare(stanza.attr.from); | |
-- If user is a moderator or an admin, set their affiliation to be an owner | |
if body["moderator"] == true or is_admin(jid) then | |
room:set_affiliation("token_plugin", jid, "owner"); | |
else | |
room:set_affiliation("token_plugin", jid, "member"); | |
end; | |
end; | |
end; | |
end; | |
end; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local log = module._log; | |
local http = require "net.http"; | |
local json = require "util.json"; | |
local is_healthcheck_room = module:require "util".is_healthcheck_room; | |
local jid_split = require "util.jid".split; | |
local pre_jibri_user = os.getenv("JIBRI_RECORDER_USER") | |
local pre_jibri_domain = os.getenv("XMPP_RECORDER_DOMAIN") | |
local webhook_url = os.getenv("WEBHOOK_URL") | |
local webhook_token = os.getenv("WEBHOOK_TOKEN") | |
log('info', 'Loaded webhook plugin'); | |
function make_http_request(params) | |
params.token=webhook_token; | |
http.request(webhook_url,{ | |
body = json.encode(params); | |
}, function (response_text, code, response) | |
if code == 200 or code == 204 then | |
log('info', 'Webhook: Request response (%s)', code); | |
else | |
log('error', 'Webhook: Request error (%s) - %s', code, response_text); | |
end | |
return ; | |
end); | |
end; | |
-- Hook to assign meetingId for new rooms | |
module:hook("muc-room-created", function(event) | |
local room = event.room; | |
local roomId = jid_split(room.jid); | |
if is_healthcheck_room(room.jid) then | |
return; | |
end | |
log('info', 'Webhook: Sala %s criada!', roomId); | |
local params = { | |
room = roomId, | |
event = "room_created" | |
}; | |
make_http_request(params); | |
end); | |
-- Hook to assign meetingId for destroyed rooms | |
module:hook("muc-room-destroyed", function(event) | |
local room = event.room; | |
local roomId = jid_split(room.jid); | |
if is_healthcheck_room(room.jid) then | |
return; | |
end | |
log('info', 'Webhook: Sala %s removida!', roomId); | |
local params = { | |
room = roomId, | |
event = "room_closed" | |
}; | |
make_http_request(params); | |
end); | |
-- Hook to assign meetingId for recordings rooms | |
module:hook("muc-occupant-joined", function (event) | |
local occupant, room, stanza = event.occupant, event.room, event.stanza; | |
if is_healthcheck_room(room.jid) then | |
return; | |
end | |
local roomId = jid_split(room.jid); | |
local user, domain, res = jid_split(stanza.attr.from); | |
if ( user == pre_jibri_user and domain == pre_jibri_domain ) then | |
log('info', 'Webhook: Gravação da sala %s - Iniciada', roomId); | |
local params = { | |
room = roomId, | |
event = "recording_started" | |
}; | |
make_http_request(params); | |
else | |
-- local userId = getUserId(origin); | |
local presence = occupant:get_presence(); | |
if presence and presence:get_child("identity") and presence:get_child("identity"):get_child("user") then | |
local userId = presence:get_child("identity"):get_child("user"):get_child_text("id"); | |
log('info', 'Webhook: Usuário %s entrou na sala', userId); | |
local params = { | |
room = roomId, | |
user = userId, | |
event = "user_joined" | |
}; | |
make_http_request(params); | |
end | |
end; | |
end); | |
-- Hook to assign meetingId for recordings rooms | |
module:hook("muc-occupant-left", function (event) | |
local occupant, room, stanza = event.occupant, event.room, event.stanza; | |
if is_healthcheck_room(room.jid) then | |
return; | |
end | |
local roomId = jid_split(room.jid); | |
local user, domain, res = jid_split(stanza.attr.from); | |
if ( user == pre_jibri_user and domain == pre_jibri_domain ) then | |
log('info', 'Webhook: Gravação da sala %s - Encerrada', roomId); | |
local params = { | |
room = roomId, | |
event = "recording_ended" | |
}; | |
make_http_request(params); | |
else | |
-- local userId = getUserId(origin); | |
local presence = occupant:get_presence(); | |
if presence and presence:get_child("identity") and presence:get_child("identity"):get_child("user") then | |
local userId = presence:get_child("identity"):get_child("user"):get_child_text("id"); | |
log('info', 'Webhook: Usuário %s saiu da sala', userId); | |
local params = { | |
room = roomId, | |
user = userId, | |
event = "user_left" | |
}; | |
make_http_request(params); | |
end | |
end; | |
end); | |
module:hook('muc-set-affiliation', function (event) | |
local affiliation, previous_affiliation, actor, room, jid = event.affiliation, event.previous_affiliation, event.actor, event.room, event.jid; | |
if actor and previous_affiliation ~= 'owner' and affiliation == 'owner' then | |
local roomId = jid_split(room.jid); | |
local occupant = nil; | |
for _, occupant_r in room:each_occupant() do | |
if occupant_r.bare_jid == jid then | |
occupant = occupant_r; | |
break | |
end | |
end | |
if occupant then | |
local presence = occupant:get_presence(); | |
local userId = presence:get_child("identity"):get_child("user"):get_child_text("id"); | |
log('info', 'Webhook: Moderador atribuído para %s', userId); | |
local params = { | |
room = roomId, | |
user = userId, | |
event = "grant_permission" | |
}; | |
make_http_request(params); | |
end | |
end | |
end) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment