Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Delegate authorization from groups.$DOMAIN to $DOMAIN #157

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions ansible/files/prosody.cfg.lua
Original file line number Diff line number Diff line change
Expand Up @@ -263,9 +263,14 @@ Component ("groups."..DOMAIN) "muc"
"muc_offline_delivery";
"snikket_restricted_users";
"muc_auto_reserve_nicks";
"snikket_circle_muc_protection";
}
restrict_room_creation = "local"
muc_local_only = { "general@groups."..DOMAIN }
circle_muc_protection_main_domain = DOMAIN

authorization = "delegate"
authz_delegate_to = DOMAIN

-- Default configuration for rooms (typically overwritten by the client)
muc_room_default_allow_member_invites = true
Expand Down
2 changes: 1 addition & 1 deletion ansible/snikket.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
package: "prosody-trunk"
snapshot: "2023-03-31"
prosody_modules:
revision: "5178c13deb78"
revision: "98d5acb93439"
tasks:
- import_tasks: tasks/prosody.yml
- import_tasks: tasks/supervisor.yml
Expand Down
2 changes: 2 additions & 0 deletions ansible/tasks/prosody.yml
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@
- mod_measure_malloc
- mod_http_xep227
- mod_portcheck
- mod_authz_delegate

- name: Enable wanted modules (snikket-modules)
file:
Expand All @@ -129,6 +130,7 @@
- mod_snikket_client_id
- mod_snikket_ios_preserve_push
- mod_snikket_restricted_users
- mod_snikket_circle_muc_protection

- name: "Install lua-ossl for encrypted push notifications"
apt:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
--[[
The purpose of this module is to avoid accidental modification of the member
list by users.

With mod_authz_delegate enabled, snikket admins suddenly are granted ownership
on circle MUCs; while this is great for setting avatars, it is problematic
when considering that this also allows affiliation changes which would not be
reflected in the circle membership, causing all kinds of desyncs.

This is a first order solution to this challenge. Future solutions may allow
more modifications as well as synchronisation between MUC affiliation lists
and circle membership or stuff like that.

We want to get a release shipped which allows setting avatars first :-).
]]
local modulemanager = require"core.modulemanager";
local st = require "prosody.util.stanza";

local main_host_name = module:get_option("circle_muc_protection_main_domain");
local main_host_groups = nil;

local function get_groups_module()
if main_host_groups then
return main_host_groups;
end

module:log("debug", "lazy-initializing MUC protection module");
if not main_host_name then
return error("main host name required for circle MUC affiliation protection")
end

local target_module = modulemanager.get_module(main_host_name, "groups_internal");
if not target_module then
return error("groups_internal not available on "..main_host_name);
end

main_host_groups = target_module;
return target_module;
end

local function get_muc_circle(muc_jid)
for group_id in get_groups_module().groups() do
local group_data = main_host_groups.get_info(group_id);
if group_data.muc_jid == muc_jid then
return group_id
end
end
return nil
end

module:hook("muc-pre-set-affiliation", function(event)
if event.actor == nil then
module:log("debug", "affiliation change in %s granted because the actor is nil.", event.room.jid);
return;
end
local group_id = get_muc_circle(event.room.jid);
if group_id ~= nil then
module:log("warn", "affiliation change blocked as %s is associated with circle %s", event.room.jid, group_id);
event.allowed = false;
else
module:log("debug", "affiliation change not blocked as %s is not associated with any circle", event.room.jid);
end
end);

module:hook("muc-pre-invite", function(event)
local room = event.room;
local group_id = get_muc_circle(room.jid);
if group_id ~= nil then
module:log("warn", "invite blocked as %s is associated with circle %s", room.jid, group_id);
event.origin.send(st.error_reply(event.stanza, "cancel", "not-allowed", nil, room.jid));
return true;
else
module:log("debug", "invite not blocked as %s is not associated with any circle", event.room.jid);
end
end, -1); -- run after the main members_only permission check