Created
September 16, 2021 06:26
-
-
Save ashiqhassan95/0ab2174474b8fe5f763a4e42c8578375 to your computer and use it in GitHub Desktop.
Assign role based JWT token
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 custom plugin assign affiliation to occupant based on JWT payload. | |
-- Skip assigning affiliation on unavaiability of JWT for occupant. | |
-- | |
-- By default deployment of Jitsi meet with secure domain enabled instance, | |
-- jicofo assign owner (moderator) affiliation to all the authenticated user (having JWT). | |
-- | |
-- This plugin override the function set_affiliation of room object in room creation hook to prevent | |
-- assigning affiliation from Jifoco (focus user) to authenticated user joining the conference (with JWT). | |
-- | |
-- We want to grant owner affiliation to the occupant with JWT payload having affiliation: 'moderator' | |
-- all else will get member affiliation. | |
-- | |
-- Sample JWT payload | |
-- { | |
-- "context": { | |
-- "user": { | |
-- "avatar": "image_url", | |
-- "name": "Ashiq Hassan", | |
-- "email": "ashiq@example.com", | |
-- "id": "ashiq", | |
-- "affiliation": "moderator" | |
-- } | |
-- }, | |
-- "room": "kvss-v6shm-54gs", | |
-- "iat": 1629803006, | |
-- "aud": "APP_JITSI", | |
-- "iss": "APP_JITSI", | |
-- "sub": "meet.example.com" | |
-- } | |
-- | |
--------------------- | |
-- Instruction -- | |
--------------------- | |
-- 1. Add this plugin in Prosody plugins directory of your jitsi meet. | |
-- It mostly is /usr/share/jitsi-meet/prosody-plugins/ | |
-- | |
-- sudo nano /usr/share/jitsi-meet/prosody-plugins/mod_inf_token_moderation.lua | |
-- | |
-- 2. Enable this plugin in your prosody config. | |
-- Add "inf_token_moderation" in the modules_enabled = {} of Component "conference.YOUR_DOMAIN.com" "muc" | |
-- | |
-- sudo nano /etc/prosody/conf.d/YOUR_DOMAIN.cfg.lua | |
-- | |
-- Component "conference.YOUR_DOMAIN" "muc" | |
-- restrict_room_creation = true | |
-- storage = "memory" | |
-- modules_enabled = { | |
-- ... | |
-- ... | |
-- "token_verification"; | |
-- "token_moderation"; | |
-- } | |
-- | |
-- 3. Restart depended services | |
-- | |
-- sudo service jicofo restart | |
-- sudo service prosody restart | |
-- | |
---------------------- | |
local um_is_admin = require"core.usermanager".is_admin; | |
local is_healthcheck_room = module:require "util".is_healthcheck_room; | |
local LOGLEVEL = "debug"; | |
local function is_admin(jid) | |
return um_is_admin(jid, module.host); | |
end | |
module:log(LOGLEVEL, "Loaded token moderation plugin"); | |
-- Hook into room creation in the conference to override to add this wrapper to every new room | |
module:hook("muc-room-created", function(event) | |
module:log(LOGLEVEL, "room created, adding token moderation code"); | |
local room = event.room; | |
-- Retrieve default set_affiliation function of this room. | |
local _set_affiliation = room.set_affiliation; | |
-- Overrid set_affiliation function of this room into custom created below. | |
room.set_affiliation = function(room, actor, jid, affiliation, reason) | |
if actor == "token_plugin" then | |
-- Triggered set_affiliation from this plugin module. | |
return _set_affiliation(room, true, jid, affiliation, reason); | |
elseif affiliation == "owner" then | |
module:log(LOGLEVEL, "set_affiliation: room=%s, actor=%s, jid=%s, affiliation=%s, reason=%s", room, actor, | |
jid, affiliation, reason); | |
if string.match(tostring(actor), "focus@") then | |
module:log(LOGLEVEL, "set_affiliation not acceptable, focus user"); | |
-- Just respond to jicofo with mock replay that affiliation assigned (actually not) | |
return true; -- nil, "modify", "not-acceptable"; | |
end | |
end | |
-- Triggered set_affiliation from somewhere not in this plugin module | |
return _set_affiliation(room, actor, jid, affiliation, reason); | |
end; | |
end); | |
-- Hook into occupant join in the conference to assign affiliation based on JWT token | |
module:hook("muc-occupant-joined", function(event) | |
module:log(LOGLEVEL, "occupant joined, checking token for ownership"); | |
local room, occupant, origin = event.room, event.occupant, event.origin; | |
-- Skip affiliation for admin users | |
if is_healthcheck_room(room.jid) or is_admin(occupant.jid) then | |
module:log(LOGLEVEL, "skip affiliation, %s", occupant.jid); | |
return; | |
end | |
-- Check token exist in this occupant | |
if not origin.auth_token then | |
module:log(LOGLEVEL, "skip affiliation, no token"); | |
return; | |
end | |
-- Default to member | |
local affiliation = "member"; | |
-- Retrieve occupant token payload | |
local context_user = origin.jitsi_meet_context_user; | |
if context_user then | |
if context_user.affiliation == "owner" or context_user.affiliation == "moderator" then | |
affiliation = "owner"; | |
end | |
end | |
module:log(LOGLEVEL, "Assigned %s affiliation to %s", affiliation, occupant.jid); | |
-- Assign affiliation to occupant | |
room:set_affiliation("token_plugin", occupant.bare_jid, affiliation); | |
end); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment