plugins/mod_tombstones.lua
author Kim Alvefur <zash@zash.se>
Thu, 28 Mar 2024 15:26:57 +0100
changeset 13472 98806cac64c3
parent 13217 50324f66ca2a
permissions -rw-r--r--
MUC: Switch to official XEP-0317 namespace for Hats (including compat) (thanks nicoco)
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
12119
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     1
-- TODO warn when trying to create an user before the tombstone expires
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     2
-- e.g. via telnet or other admin interface
12981
74b9e05af71e plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12442
diff changeset
     3
local datetime = require "prosody.util.datetime";
74b9e05af71e plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12442
diff changeset
     4
local errors = require "prosody.util.error";
74b9e05af71e plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12442
diff changeset
     5
local jid_node = require"prosody.util.jid".node;
74b9e05af71e plugins: Prefix module imports with prosody namespace
Kim Alvefur <zash@zash.se>
parents: 12442
diff changeset
     6
local st = require "prosody.util.stanza";
12119
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     7
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     8
-- Using a map store as key-value store so that removal of all user data
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
     9
-- does not also remove the tombstone, which would defeat the point
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    10
local graveyard = module:open_store(nil, "map");
13217
50324f66ca2a plugins: Use integer config API with interval specification where sensible
Kim Alvefur <zash@zash.se>
parents: 13213
diff changeset
    11
local graveyard_cache = require "prosody.util.cache".new(module:get_option_integer("tombstone_cache_size", 1024, 1));
12119
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    12
13213
c8d949cf6b09 plugins: Switch to :get_option_period() for time range options
Kim Alvefur <zash@zash.se>
parents: 12981
diff changeset
    13
local ttl = module:get_option_period("user_tombstone_expiry", nil);
12119
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    14
-- Keep tombstones forever by default
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    15
--
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    16
-- Rationale:
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    17
-- There is no way to be completely sure when remote services have
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    18
-- forgotten and revoked all memberships.
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    19
12121
0c9b64178eda mod_tombstones: Add some future TODOs
Kim Alvefur <zash@zash.se>
parents: 12119
diff changeset
    20
-- TODO If the user left a JID they moved to, return a gone+redirect error
0c9b64178eda mod_tombstones: Add some future TODOs
Kim Alvefur <zash@zash.se>
parents: 12119
diff changeset
    21
-- TODO Attempt to deregister from MUCs based on bookmarks
0c9b64178eda mod_tombstones: Add some future TODOs
Kim Alvefur <zash@zash.se>
parents: 12119
diff changeset
    22
-- TODO Unsubscribe from pubsub services if a notification is received
0c9b64178eda mod_tombstones: Add some future TODOs
Kim Alvefur <zash@zash.se>
parents: 12119
diff changeset
    23
