view mod_flags/mod_flags.lua @ 6214:cc5c0f1dc89b

mod_muc_anonymize_moderation_actions: Fix mentioning Virtualhost for MUC, Compatibility section and License. diff --git a/mod_muc_anonymize_moderation_actions/README.md b/mod_muc_anonymize_moderation_actions/README.md --- a/mod_muc_anonymize_moderation_actions/README.md +++ b/mod_muc_anonymize_moderation_actions/README.md @@ -1,8 +1,10 @@ -<!-- -SPDX-FileCopyrightText: 2024 John Livingston <https://www.john-livingston.fr/> -SPDX-License-Identifier: AGPL-3.0-only ---> -# mod_muc_anonymize_moderation_actions +--- +labels: +- 'Stage-Alpha' +summary: Anonymize moderator actions for participants +--- + +## Introduction This modules allows to anonymize affiliation and role changes in MUC rooms. @@ -11,13 +13,10 @@ When the feature is enabled, when a mode This is particularly usefull to prevent some revenge when a moderator bans someone. -This module is under AGPL-3.0 license. - -It was tested on Prosody 0.12.x. ## Configuration -Just enable the module on your MUC VirtualHost. +Just enable the module on your MUC Component. The feature will be accessible throught the room configuration form. You can tweak the position of the settings in the MUC configuration form using `anonymize_moderation_actions_form_position`. @@ -26,7 +25,20 @@ This value will be passed as priority fo By default, the field will be between muc#roomconfig_changesubject and muc#roomconfig_moderatedroom (default value is `78`). ``` lua -VirtualHost "muc.example.com" +Component "muc.example.com" "muc" modules_enabled = { "muc_anonymize_moderation_actions" } anonymize_moderation_actions_form_position = 96 ``` + +## Compatibility + + ------ ---------------------- + trunk Works as of 25-05-12 + 0.13 Works + 0.12 Works + ------ ---------------------- + +### License + +SPDX-FileCopyrightText: 2024 John Livingston <https://www.john-livingston.fr/> +SPDX-License-Identifier: AGPL-3.0-only
author Menel <menel@snikket.de>
date Mon, 12 May 2025 10:42:26 +0200
parents ffec70ddbffc
children
line wrap: on
line source

-- This module is only for 0.12, later versions have mod_flags bundled
--% conflicts: mod_flags

local flags_map;
if prosody.process_type ~= "prosodyctl" then
	flags_map = module:open_store("account_flags", "map");
end

-- API

function add_flag(username, flag, comment) -- luacheck: ignore 131/add_flag
	local flag_data = {
		when = os.time();
		comment = comment;
	};

	local ok, err = flags_map:set(username, flag, flag_data);
	if not ok then
		return nil, err;
	end

	module:fire_event("user-flag-added/"..flag, {
		user = username;
		flag = flag;
		data = flag_data;
	});

	return true;
end

function remove_flag(username, flag) -- luacheck: ignore 131/remove_flag
	local ok, err = flags_map:set(username, flag, nil);
	if not ok then
		return nil, err;
	end

	module:fire_event("user-flag-removed/"..flag, {
		user = username;
		flag = flag;
	});

	return true;
end

function has_flag(username, flag) -- luacheck: ignore 131/has_flag
	local ok, err = flags_map:get(username, flag);
	if not ok and err then
		error("Failed to check flags for user: "..err);
	end
	return not not ok;
end

function get_flag_info(username, flag) -- luacheck: ignore 131/get_flag_info
	return flags_map:get(username, flag);
end


-- Migration from mod_firewall marks

local function migrate_marks(host)
	local usermanager = require "core.usermanager";

	local flag_storage = module:open_store("account_flags");
	local mark_storage = module:open_store("firewall_marks");

	local migration_comment = "Migrated from mod_firewall marks at "..os.date("%Y-%m-%d %R");

	local migrated, empty, errors = 0, 0, 0;
	for username in usermanager.users(host) do
		local marks, err = mark_storage:get(username);
		if marks then
			local flags = {};
			for mark_name, mark_timestamp in pairs(marks) do
				flags[mark_name] = {
					when = mark_timestamp;
					comment = migration_comment;
				};
			end
			local saved_ok, saved_err = flag_storage:set(username, flags);
			if saved_ok then
				prosody.log("error", "Failed to save flags for %s: %s", username, saved_err);
				migrated = migrated + 1;
			else
				errors = errors + 1;
			end
		elseif err then
			prosody.log("error", "Failed to load marks for %s: %s", username, err);
			errors = errors + 1;
		else
			empty = empty + 1;
		end
	end

	print(("Finished - %d migrated, %d users with no marks, %d errors"):format(migrated, empty, errors));
end

function module.command(arg)
	local storagemanager = require "core.storagemanager";
	local usermanager = require "core.usermanager";
	local jid = require "util.jid";
	local warn = require"util.prosodyctl".show_warning;

	local command = arg[1];
	if not command then
		warn("Valid subcommands: migrate_marks");
		return 0;
	end
	table.remove(arg, 1);

	local node, host = jid.prepped_split(arg[1]);
	if not host then
		warn("Please specify a host or JID after the command");
		return 1;
	elseif not prosody.hosts[host] then
		warn("Unknown host: "..host);
		return 1;
	end

	table.remove(arg, 1);

	module.host = host; -- luacheck: ignore 122
	storagemanager.initialize_host(host);
	usermanager.initialize_host(host);

	flags_map = module:open_store("account_flags", "map");

	if command == "migrate_marks" then
		migrate_marks(host);
		return 0;
	elseif command == "find" then
		local flag = assert(arg[1], "expected argument: flag");
		local flags = module:open_store("account_flags", "map");
		local users_with_flag = flags:get_all(flag);

		local c = 0;
		for user, flag_data in pairs(users_with_flag) do
			print(user, os.date("%Y-%m-%d %R", flag_data.when), flag_data.comment or "");
			c = c + 1;
		end

		print(("%d accounts listed"):format(c));
		return 1;
	elseif command == "add" then
		local username = assert(node, "expected a user JID, got "..host);
		local flag = assert(arg[1], "expected argument: flag");
		local comment = arg[2];

		local ok, err = add_flag(username, flag, comment);
		if not ok then
			print("Failed to add flag: "..err);
			return 1;
		end

		print("Flag added");
		return 1;
	elseif command == "remove" then
		local username = assert(node, "expected a user JID, got "..host);
		local flag = assert(arg[1], "expected argument: flag");

		local ok, err = remove_flag(username, flag);
		if not ok then
			print("Failed to remove flag: "..err);
			return 1;
		end

		print("Flag removed");
		return 1;
	elseif command == "list" then
		local username = assert(node, "expected a user JID, got "..host);

		local c = 0;

		local flags = module:open_store("account_flags");
		local user_flags, err = flags:get(username);

		if not user_flags and err then
			print("Unable to list flags: "..err);
			return 1;
		end

		if user_flags then
			for flag_name, flag_data in pairs(user_flags) do
				print(flag_name, os.date("%Y-%m-%d %R", flag_data.when), flag_data.comment or "");
				c = c + 1;
			end
		end

		print(("%d flags listed"):format(c));
		return 0;
	else
		warn("Unknown command: %s", command);
		return 1;
	end
end