plugins/mod_blocklist.lua
author Kim Alvefur <zash@zash.se>
Sun, 24 Mar 2024 20:39:42 +0100
changeset 13466 720aed1f5cf2
parent 13349 a74251a790ed
child 13485 1c87c0a7ece6
permissions -rw-r--r--
util.startup: Check root after detecting platform and reading config (thanks SigmaTel71) Ensures that startup.detect_platform() runs so know whether to use the POSIX method of checking the current user or something else. Also after reading the config so we know whether the root override setting is set.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
6344
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     1
-- Prosody IM
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     2
-- Copyright (C) 2009-2010 Matthew Wild
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     3
-- Copyright (C) 2009-2010 Waqas Hussain
6979
4688ff9d4f2b mod_blocklist: Update Copyright header
Kim Alvefur <zash@zash.se>
parents: 6978
diff changeset
     4
-- Copyright (C) 2014-2015 Kim Alvefur
6344
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     5
--
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     6
-- This project is MIT/X11 licensed. Please see the
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     7
-- COPYING file in the source package for more information.
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     8
--
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     9
-- This module implements XEP-0191: Blocking Command
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    10
--
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    11
12981
74b9e05af71e plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12779
diff changeset
    12
local user_exists = require"prosody.core.usermanager".user_exists;
74b9e05af71e plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12779
diff changeset
    13