12119
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    24
module:hook_global("user-deleted", function(event)
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    25
	if event.host == module.host then
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    26
		local ok, err = graveyard:set(nil, event.username, os.time());
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    27
		if not ok then module:log("error", "Could store tombstone for %s: %s", event.username, err); end
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    28
	end
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    29
end);
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    30
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    31
-- Public API
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    32
function has_tombstone(username)
12442
a698f65df453 mod_tombstones: Add caching to improve performance on busy servers (fixes #1728)
Matthew Wild <mwild1@gmail.com>
parents: 12121
diff changeset
    33
	local tombstone;
12119
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    34
12442
a698f65df453 mod_tombstones: Add caching to improve performance on busy servers (fixes #1728)
Matthew Wild <mwild1@gmail.com>
parents: 12121
diff changeset
    35
	-- Check cache
a698f65df453 mod_tombstones: Add caching to improve performance on busy servers (fixes #1728)
Matthew Wild <mwild1@gmail.com>
parents: 12121
diff changeset
    36
	local cached_result = graveyard_cache:get(username);
a698f65df453 mod_tombstones: Add caching to improve performance on busy servers (fixes #1728)
Matthew Wild <mwild1@gmail.com>
parents: 12121
diff changeset
    37
	if cached_result == false then
a698f65df453 mod_tombstones: Add caching to improve performance on busy servers (fixes #1728)
Matthew Wild <mwild1@gmail.com>
parents: 12121
diff changeset
    38
		-- We cached that there is no tombstone for this user
a698f65df453 mod_tombstones: Add caching to improve performance on busy servers (fixes #1728)
Matthew Wild <mwild1@gmail.com>
parents: 12121
diff changeset
    39
		return false;
a698f65df453 mod_tombstones: Add caching to improve performance on busy servers (fixes #1728)
Matthew Wild <mwild1@gmail.com>
parents: 12121
diff changeset
    40
	elseif cached_result then
a698f65df453 mod_tombstones: Add caching to improve performance on busy servers (fixes #1728)
Matthew Wild <mwild1@gmail.com>
parents: 12121
diff changeset
    41
		tombstone = cached_result;
a698f65df453 mod_tombstones: Add caching to improve performance on busy servers (fixes #1728)
Matthew Wild <mwild1@gmail.com>
parents: 12121
diff changeset
    42
	else
a698f65df453 mod_tombstones: Add caching to improve performance on busy servers (fixes #1728)
Matthew Wild <mwild1@gmail.com>
parents: 12121
diff changeset
    43
		local stored_result, err = graveyard:get(nil, username);
a698f65df453 mod_tombstones: Add caching to improve performance on busy servers (fixes #1728)
Matthew Wild <mwild1@gmail.com>
parents: 12121
diff changeset
    44
		if not stored_result and not err then
a698f65df453 mod_tombstones: Add caching to improve performance on busy servers (fixes #1728)
Matthew Wild <mwild1@gmail.com>
parents: 12121
diff changeset
    45
			-- Cache that there is no tombstone for this user
a698f65df453 mod_tombstones: Add caching to improve performance on busy servers (fixes #1728)
Matthew Wild <mwild1@gmail.com>
parents: 12121
diff changeset
    46
			graveyard_cache:set(username, false);
a698f65df453 mod_tombstones: Add caching to improve performance on busy servers (fixes #1728)
Matthew Wild <mwild1@gmail.com>
parents: 12121
diff changeset
    47
			return false;
a698f65df453 mod_tombstones: Add caching to improve performance on busy servers (fixes #1728)
Matthew Wild <mwild1@gmail.com>
parents: 12121
diff changeset
    48
		elseif err then
a698f65df453 mod_tombstones: Add caching to improve performance on busy servers (fixes #1728)
Matthew Wild <mwild1@gmail.com>
parents: 12121
diff changeset
    49
			-- Failed to check tombstone status
a698f65df453 mod_tombstones: Add caching to improve performance on busy servers (fixes #1728)
Matthew Wild <mwild1@gmail.com>
parents: 12121
diff changeset
    50
			return nil, err;
a698f65df453 mod_tombstones: Add caching to improve performance on busy servers (fixes #1728)
Matthew Wild <mwild1@gmail.com>
parents: 12121
diff changeset
    51
		end
a698f65df453 mod_tombstones: Add caching to improve performance on busy servers (fixes #1728)
Matthew Wild <mwild1@gmail.com>
parents: 12121
diff changeset
    52
		-- We have a tombstone stored, so let's continue with that
a698f65df453 mod_tombstones: Add caching to improve performance on busy servers (fixes #1728)
Matthew Wild <mwild1@gmail.com>
parents: 12121
diff changeset
    53
		tombstone = stored_result;
a698f65df453 mod_tombstones: Add caching to improve performance on busy servers (fixes #1728)
Matthew Wild <mwild1@gmail.com>
parents: 12121
diff changeset
    54
	end
12119
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    55
12442
a698f65df453 mod_tombstones: Add caching to improve performance on busy servers (fixes #1728)
Matthew Wild <mwild1@gmail.com>
parents: 12121
diff changeset
    56
	-- Check expiry
12119
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    57
	if ttl and tombstone + ttl < os.time() then
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    58
		module:log("debug", "Tombstone for %s created at %s has expired", username, datetime.datetime(tombstone));
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    59
		graveyard:set(nil, username, nil);
12442
a698f65df453 mod_tombstones: Add caching to improve performance on busy servers (fixes #1728)
Matthew Wild <mwild1@gmail.com>
parents: 12121
diff changeset
    60
		graveyard_cache:set(username, nil); -- clear cache entry (if any)
12119
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    61
		return nil;
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    62
	end
12442
a698f65df453 mod_tombstones: Add caching to improve performance on busy servers (fixes #1728)
Matthew Wild <mwild1@gmail.com>
parents: 12121
diff changeset
    63
a698f65df453 mod_tombstones: Add caching to improve performance on busy servers (fixes #1728)
Matthew Wild <mwild1@gmail.com>
parents: 12121
diff changeset
    64
	-- Cache for the future
a698f65df453 mod_tombstones: Add caching to improve performance on busy servers (fixes #1728)
Matthew Wild <mwild1@gmail.com>
parents: 12121
diff changeset
    65
	graveyard_cache:set(username, tombstone);
a698f65df453 mod_tombstones: Add caching to improve performance on busy servers (fixes #1728)
Matthew Wild <mwild1@gmail.com>
parents: 12121
diff changeset
    66
12119
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    67
	return tombstone;
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    68
end
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    69
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    70
module:hook("user-registering", function(event)
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    71
	local tombstone, err = has_tombstone(event.username);
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    72
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    73
	if err then
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    74
		event.allowed, event.error = errors.coerce(false, err);
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    75
		return true;
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    76
	elseif not tombstone then
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    77
		-- Feel free
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    78
		return;
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    79
	end
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    80
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    81
	module:log("debug", "Tombstone for %s created at %s", event.username, datetime.datetime(tombstone));
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    82
	event.allowed = false;
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    83
	return true;
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    84
end);
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    85
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    86
module:hook("presence/bare", function(event)
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    87
	local origin, presence = event.origin, event.stanza;
12442
a698f65df453 mod_tombstones: Add caching to improve performance on busy servers (fixes #1728)
Matthew Wild <mwild1@gmail.com>
parents: 12121
diff changeset
    88
	local local_username = jid_node(presence.attr.to);
a698f65df453 mod_tombstones: Add caching to improve performance on busy servers (fixes #1728)
Matthew Wild <mwild1@gmail.com>
parents: 12121
diff changeset
    89
	if not local_username then return; end
12119
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    90
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    91
	-- We want to undo any left-over presence subscriptions and notify the former
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    92
	-- contact that they're gone.
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    93
	--
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    94
	-- FIXME This leaks that the user once existed. Hard to avoid without keeping
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    95
	-- the contact list in some form, which we don't want to do for privacy
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
    96
	-- reasons.  Bloom filter perhaps?
12442
a698f65df453 mod_tombstones: Add caching to improve performance on busy servers (fixes #1728)
Matthew Wild <mwild1@gmail.com>
parents: 12121
diff changeset
    97
a698f65df453 mod_tombstones: Add caching to improve performance on busy servers (fixes #1728)
Matthew Wild <mwild1@gmail.com>
parents: 12121
diff changeset
    98
	local pres_type = presence.attr.type;
a698f65df453 mod_tombstones: Add caching to improve performance on busy servers (fixes #1728)
Matthew Wild <mwild1@gmail.com>
parents: 12121
diff changeset
    99
	local is_probe = pres_type == "probe";
a698f65df453 mod_tombstones: Add caching to improve performance on busy servers (fixes #1728)
Matthew Wild <mwild1@gmail.com>
parents: 12121
diff changeset
   100
	local is_normal = pres_type == nil or pres_type == "unavailable";
a698f65df453 mod_tombstones: Add caching to improve performance on busy servers (fixes #1728)
Matthew Wild <mwild1@gmail.com>
parents: 12121
diff changeset
   101
	if is_probe and has_tombstone(local_username) then
a698f65df453 mod_tombstones: Add caching to improve performance on busy servers (fixes #1728)
Matthew Wild <mwild1@gmail.com>
parents: 12121
diff changeset
   102
		origin.send(st.error_reply(presence, "cancel", "gone", "User deleted"));
a698f65df453 mod_tombstones: Add caching to improve performance on busy servers (fixes #1728)
Matthew Wild <mwild1@gmail.com>
parents: 12121
diff changeset
   103
		origin.send(st.presence({ type = "unsubscribed"; to = presence.attr.from; from = presence.attr.to }));
a698f65df453 mod_tombstones: Add caching to improve performance on busy servers (fixes #1728)
Matthew Wild <mwild1@gmail.com>
parents: 12121
diff changeset
   104
		return true;
a698f65df453 mod_tombstones: Add caching to improve performance on busy servers (fixes #1728)
Matthew Wild <mwild1@gmail.com>
parents: 12121
diff changeset
   105
	elseif is_normal and has_tombstone(local_username) then
a698f65df453 mod_tombstones: Add caching to improve performance on busy servers (fixes #1728)
Matthew Wild <mwild1@gmail.com>
parents: 12121
diff changeset
   106
		origin.send(st.error_reply(presence, "cancel", "gone", "User deleted"));
a698f65df453 mod_tombstones: Add caching to improve performance on busy servers (fixes #1728)
Matthew Wild <mwild1@gmail.com>
parents: 12121
diff changeset
   107
		origin.send(st.presence({ type = "unsubscribe"; to = presence.attr.from; from = presence.attr.to }));
12119
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   108
		return true;
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   109
	end
94de6b7596cc mod_tombstones: Remember deleted accounts #1307
Kim Alvefur <zash@zash.se>
parents:
diff changeset
   110
end, 1);