From 0294b0e7e0b834b46d400779ad9f53f9e83ec6bc Mon Sep 17 00:00:00 2001 From: Matthew Wild Date: Mon, 8 Nov 2021 16:13:07 +0000 Subject: [PATCH] prosody: Prevent restricted users from creating public channels (#37) --- ansible/files/prosody.cfg.lua | 5 +- .../mod_snikket_restricted_users.lua | 52 +++++++++++++++---- 2 files changed, 47 insertions(+), 10 deletions(-) diff --git a/ansible/files/prosody.cfg.lua b/ansible/files/prosody.cfg.lua index a63ec33..e448264 100644 --- a/ansible/files/prosody.cfg.lua +++ b/ansible/files/prosody.cfg.lua @@ -241,8 +241,11 @@ Component ("groups."..DOMAIN) "muc" } restrict_room_creation = "local" muc_local_only = { "general@groups."..DOMAIN } - muc_room_default_persistent = true + + -- Default configuration for rooms (typically overwritten by the client) muc_room_default_allow_member_invites = true + muc_room_default_persistent = true + muc_room_default_public = false default_mucs = { { diff --git a/snikket-modules/mod_snikket_restricted_users/mod_snikket_restricted_users.lua b/snikket-modules/mod_snikket_restricted_users/mod_snikket_restricted_users.lua index 58a42f2..80dfe3e 100644 --- a/snikket-modules/mod_snikket_restricted_users/mod_snikket_restricted_users.lua +++ b/snikket-modules/mod_snikket_restricted_users/mod_snikket_restricted_users.lua @@ -1,16 +1,50 @@ local jid_bare = require "util.jid".bare; local um_get_roles = require "core.usermanager".get_roles; -local function check_user_isolated(event) - local session = event.session; - if not session.no_host_isolation then - local bare_jid = jid_bare(session.full_jid); - local roles = um_get_roles(bare_jid, module.host); - if roles and not roles["prosody:restricted"] then - -- Bypass isolation for all unrestricted users - session.no_host_isolation = true; +local function load_main_host(module) + local function check_user_isolated(event) + local session = event.session; + if not session.no_host_isolation then + local bare_jid = jid_bare(session.full_jid); + local roles = um_get_roles(bare_jid, module.host); + if roles and not roles["prosody:restricted"] then + -- Bypass isolation for all unrestricted users + session.no_host_isolation = true; + end end end + + module:hook("resource-bind", check_user_isolated, -0.5); end -module:hook("resource-bind", check_user_isolated, -0.5); +local function load_groups_host(module) + local primary_host = module.host:gsub("^%a+%.", ""); + + local function is_restricted(user_jid) + local roles = um_get_roles(user_jid, primary_host); + return not roles or roles["prosody:restricted"]; + end + + module:hook("muc-config-submitted/muc#roomconfig_publicroom", function (event) + if not is_restricted(event.stanza.attr.from) then return; end + -- Don't allow modification of this value by restricted users + return true; + end, 5); + + module:hook("muc-config-form", function (event) + if not is_restricted(event.stanza.attr.from) then return; end -- Don't restrict admins + -- Hide the option from the config form for restricted users + local form = event.form; + for i = #form, 1, -1 do + if form[i].name == "muc#roomconfig_publicroom" then + table.remove(form, i); + end + end + end); +end + +if module:get_host_type() == "component" and module:get_option_string("component_module") == "muc" then + load_groups_host(module); +else + load_main_host(module); +end