File

mod_blocking/mod_blocking.lua @ 161:fda7faee7677

mod_blocking: XEP-0191 Simple Communications Blocking, should work, but not tested. Requires mod_privacy be loaded.
author Matthew Wild <mwild1@gmail.com>
date Thu, 03 Jun 2010 01:56:49 +0100
child 163:9fe6d314fd07
line wrap: on
line source

module:add_feature("urn:xmpp:blocking");

-- Add JID to default privacy list
function add_blocked_jid(username, host, jid)
	local privacy_lists = datamanager.load(username, host, "privacy") or {};
	local default_list_name = privacy_lists.default;
	if not default_list_name then
		default_list_name = "blocklist";
		privacy_lists.default = default_list_name;
	end
	local default_list = privacy_lists.list[default_list_name];
	if not default_list then
		default_list = { name = default_list_name, items = {} };
		privacy_lists.lists[default_list_name] = default_list;
	end
	local items = default_list.items;
	local order = items[1].order; -- Must come first
	for i=1,#items do -- order must be unique
		items[i].order = items[i].order + 1;
	end
	table.insert(items, 1, { type = "jid"
		, action = "deny"
		, value = jid
		, message = false
		, ["presence-out"] = false
		, ["presence-in"] = false
		, iq = false
		, order = order
	};
	datamanager.store(username, host, "privacy", privacy_lists);
end

-- Remove JID from default privacy list
function remove_blocked_jid(username, host, jid)
	local privacy_lists = datamanager.load(username, host, "privacy") or {};
	local default_list_name = privacy_lists.default;
	if not default_list_name then return; end
	local default_list = privacy_lists.list[default_list_name];
	if not default_list then return; end
	local items = default_list.items;
	local item;
	for i=1,#items do -- order must be unique
		item = items[i];
		if item.type == "jid" and item.value == jid then
			table.remove(items, i);
			return true;
		end
	end
end

function get_blocked_jids(username, host)
	-- Return array of blocked JIDs in default privacy list
	local privacy_lists = datamanager.load(username, host, "privacy") or {};
	local default_list_name = privacy_lists.default;
	if not default_list_name then return {}; end
	local default_list = privacy_lists.list[default_list_name];
	if not default_list then return {}; end
	local items = default_list.items;
	local item;
	local jid_list = {};
	for i=1,#items do -- order must be unique
		item = items[i];
		if item.type == "jid" then
			jid_list[#jid_list+1] = item.value;
		end
	end
	return jid_list;
end

function handle_blocking_command(session, stanza)
	local username, host = jid_split(stanza.attr.from);
	if stanza.attr.type == "set" and stanza.tags[1].name == "block" then
		local block = stanza.tags[1]:get_child("block");
		local block_jid_list = {};
		for item in block:childtags() do
			block_jid_list[#block_jid_list+1] = item.attr.jid;
		end
		if #block_jid_list == 0 then
			--FIXME: Reply bad-request
		else
			for _, jid in ipairs(block_jid_list) do
				add_blocked_jid(username, host, jid);
			end
			session.send(st.reply(stanza));
		end
	elseif stanza.attr.type == "get" and stanza.tags[1].name == "blocklist" then
		local reply = st.reply(stanza):tag("blocklist", { xmlns = xmlns_block });
		local blocked_jids = get_blocked_jids(username, host);
		for _, jid in ipairs(blocked_jids) do
			reply:tag("item", { jid = jid }):up();
		end
		session.send(reply);
	else
		--FIXME: Need to respond with service-unavailable
	end
end

module:add_iq_handler("c2s", xmlns_blocking, handle_blocking_command);