mod_spam_filter: Add 'drop_from_spam_filter_cache'

Add a 'drop_from_spam_filter_cache' command that allows for removing
individual JIDs from the cache.
This commit is contained in:
Holger Weiss 2019-04-10 00:49:36 +02:00
parent b5daceaac2
commit 6a877d7018
2 changed files with 54 additions and 3 deletions

View File

@ -68,9 +68,10 @@ The configurable mod_spam_filter options are:
----------------- -----------------
This module provides ejabberdctl/API calls to reread the spam JID/URL This module provides ejabberdctl/API calls to reread the spam JID/URL
files, to print the JID cache contents, and to expire old entries from files, to print the JID cache contents, and to remove entries from that
that cache. See: cache. See:
$ ejabberdctl help reload-spam-filter-files $ ejabberdctl help reload-spam-filter-files
$ ejabberdctl help get-spam-filter-cache $ ejabberdctl help get-spam-filter-cache
$ ejabberdctl help expire-spam-filter-cache $ ejabberdctl help expire-spam-filter-cache
$ ejabberdctl help drop-from-spam-filter-cache

View File

@ -51,7 +51,8 @@
%% ejabberd_commands callbacks. %% ejabberd_commands callbacks.
-export([get_commands_spec/0, reload_spam_filter_files/1, -export([get_commands_spec/0, reload_spam_filter_files/1,
get_spam_filter_cache/1, expire_spam_filter_cache/2]). get_spam_filter_cache/1, expire_spam_filter_cache/2,
drop_from_spam_filter_cache/2]).
-include("ejabberd_commands.hrl"). -include("ejabberd_commands.hrl").
-include("logger.hrl"). -include("logger.hrl").
@ -176,6 +177,9 @@ handle_call({reload_files, JIDsFile, URLsFile}, _From, State) ->
handle_call({expire_cache, Age}, _From, State) -> handle_call({expire_cache, Age}, _From, State) ->
{Result, State1} = expire_cache(Age, State), {Result, State1} = expire_cache(Age, State),
{reply, {spam_filter, Result}, State1}; {reply, {spam_filter, Result}, State1};
handle_call({drop_from_cache, JID}, _From, State) ->
{Result, State1} = drop_from_cache(JID, State),
{reply, {spam_filter, Result}, State1};
handle_call(get_cache, _From, #state{jid_cache = Cache} = State) -> handle_call(get_cache, _From, #state{jid_cache = Cache} = State) ->
{reply, {spam_filter, maps:to_list(Cache)}, State}; {reply, {spam_filter, maps:to_list(Cache)}, State};
handle_call(Request, From, State) -> handle_call(Request, From, State) ->
@ -549,6 +553,17 @@ expire_cache(Age, #state{jid_cache = Cache} = State) ->
Txt = format("Expired ~B cache entries", [NumExp]), Txt = format("Expired ~B cache entries", [NumExp]),
{{ok, Txt}, State#state{jid_cache = Cache1}}. {{ok, Txt}, State#state{jid_cache = Cache1}}.
-spec drop_from_cache(ljid(), state()) -> {{ok, binary()}, state()}.
drop_from_cache(LJID, #state{jid_cache = Cache} = State) ->
Cache1 = maps:remove(LJID, Cache),
if map_size(Cache1) < map_size(Cache) ->
Txt = format("~s removed from cache", [jid:encode(LJID)]),
{{ok, Txt}, State#state{jid_cache = Cache1}};
true ->
Txt = format("~s wasn't cached", [jid:encode(LJID)]),
{{ok, Txt}, State}
end.
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
%% ejabberd command callbacks. %% ejabberd command callbacks.
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
@ -569,6 +584,12 @@ get_commands_spec() ->
desc = "Remove old/unused spam JIDs from cache", desc = "Remove old/unused spam JIDs from cache",
module = ?MODULE, function = expire_spam_filter_cache, module = ?MODULE, function = expire_spam_filter_cache,
args = [{host, binary}, {seconds, integer}], args = [{host, binary}, {seconds, integer}],
result = {res, restuple}},
#ejabberd_commands{name = drop_from_spam_filter_cache, tags = [filter],
desc = "Drop JID from spam filter cache",
module = ?MODULE,
function = drop_from_spam_filter_cache,
args = [{host, binary}, {jid, binary}],
result = {res, restuple}}]. result = {res, restuple}}].
-spec reload_spam_filter_files(binary()) -> {ok | error, string()}. -spec reload_spam_filter_files(binary()) -> {ok | error, string()}.
@ -634,3 +655,32 @@ expire_spam_filter_cache(Host, Age) ->
exit:{timeout, _} -> exit:{timeout, _} ->
{error, "Timeout while querying ejabberd"} {error, "Timeout while querying ejabberd"}
end. end.
-spec drop_from_spam_filter_cache(binary(), binary()) -> {ok | error, string()}.
drop_from_spam_filter_cache(<<"global">>, JID) ->
try lists:foreach(fun(Host) ->
{ok, _} = drop_from_spam_filter_cache(Host, JID)
end, ejabberd_config:get_myhosts()) of
ok ->
{ok, "Dropped " ++ binary_to_list(JID) ++ " from caches"}
catch error:{badmatch, {error, _Reason} = Error} ->
Error
end;
drop_from_spam_filter_cache(Host, EncJID) ->
LServer = jid:nameprep(Host),
Proc = get_proc_name(LServer),
try jid:decode(EncJID) of
#jid{} = JID ->
LJID = jid:remove_resource(jid:tolower(JID)),
try gen_server:call(Proc, {drop_from_cache, LJID},
?COMMAND_TIMEOUT) of
{spam_filter, {Status, Txt}} ->
{Status, binary_to_list(Txt)}
catch exit:{noproc, _} ->
{error, "Not configured for " ++ binary_to_list(Host)};
exit:{timeout, _} ->
{error, "Timeout while querying ejabberd"}
end
catch _:{bad_jid, _} ->
{error, "Not a valid JID: " ++ binary_to_list(EncJID)}
end.