local rostermanager = require"prosody.core.rostermanager";
6977
bdb216e0688a mod_blocklist: When blocking someone who sent a subscription request, forget that request since the user would be unable to deny it while blocked (Fixes #574)
Kim Alvefur <zash@zash.se>
parents: 6976
diff changeset
    14
local is_contact_subscribed = rostermanager.is_contact_subscribed;
bdb216e0688a mod_blocklist: When blocking someone who sent a subscription request, forget that request since the user would be unable to deny it while blocked (Fixes #574)
Kim Alvefur <zash@zash.se>
parents: 6976
diff changeset
    15
local is_contact_pending_in = rostermanager.is_contact_pending_in;
bdb216e0688a mod_blocklist: When blocking someone who sent a subscription request, forget that request since the user would be unable to deny it while blocked (Fixes #574)
Kim Alvefur <zash@zash.se>
parents: 6976
diff changeset
    16
local load_roster = rostermanager.load_roster;
bdb216e0688a mod_blocklist: When blocking someone who sent a subscription request, forget that request since the user would be unable to deny it while blocked (Fixes #574)
Kim Alvefur <zash@zash.se>
parents: 6976
diff changeset
    17
local save_roster = rostermanager.save_roster;
12981
74b9e05af71e plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12779
diff changeset
    18
local st = require"prosody.util.stanza";
6344
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    19
local st_error_reply = st.error_reply;
12981
74b9e05af71e plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12779
diff changeset
    20
local jid_prep = require"prosody.util.jid".prep;
74b9e05af71e plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12779
diff changeset
    21
local jid_split = require"prosody.util.jid".split;
6344
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    22
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    23
local storage = module:open_store();
6632
42aeb882b3e1 mod_blocklist: Some cleanup [luacheck]
Kim Alvefur <zash@zash.se>
parents: 6534
diff changeset
    24
local sessions = prosody.hosts[module.host].sessions;
8278
13dad833e821 mod_blocklist: Drop messages to existing full JIDs in order to prevent issues with MUC PMs, fixes #690
Kim Alvefur <zash@zash.se>
parents: 8043
diff changeset
    25
local full_sessions = prosody.full_sessions;
6344
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    26
13349
a74251a790ed mod_blocklist: Remove weak cache (and increase default LRU cache size)
Kim Alvefur <zash@zash.se>
parents: 13217
diff changeset
    27
-- Cache of blocklists, keeps a fixed number of items.
6973
cde7d14052f9 mod_blocklist: Expand comments on caching of blocklists
Kim Alvefur <zash@zash.se>
parents: 6972
diff changeset
    28
--
cde7d14052f9 mod_blocklist: Expand comments on caching of blocklists
Kim Alvefur <zash@zash.se>
parents: 6972
diff changeset
    29
-- The size of this affects how often we will need to load a blocklist from
cde7d14052f9 mod_blocklist: Expand comments on caching of blocklists
Kim Alvefur <zash@zash.se>
parents: 6972
diff changeset
    30
-- disk, which we want to avoid during routing. On the other hand, we don't
cde7d14052f9 mod_blocklist: Expand comments on caching of blocklists
Kim Alvefur <zash@zash.se>
parents: 6972
diff changeset
    31
-- want to use too much memory either, so this can be tuned by advanced
cde7d14052f9 mod_blocklist: Expand comments on caching of blocklists
Kim Alvefur <zash@zash.se>
parents: 6972
diff changeset
    32
-- users. TODO use science to figure out a better default, 64 is just a guess.
13349
a74251a790ed mod_blocklist: Remove weak cache (and increase default LRU cache size)
Kim Alvefur <zash@zash.se>
parents: 13217
diff changeset
    33
local cache_size = module:get_option_integer("blocklist_cache_size", 256, 1);
a74251a790ed mod_blocklist: Remove weak cache (and increase default LRU cache size)
Kim Alvefur <zash@zash.se>
parents: 13217
diff changeset
    34
local blocklist_cache = require"prosody.util.cache".new(cache_size);
6344
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    35
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    36
local null_blocklist = {};
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    37
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    38
module:add_feature("urn:xmpp:blocking");
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    39
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    40
local function set_blocklist(username, blocklist)
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    41
	local ok, err = storage:set(username, blocklist);
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    42
	if not ok then
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    43
		return ok, err;
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    44
	end
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    45
	-- Successful save, update the cache
13349
a74251a790ed mod_blocklist: Remove weak cache (and increase default LRU cache size)
Kim Alvefur <zash@zash.se>
parents: 13217
diff changeset
    46
	blocklist_cache:set(username, blocklist);
6344
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    47
	return true;
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    48
end
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    49
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    50
-- Migrates from the old mod_privacy storage
12779
1dd468c63a3d mod_blocklist: Add option 'migrate_legacy_blocking' to disable migration from mod_privacy
Kim Alvefur <zash@zash.se>
parents: 10115
diff changeset
    51
-- TODO mod_privacy was removed in 0.10.0, this should be phased out
6344
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    52
local function migrate_privacy_list(username)
7775
752697d68fda mod_blocklist: Return early from migration if no valid privacy list data is found
Kim Alvefur <zash@zash.se>
parents: 7774
diff changeset
    53
	local legacy_data = module:open_store("privacy"):get(username);
752697d68fda mod_blocklist: Return early from migration if no valid privacy list data is found
Kim Alvefur <zash@zash.se>
parents: 7774
diff changeset
    54
	if not legacy_data or not legacy_data.lists or not legacy_data.default then return; end
752697d68fda mod_blocklist: Return early from migration if no valid privacy list data is found
Kim Alvefur <zash@zash.se>
parents: 7774
diff changeset
    55
	local default_list = legacy_data.lists[legacy_data.default];
752697d68fda mod_blocklist: Return early from migration if no valid privacy list data is found
Kim Alvefur <zash@zash.se>
parents: 7774
diff changeset
    56
	if not default_list or not default_list.items then return; end
752697d68fda mod_blocklist: Return early from migration if no valid privacy list data is found
Kim Alvefur <zash@zash.se>
parents: 7774
diff changeset
    57
7774
2b288dab781a mod_blocklist: Make the 'false' metadata field a table so we can store timestamps and other useful data
Kim Alvefur <zash@zash.se>
parents: 7624
diff changeset
    58
	local migrated_data = { [false] = { created = os.time(); migrated = "privacy" }};
7775
752697d68fda mod_blocklist: Return early from migration if no valid privacy list data is found
Kim Alvefur <zash@zash.se>
parents: 7774
diff changeset
    59
7776
7fd26815fcf6 mod_blocklist: Remove one indentation level
Kim Alvefur <zash@zash.se>
parents: 7775
diff changeset
    60
	module:log("info", "Migrating blocklist from mod_privacy storage for user '%s'", username);
7777
1f55edac1f72 mod_blocklist: Simplify loop with ipairs
Kim Alvefur <zash@zash.se>
parents: 7776
diff changeset
    61
	for _, item in ipairs(default_list.items) do
7776
7fd26815fcf6 mod_blocklist: Remove one indentation level
Kim Alvefur <zash@zash.se>
parents: 7775
diff changeset
    62
		if item.type == "jid" and item.action == "deny" then
7777
1f55edac1f72 mod_blocklist: Simplify loop with ipairs
Kim Alvefur <zash@zash.se>
parents: 7776
diff changeset
    63
			local jid = jid_prep(item.value);
7776
7fd26815fcf6 mod_blocklist: Remove one indentation level
Kim Alvefur <zash@zash.se>
parents: 7775
diff changeset
    64
			if not jid then
10115
0f335815244f plugins: Remove tostring call from logging
Kim Alvefur <zash@zash.se>
parents: 10058
diff changeset
    65
				module:log("warn", "Invalid JID in privacy store for user '%s' not migrated: %s", username, item.value);
7776
7fd26815fcf6 mod_blocklist: Remove one indentation level
Kim Alvefur <zash@zash.se>
parents: 7775
diff changeset
    66
			else
7fd26815fcf6 mod_blocklist: Remove one indentation level
Kim Alvefur <zash@zash.se>
parents: 7775
diff changeset
    67
				migrated_data[jid] = true;
6344
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    68
			end
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    69
		end
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    70
	end
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    71
	set_blocklist(username, migrated_data);
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    72
	return migrated_data;
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    73
end
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    74
12779
1dd468c63a3d mod_blocklist: Add option 'migrate_legacy_blocking' to disable migration from mod_privacy
Kim Alvefur <zash@zash.se>
parents: 10115
diff changeset
    75
if not module:get_option_boolean("migrate_legacy_blocking", true) then
1dd468c63a3d mod_blocklist: Add option 'migrate_legacy_blocking' to disable migration from mod_privacy
Kim Alvefur <zash@zash.se>
parents: 10115
diff changeset
    76
	migrate_privacy_list = function (username)
1dd468c63a3d mod_blocklist: Add option 'migrate_legacy_blocking' to disable migration from mod_privacy
Kim Alvefur <zash@zash.se>
parents: 10115
diff changeset
    77
		module:log("debug", "Migrating from mod_privacy disabled, user '%s' will start with a fresh blocklist", username);
1dd468c63a3d mod_blocklist: Add option 'migrate_legacy_blocking' to disable migration from mod_privacy
Kim Alvefur <zash@zash.se>
parents: 10115
diff changeset
    78
		return nil;
1dd468c63a3d mod_blocklist: Add option 'migrate_legacy_blocking' to disable migration from mod_privacy
Kim Alvefur <zash@zash.se>
parents: 10115
diff changeset
    79
	end
1dd468c63a3d mod_blocklist: Add option 'migrate_legacy_blocking' to disable migration from mod_privacy
Kim Alvefur <zash@zash.se>
parents: 10115
diff changeset
    80
end
1dd468c63a3d mod_blocklist: Add option 'migrate_legacy_blocking' to disable migration from mod_privacy
Kim Alvefur <zash@zash.se>
parents: 10115
diff changeset
    81
6344
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    82
local function get_blocklist(username)
13349
a74251a790ed mod_blocklist: Remove weak cache (and increase default LRU cache size)
Kim Alvefur <zash@zash.se>
parents: 13217
diff changeset
    83
	local blocklist = blocklist_cache:get(username);
6947
62b6f6d230f1 mod_blocklist: Use util.cache to manage how many users blocklists are kept in memory
Kim Alvefur <zash@zash.se>
parents: 6836
diff changeset
    84
	if not blocklist then
6632
42aeb882b3e1 mod_blocklist: Some cleanup [luacheck]
Kim Alvefur <zash@zash.se>
parents: 6534
diff changeset
    85
		if not user_exists(username, module.host) then
6344
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    86
			return null_blocklist;
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    87
		end
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    88
		blocklist = storage:get(username);
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    89
		if not blocklist then
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    90
			blocklist = migrate_privacy_list(username);
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    91
		end
7775
752697d68fda mod_blocklist: Return early from migration if no valid privacy list data is found
Kim Alvefur <zash@zash.se>
parents: 7774
diff changeset
    92
		if not blocklist then
752697d68fda mod_blocklist: Return early from migration if no valid privacy list data is found
Kim Alvefur <zash@zash.se>
parents: 7774
diff changeset
    93
			blocklist = { [false] = { created = os.time(); }; };
752697d68fda mod_blocklist: Return early from migration if no valid privacy list data is found
Kim Alvefur <zash@zash.se>
parents: 7774
diff changeset
    94
		end
13349
a74251a790ed mod_blocklist: Remove weak cache (and increase default LRU cache size)
Kim Alvefur <zash@zash.se>
parents: 13217
diff changeset
    95
		blocklist_cache:set(username, blocklist);
6344
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    96
	end
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    97
	return blocklist;
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    98
end
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    99
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   100
module:hook("iq-get/self/urn:xmpp:blocking:blocklist", function (event)
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   101
	local origin, stanza = event.origin, event.stanza;
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   102
	local username = origin.username;
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   103
	local reply = st.reply(stanza):tag("blocklist", { xmlns = "urn:xmpp:blocking" });
13349
a74251a790ed mod_blocklist: Remove weak cache (and increase default LRU cache size)
Kim Alvefur <zash@zash.se>
parents: 13217
diff changeset
   104
	local blocklist = get_blocklist(username);
6344
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   105
	for jid in pairs(blocklist) do
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   106
		if jid then
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   107
			reply:tag("item", { jid = jid }):up();
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   108
		end
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   109
	end
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   110
	origin.interested_blocklist = true; -- Gets notified about changes
6836
aeb088bb1a20 mod_blocklist: Explicitly halt event propagation after returning a reply (send returns nil sometimes)
Kim Alvefur <zash@zash.se>
parents: 6632
diff changeset
   111
	origin.send(reply);
aeb088bb1a20 mod_blocklist: Explicitly halt event propagation after returning a reply (send returns nil sometimes)
Kim Alvefur <zash@zash.se>
parents: 6632
diff changeset
   112
	return true;
7623
c27c9695d130 mod_blocklist: Decrease priority of iq hooks to ease handling by other modules
Kim Alvefur <zash@zash.se>
parents: 7082
diff changeset
   113
end, -1);
6344
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   114
6351
10dc228a45a4 mod_blocklist: Correct comment
Kim Alvefur <zash@zash.se>
parents: 6350
diff changeset
   115
-- Add or remove some jid(s) from the blocklist
6344
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   116
-- We want this to be atomic and not do a partial update
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   117
local function edit_blocklist(event)
9251
1d6a2cc389eb mod_blocklist: Store timestamp of blocking to allow age to be determined
Kim Alvefur <zash@zash.se>
parents: 8744
diff changeset
   118
	local now = os.time();
6344
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   119
	local origin, stanza = event.origin, event.stanza;
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   120
	local username = origin.username;
6974
96080d86bab8 mod_blocklist: Add comments describing some variables
Kim Alvefur <zash@zash.se>
parents: 6973
diff changeset
   121
	local action = stanza.tags[1]; -- "block" or "unblock"
9251
1d6a2cc389eb mod_blocklist: Store timestamp of blocking to allow age to be determined
Kim Alvefur <zash@zash.se>
parents: 8744
diff changeset
   122
	local is_blocking = action.name == "block" and now or nil; -- nil if unblocking
6974
96080d86bab8 mod_blocklist: Add comments describing some variables
Kim Alvefur <zash@zash.se>
parents: 6973
diff changeset
   123
	local new = {}; -- JIDs to block depending or unblock on action
6344
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   124
9251
1d6a2cc389eb mod_blocklist: Store timestamp of blocking to allow age to be determined
Kim Alvefur <zash@zash.se>
parents: 8744
diff changeset
   125
6976
f350f840a6f7 mod_blocklist: Restructure how we keep track of where to send unavailable presence
Kim Alvefur <zash@zash.se>
parents: 6975
diff changeset
   126
	-- XEP-0191 sayeth:
f350f840a6f7 mod_blocklist: Restructure how we keep track of where to send unavailable presence
Kim Alvefur <zash@zash.se>
parents: 6975
diff changeset
   127
	-- > When the user blocks communications with the contact, the user's
f350f840a6f7 mod_blocklist: Restructure how we keep track of where to send unavailable presence
Kim Alvefur <zash@zash.se>
parents: 6975
diff changeset
   128
	-- > server MUST send unavailable presence information to the contact (but
f350f840a6f7 mod_blocklist: Restructure how we keep track of where to send unavailable presence
Kim Alvefur <zash@zash.se>
parents: 6975
diff changeset
   129
	-- > only if the contact is allowed to receive presence notifications [...]
f350f840a6f7 mod_blocklist: Restructure how we keep track of where to send unavailable presence
Kim Alvefur <zash@zash.se>
parents: 6975
diff changeset
   130
	-- So contacts we need to do that for are added to the set below.
6978
5bc229eb99d3 mod_blocklist: Skip creating some tables and some processing if unblocking
Kim Alvefur <zash@zash.se>
parents: 6977
diff changeset
   131
	local send_unavailable = is_blocking and {};
10056
0c35f353db68 mod_blocklist: Trigger resend of presence when unblocking a contact (fixes #1380)
Kim Alvefur <zash@zash.se>
parents: 9251
diff changeset
   132
	local send_available = not is_blocking and {};
6976
f350f840a6f7 mod_blocklist: Restructure how we keep track of where to send unavailable presence
Kim Alvefur <zash@zash.se>
parents: 6975
diff changeset
   133
6977
bdb216e0688a mod_blocklist: When blocking someone who sent a subscription request, forget that request since the user would be unable to deny it while blocked (Fixes #574)
Kim Alvefur <zash@zash.se>
parents: 6976
diff changeset
   134
	-- Because blocking someone currently also blocks the ability to reject
bdb216e0688a mod_blocklist: When blocking someone who sent a subscription request, forget that request since the user would be unable to deny it while blocked (Fixes #574)
Kim Alvefur <zash@zash.se>
parents: 6976
diff changeset
   135
	-- subscription requests, we'll preemptively reject such
6978
5bc229eb99d3 mod_blocklist: Skip creating some tables and some processing if unblocking
Kim Alvefur <zash@zash.se>
parents: 6977
diff changeset
   136
	local remove_pending = is_blocking and {};
6977
bdb216e0688a mod_blocklist: When blocking someone who sent a subscription request, forget that request since the user would be unable to deny it while blocked (Fixes #574)
Kim Alvefur <zash@zash.se>
parents: 6976
diff changeset
   137
6352
b703e6930e4c mod_blocklist: Use full word as variable name, we can afford that
Kim Alvefur <zash@zash.se>
parents: 6351
diff changeset
   138
	for item in action:childtags("item") do
6632
42aeb882b3e1 mod_blocklist: Some cleanup [luacheck]
Kim Alvefur <zash@zash.se>
parents: 6534
diff changeset
   139
		local jid = jid_prep(item.attr.jid);
6344
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   140
		if not jid then
6836
aeb088bb1a20 mod_blocklist: Explicitly halt event propagation after returning a reply (send returns nil sometimes)
Kim Alvefur <zash@zash.se>
parents: 6632
diff changeset
   141
			origin.send(st_error_reply(stanza, "modify", "jid-malformed"));
aeb088bb1a20 mod_blocklist: Explicitly halt event propagation after returning a reply (send returns nil sometimes)
Kim Alvefur <zash@zash.se>
parents: 6632
diff changeset
   142
			return true;
6344
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   143
		end
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   144
		item.attr.jid = jid; -- echo back prepped
6976
f350f840a6f7 mod_blocklist: Restructure how we keep track of where to send unavailable presence
Kim Alvefur <zash@zash.se>
parents: 6975
diff changeset
   145
		new[jid] = true;
6978
5bc229eb99d3 mod_blocklist: Skip creating some tables and some processing if unblocking
Kim Alvefur <zash@zash.se>
parents: 6977
diff changeset
   146
		if is_blocking then
5bc229eb99d3 mod_blocklist: Skip creating some tables and some processing if unblocking
Kim Alvefur <zash@zash.se>
parents: 6977
diff changeset
   147
			if is_contact_subscribed(username, module.host, jid) then
5bc229eb99d3 mod_blocklist: Skip creating some tables and some processing if unblocking
Kim Alvefur <zash@zash.se>
parents: 6977
diff changeset
   148
				send_unavailable[jid] = true;
5bc229eb99d3 mod_blocklist: Skip creating some tables and some processing if unblocking
Kim Alvefur <zash@zash.se>
parents: 6977
diff changeset
   149
			elseif is_contact_pending_in(username, module.host, jid) then
5bc229eb99d3 mod_blocklist: Skip creating some tables and some processing if unblocking
Kim Alvefur <zash@zash.se>
parents: 6977
diff changeset
   150
				remove_pending[jid] = true;
5bc229eb99d3 mod_blocklist: Skip creating some tables and some processing if unblocking
Kim Alvefur <zash@zash.se>
parents: 6977
diff changeset
   151
			end
10056
0c35f353db68 mod_blocklist: Trigger resend of presence when unblocking a contact (fixes #1380)
Kim Alvefur <zash@zash.se>
parents: 9251
diff changeset
   152
		elseif is_contact_subscribed(username, module.host, jid) then
0c35f353db68 mod_blocklist: Trigger resend of presence when unblocking a contact (fixes #1380)
Kim Alvefur <zash@zash.se>
parents: 9251
diff changeset
   153
			send_available[jid] = true;
6976
f350f840a6f7 mod_blocklist: Restructure how we keep track of where to send unavailable presence
Kim Alvefur <zash@zash.se>
parents: 6975
diff changeset
   154
		end
6344
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   155
	end
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   156
6971
828a10e0464b mod_blocklist: Rename variable for clarity
Kim Alvefur <zash@zash.se>
parents: 6970
diff changeset
   157
	if is_blocking and not next(new) then
6344
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   158
		-- <block/> element does not contain at least one <item/> child element
6836
aeb088bb1a20 mod_blocklist: Explicitly halt event propagation after returning a reply (send returns nil sometimes)
Kim Alvefur <zash@zash.se>
parents: 6632
diff changeset
   159
		origin.send(st_error_reply(stanza, "modify", "bad-request"));
aeb088bb1a20 mod_blocklist: Explicitly halt event propagation after returning a reply (send returns nil sometimes)
Kim Alvefur <zash@zash.se>
parents: 6632
diff changeset
   160
		return true;
6344
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   161
	end
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   162
13349
a74251a790ed mod_blocklist: Remove weak cache (and increase default LRU cache size)
Kim Alvefur <zash@zash.se>
parents: 13217
diff changeset
   163
	local blocklist = get_blocklist(username);
6344
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   164
7774
2b288dab781a mod_blocklist: Make the 'false' metadata field a table so we can store timestamps and other useful data
Kim Alvefur <zash@zash.se>
parents: 7624
diff changeset
   165
	local new_blocklist = {
9997
02a41315d275 Fix various spelling mistakes [codespell]
Kim Alvefur <zash@zash.se>
parents: 9251
diff changeset
   166
		-- We set the [false] key to something as a signal not to migrate privacy lists
9251
1d6a2cc389eb mod_blocklist: Store timestamp of blocking to allow age to be determined
Kim Alvefur <zash@zash.se>
parents: 8744
diff changeset
   167
		[false] = blocklist[false] or { created = now; };
7774
2b288dab781a mod_blocklist: Make the 'false' metadata field a table so we can store timestamps and other useful data
Kim Alvefur <zash@zash.se>
parents: 7624
diff changeset
   168
	};
2b288dab781a mod_blocklist: Make the 'false' metadata field a table so we can store timestamps and other useful data
Kim Alvefur <zash@zash.se>
parents: 7624
diff changeset
   169
	if type(blocklist[false]) == "table" then
9251
1d6a2cc389eb mod_blocklist: Store timestamp of blocking to allow age to be determined
Kim Alvefur <zash@zash.se>
parents: 8744
diff changeset
   170
		new_blocklist[false].modified = now;
7774
2b288dab781a mod_blocklist: Make the 'false' metadata field a table so we can store timestamps and other useful data
Kim Alvefur <zash@zash.se>
parents: 7624
diff changeset
   171
	end
6344
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   172
6971
828a10e0464b mod_blocklist: Rename variable for clarity
Kim Alvefur <zash@zash.se>
parents: 6970
diff changeset
   173
	if is_blocking or next(new) then
9251
1d6a2cc389eb mod_blocklist: Store timestamp of blocking to allow age to be determined
Kim Alvefur <zash@zash.se>
parents: 8744
diff changeset
   174
		for jid, t in pairs(blocklist) do
1d6a2cc389eb mod_blocklist: Store timestamp of blocking to allow age to be determined
Kim Alvefur <zash@zash.se>
parents: 8744
diff changeset
   175
			if jid then new_blocklist[jid] = t; end
6344
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   176
		end
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   177
		for jid in pairs(new) do
6971
828a10e0464b mod_blocklist: Rename variable for clarity
Kim Alvefur <zash@zash.se>
parents: 6970
diff changeset
   178
			new_blocklist[jid] = is_blocking;
6344
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   179
		end
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   180
		-- else empty the blocklist
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   181
	end
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   182
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   183
	local ok, err = set_blocklist(username, new_blocklist);
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   184
	if ok then
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   185
		origin.send(st.reply(stanza));
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   186
	else
6836
aeb088bb1a20 mod_blocklist: Explicitly halt event propagation after returning a reply (send returns nil sometimes)
Kim Alvefur <zash@zash.se>
parents: 6632
diff changeset
   187
		origin.send(st_error_reply(stanza, "wait", "internal-server-error", err));
aeb088bb1a20 mod_blocklist: Explicitly halt event propagation after returning a reply (send returns nil sometimes)
Kim Alvefur <zash@zash.se>
parents: 6632
diff changeset
   188
		return true;
6344
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   189
	end
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   190
6971
828a10e0464b mod_blocklist: Rename variable for clarity
Kim Alvefur <zash@zash.se>
parents: 6970
diff changeset
   191
	if is_blocking then
6976
f350f840a6f7 mod_blocklist: Restructure how we keep track of where to send unavailable presence
Kim Alvefur <zash@zash.se>
parents: 6975
diff changeset
   192
		for jid in pairs(send_unavailable) do
10058
0656bd283fa2 mod_blocklist: Add comment to clarify some logic
Kim Alvefur <zash@zash.se>
parents: 10057
diff changeset
   193
			-- Check that this JID isn't already blocked, i.e. this is not a change
6976
f350f840a6f7 mod_blocklist: Restructure how we keep track of where to send unavailable presence
Kim Alvefur <zash@zash.se>
parents: 6975
diff changeset
   194
			if not blocklist[jid] then
6344
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   195
				for _, session in pairs(sessions[username].sessions) do
6498
44df423f8290 mod_blocklist: Don't send unavailable presence from unavailable sessions when blocking a contact
Kim Alvefur <zash@zash.se>
parents: 6497
diff changeset
   196
					if session.presence then
44df423f8290 mod_blocklist: Don't send unavailable presence from unavailable sessions when blocking a contact
Kim Alvefur <zash@zash.se>
parents: 6497
diff changeset
   197
						module:send(st.presence({ type = "unavailable", to = jid, from = session.full_jid }));
44df423f8290 mod_blocklist: Don't send unavailable presence from unavailable sessions when blocking a contact
Kim Alvefur <zash@zash.se>
parents: 6497
diff changeset
   198
					end
6344
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   199
				end
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   200
			end
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   201
		end
6977
bdb216e0688a mod_blocklist: When blocking someone who sent a subscription request, forget that request since the user would be unable to deny it while blocked (Fixes #574)
Kim Alvefur <zash@zash.se>
parents: 6976
diff changeset
   202
bdb216e0688a mod_blocklist: When blocking someone who sent a subscription request, forget that request since the user would be unable to deny it while blocked (Fixes #574)
Kim Alvefur <zash@zash.se>
parents: 6976
diff changeset
   203
		if next(remove_pending) then
bdb216e0688a mod_blocklist: When blocking someone who sent a subscription request, forget that request since the user would be unable to deny it while blocked (Fixes #574)
Kim Alvefur <zash@zash.se>
parents: 6976
diff changeset
   204
			local roster = load_roster(username, module.host);
bdb216e0688a mod_blocklist: When blocking someone who sent a subscription request, forget that request since the user would be unable to deny it while blocked (Fixes #574)
Kim Alvefur <zash@zash.se>
parents: 6976
diff changeset
   205
			for jid in pairs(remove_pending) do
bdb216e0688a mod_blocklist: When blocking someone who sent a subscription request, forget that request since the user would be unable to deny it while blocked (Fixes #574)
Kim Alvefur <zash@zash.se>
parents: 6976
diff changeset
   206
				roster[false].pending[jid] = nil;
bdb216e0688a mod_blocklist: When blocking someone who sent a subscription request, forget that request since the user would be unable to deny it while blocked (Fixes #574)
Kim Alvefur <zash@zash.se>
parents: 6976
diff changeset
   207
			end
bdb216e0688a mod_blocklist: When blocking someone who sent a subscription request, forget that request since the user would be unable to deny it while blocked (Fixes #574)
Kim Alvefur <zash@zash.se>
parents: 6976
diff changeset
   208
			save_roster(username, module.host, roster);
bdb216e0688a mod_blocklist: When blocking someone who sent a subscription request, forget that request since the user would be unable to deny it while blocked (Fixes #574)
Kim Alvefur <zash@zash.se>
parents: 6976
diff changeset
   209
			-- Not much we can do about save failing here
bdb216e0688a mod_blocklist: When blocking someone who sent a subscription request, forget that request since the user would be unable to deny it while blocked (Fixes #574)
Kim Alvefur <zash@zash.se>
parents: 6976
diff changeset
   210
		end
10056
0c35f353db68 mod_blocklist: Trigger resend of presence when unblocking a contact (fixes #1380)
Kim Alvefur <zash@zash.se>
parents: 9251
diff changeset
   211
	else
0c35f353db68 mod_blocklist: Trigger resend of presence when unblocking a contact (fixes #1380)
Kim Alvefur <zash@zash.se>
parents: 9251
diff changeset
   212
		local user_bare = username .. "@" .. module.host;
0c35f353db68 mod_blocklist: Trigger resend of presence when unblocking a contact (fixes #1380)
Kim Alvefur <zash@zash.se>
parents: 9251
diff changeset
   213
		for jid in pairs(send_available) do
0c35f353db68 mod_blocklist: Trigger resend of presence when unblocking a contact (fixes #1380)
Kim Alvefur <zash@zash.se>
parents: 9251
diff changeset
   214
			module:send(st.presence({ type = "probe", to = user_bare, from = jid }));
0c35f353db68 mod_blocklist: Trigger resend of presence when unblocking a contact (fixes #1380)
Kim Alvefur <zash@zash.se>
parents: 9251
diff changeset
   215
		end
6344
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   216
	end
6975
9e926e48cbf9 mod_blocklist: session[username] can't possibly be unset if that user is sending queries
Kim Alvefur <zash@zash.se>
parents: 6974
diff changeset
   217
9e926e48cbf9 mod_blocklist: session[username] can't possibly be unset if that user is sending queries
Kim Alvefur <zash@zash.se>
parents: 6974
diff changeset
   218
	local blocklist_push = st.iq({ type = "set", id = "blocklist-push" })
9e926e48cbf9 mod_blocklist: session[username] can't possibly be unset if that user is sending queries
Kim Alvefur <zash@zash.se>
parents: 6974
diff changeset
   219
		:add_child(action); -- I am lazy
6344
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   220
6975
9e926e48cbf9 mod_blocklist: session[username] can't possibly be unset if that user is sending queries
Kim Alvefur <zash@zash.se>
parents: 6974
diff changeset
   221
	for _, session in pairs(sessions[username].sessions) do
9e926e48cbf9 mod_blocklist: session[username] can't possibly be unset if that user is sending queries
Kim Alvefur <zash@zash.se>
parents: 6974
diff changeset
   222
		if session.interested_blocklist then
9e926e48cbf9 mod_blocklist: session[username] can't possibly be unset if that user is sending queries
Kim Alvefur <zash@zash.se>
parents: 6974
diff changeset
   223
			blocklist_push.attr.to = session.full_jid;
9e926e48cbf9 mod_blocklist: session[username] can't possibly be unset if that user is sending queries
Kim Alvefur <zash@zash.se>
parents: 6974
diff changeset
   224
			session.send(blocklist_push);
6344
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   225
		end
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   226
	end
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   227
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   228
	return true;
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   229
end
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   230
7623
c27c9695d130 mod_blocklist: Decrease priority of iq hooks to ease handling by other modules
Kim Alvefur <zash@zash.se>
parents: 7082
diff changeset
   231
module:hook("iq-set/self/urn:xmpp:blocking:block", edit_blocklist, -1);
c27c9695d130 mod_blocklist: Decrease priority of iq hooks to ease handling by other modules
Kim Alvefur <zash@zash.se>
parents: 7082
diff changeset
   232
module:hook("iq-set/self/urn:xmpp:blocking:unblock", edit_blocklist, -1);
6344
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   233
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   234
-- Cache invalidation, solved!
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   235
module:hook_global("user-deleted", function (event)
6632
42aeb882b3e1 mod_blocklist: Some cleanup [luacheck]
Kim Alvefur <zash@zash.se>
parents: 6534
diff changeset
   236
	if event.host == module.host then
13349
a74251a790ed mod_blocklist: Remove weak cache (and increase default LRU cache size)
Kim Alvefur <zash@zash.se>
parents: 13217
diff changeset
   237
		blocklist_cache:set(event.username, nil);
6344
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   238
	end
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   239
end);
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   240
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   241
-- Buggy clients
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   242
module:hook("iq-error/self/blocklist-push", function (event)
7971
f0e35f4db9e0 mod_blocklist: Split long line [luacheck]
Kim Alvefur <zash@zash.se>
parents: 7778
diff changeset
   243
	local origin, stanza = event.origin, event.stanza;
8043
62c540d51d50 mod_blocklist: Use local variable [luacheck]
Kim Alvefur <zash@zash.se>
parents: 7971
diff changeset
   244
	local _, condition, text = stanza:get_error();
7971
f0e35f4db9e0 mod_blocklist: Split long line [luacheck]
Kim Alvefur <zash@zash.se>
parents: 7778
diff changeset
   245
	local log = (origin.log or module._log);
f0e35f4db9e0 mod_blocklist: Split long line [luacheck]
Kim Alvefur <zash@zash.se>
parents: 7778
diff changeset
   246
	log("warn", "Client returned an error in response to notification from mod_%s: %s%s%s",
f0e35f4db9e0 mod_blocklist: Split long line [luacheck]
Kim Alvefur <zash@zash.se>
parents: 7778
diff changeset
   247
		module.name, condition, text and ": " or "", text or "");
6344
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   248
	return true;
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   249
end);
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   250
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   251
local function is_blocked(user, jid)
13349
a74251a790ed mod_blocklist: Remove weak cache (and increase default LRU cache size)
Kim Alvefur <zash@zash.se>
parents: 13217
diff changeset
   252
	local blocklist = get_blocklist(user);
6344
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   253
	if blocklist[jid] then return true; end
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   254
	local node, host = jid_split(jid);
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   255
	return blocklist[host] or node and blocklist[node..'@'..host];
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   256
end
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   257
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   258
-- Event handlers for bouncing or dropping stanzas
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   259
local function drop_stanza(event)
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   260
	local stanza = event.stanza;
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   261
	local attr = stanza.attr;
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   262
	local to, from = attr.to, attr.from;
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   263
	to = to and jid_split(to);
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   264
	if to and from then
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   265
		return is_blocked(to, from);
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   266
	end
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   267
end
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   268
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   269
local function bounce_stanza(event)
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   270
	local origin, stanza = event.origin, event.stanza;
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   271
	if drop_stanza(event) then
6836
aeb088bb1a20 mod_blocklist: Explicitly halt event propagation after returning a reply (send returns nil sometimes)
Kim Alvefur <zash@zash.se>
parents: 6632
diff changeset
   272
		origin.send(st_error_reply(stanza, "cancel", "service-unavailable"));
aeb088bb1a20 mod_blocklist: Explicitly halt event propagation after returning a reply (send returns nil sometimes)
Kim Alvefur <zash@zash.se>
parents: 6632
diff changeset
   273
		return true;
6344
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   274
	end
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   275
end
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   276
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   277
local function bounce_iq(event)
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   278
	local type = event.stanza.attr.type;
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   279
	if type == "set" or type == "get" then
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   280
		return bounce_stanza(event);
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   281
	end
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   282
	return drop_stanza(event); -- result or error
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   283
end
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   284
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   285
local function bounce_message(event)
8278
13dad833e821 mod_blocklist: Drop messages to existing full JIDs in order to prevent issues with MUC PMs, fixes #690
Kim Alvefur <zash@zash.se>
parents: 8043
diff changeset
   286
	local stanza = event.stanza;
13dad833e821 mod_blocklist: Drop messages to existing full JIDs in order to prevent issues with MUC PMs, fixes #690
Kim Alvefur <zash@zash.se>
parents: 8043
diff changeset
   287
	local type = stanza.attr.type;
6344
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   288
	if type == "chat" or not type or type == "normal" then
8278
13dad833e821 mod_blocklist: Drop messages to existing full JIDs in order to prevent issues with MUC PMs, fixes #690
Kim Alvefur <zash@zash.se>
parents: 8043
diff changeset
   289
		if full_sessions[stanza.attr.to] then
13dad833e821 mod_blocklist: Drop messages to existing full JIDs in order to prevent issues with MUC PMs, fixes #690
Kim Alvefur <zash@zash.se>
parents: 8043
diff changeset
   290
			-- See #690
13dad833e821 mod_blocklist: Drop messages to existing full JIDs in order to prevent issues with MUC PMs, fixes #690
Kim Alvefur <zash@zash.se>
parents: 8043
diff changeset
   291
			return drop_stanza(event);
13dad833e821 mod_blocklist: Drop messages to existing full JIDs in order to prevent issues with MUC PMs, fixes #690
Kim Alvefur <zash@zash.se>
parents: 8043
diff changeset
   292
		end
6344
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   293
		return bounce_stanza(event);
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   294
	end
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   295
	return drop_stanza(event); -- drop headlines, groupchats etc
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   296
end
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   297
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   298
local function drop_outgoing(event)
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   299
	local origin, stanza = event.origin, event.stanza;
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   300
	local username = origin.username or jid_split(stanza.attr.from);
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   301
	if not username then return end
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   302
	local to = stanza.attr.to;
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   303
	if to then return is_blocked(username, to); end
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   304
	-- nil 'to' means a self event, don't bock those
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   305
end
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   306
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   307
local function bounce_outgoing(event)
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   308
	local origin, stanza = event.origin, event.stanza;
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   309
	local type = stanza.attr.type;
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   310
	if type == "error" or stanza.name == "iq" and type == "result" then
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   311
		return drop_outgoing(event);
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   312
	end
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   313
	if drop_outgoing(event) then
6836
aeb088bb1a20 mod_blocklist: Explicitly halt event propagation after returning a reply (send returns nil sometimes)
Kim Alvefur <zash@zash.se>
parents: 6632
diff changeset
   314
		origin.send(st_error_reply(stanza, "cancel", "not-acceptable", "You have blocked this JID")
6344
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   315
			:tag("blocked", { xmlns = "urn:xmpp:blocking:errors" }));
6836
aeb088bb1a20 mod_blocklist: Explicitly halt event propagation after returning a reply (send returns nil sometimes)
Kim Alvefur <zash@zash.se>
parents: 6632
diff changeset
   316
		return true;
6344
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   317
	end
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   318
end
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   319
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   320
-- Hook all the events!
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   321
local prio_in, prio_out = 100, 100;
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   322
module:hook("presence/bare", drop_stanza, prio_in);
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   323
module:hook("presence/full", drop_stanza, prio_in);
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   324
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   325
module:hook("message/bare", bounce_message, prio_in);
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   326
module:hook("message/full", bounce_message, prio_in);
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   327
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   328
module:hook("iq/bare", bounce_iq, prio_in);
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   329
module:hook("iq/full", bounce_iq, prio_in);
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   330
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   331
module:hook("pre-message/bare", bounce_outgoing, prio_out);
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   332
module:hook("pre-message/full", bounce_outgoing, prio_out);
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   333
module:hook("pre-message/host", bounce_outgoing, prio_out);
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   334
8744
0fd63ed1f647 mod_blocklist: Allow mod_presence to handle subscription stanzas before bouncing outgoing presence (fixes #575)
Kim Alvefur <zash@zash.se>
parents: 8278
diff changeset
   335
module:hook("pre-presence/bare", bounce_outgoing, -1);
0fd63ed1f647 mod_blocklist: Allow mod_presence to handle subscription stanzas before bouncing outgoing presence (fixes #575)
Kim Alvefur <zash@zash.se>
parents: 8278
diff changeset
   336
module:hook("pre-presence/host", bounce_outgoing, -1);
0fd63ed1f647 mod_blocklist: Allow mod_presence to handle subscription stanzas before bouncing outgoing presence (fixes #575)
Kim Alvefur <zash@zash.se>
parents: 8278
diff changeset
   337
module:hook("pre-presence/full", bounce_outgoing, prio_out);
6344
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   338
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   339
module:hook("pre-iq/bare", bounce_outgoing, prio_out);
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   340
module:hook("pre-iq/full", bounce_outgoing, prio_out);
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   341
module:hook("pre-iq/host", bounce_outgoing, prio_out);
68b5c1ed18dd mod_blocklist: XEP-0191 implementation written for speed and independence from mod_privacy
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   342