Use different cache tables per auth module

Fixes #2322
This commit is contained in:
Evgeny Khramtsov 2019-05-23 11:32:55 +03:00
parent 729c8b0d24
commit 3f7a850ae8
1 changed files with 38 additions and 23 deletions

View File

@ -52,7 +52,6 @@
-include("scram.hrl").
-include("logger.hrl").
-define(AUTH_CACHE, auth_cache).
-define(SALT_LENGTH, 16).
-record(state, {host_modules = #{} :: map()}).
@ -546,7 +545,7 @@ db_try_register(User, Server, Password, Mod) ->
case use_cache(Mod, Server) of
true ->
case ets_cache:update(
?AUTH_CACHE, {User, Server}, {ok, Password},
cache_tab(Mod), {User, Server}, {ok, Password},
fun() -> Mod:try_register(User, Server, Password1) end,
cache_nodes(Mod, Server)) of
{ok, _} -> ok;
@ -569,7 +568,7 @@ db_set_password(User, Server, Password, Mod) ->
case use_cache(Mod, Server) of
true ->
case ets_cache:update(
?AUTH_CACHE, {User, Server}, {ok, Password},
cache_tab(Mod), {User, Server}, {ok, Password},
fun() -> Mod:set_password(User, Server, Password1) end,
cache_nodes(Mod, Server)) of
{ok, _} -> ok;
@ -586,7 +585,7 @@ db_get_password(User, Server, Mod) ->
UseCache = use_cache(Mod, Server),
case erlang:function_exported(Mod, get_password, 2) of
false when UseCache ->
case ets_cache:lookup(?AUTH_CACHE, {User, Server}) of
case ets_cache:lookup(cache_tab(Mod), {User, Server}) of
{ok, exists} -> error;
Other -> Other
end;
@ -594,7 +593,7 @@ db_get_password(User, Server, Mod) ->
error;
true when UseCache ->
ets_cache:lookup(
?AUTH_CACHE, {User, Server},
cache_tab(Mod), {User, Server},
fun() -> Mod:get_password(User, Server) end);
true ->
ets_cache:untag(Mod:get_password(User, Server))
@ -608,7 +607,7 @@ db_user_exists(User, Server, Mod) ->
case {Mod:store_type(Server), use_cache(Mod, Server)} of
{external, true} ->
case ets_cache:lookup(
?AUTH_CACHE, {User, Server},
cache_tab(Mod), {User, Server},
fun() ->
case Mod:user_exists(User, Server) of
true -> {ok, exists};
@ -642,7 +641,7 @@ db_check_password(User, AuthzId, Server, ProvidedPassword,
case {Mod:store_type(Server), use_cache(Mod, Server)} of
{external, true} ->
case ets_cache:update(
?AUTH_CACHE, {User, Server}, {ok, ProvidedPassword},
cache_tab(Mod), {User, Server}, {ok, ProvidedPassword},
fun() ->
case Mod:check_password(
User, AuthzId, Server, ProvidedPassword) of
@ -672,7 +671,7 @@ db_remove_user(User, Server, Mod) ->
ok ->
case use_cache(Mod, Server) of
true ->
ets_cache:delete(?AUTH_CACHE, {User, Server},
ets_cache:delete(cache_tab(Mod), {User, Server},
cache_nodes(Mod, Server));
false ->
ok
@ -696,7 +695,7 @@ db_get_users(Server, Opts, Mod) ->
[{User, Server}|Users];
(_, _, Users) ->
Users
end, [], ?AUTH_CACHE);
end, [], cache_tab(Mod));
false ->
[]
end
@ -714,7 +713,7 @@ db_count_users(Server, Opts, Mod) ->
Num + 1;
(_, _, Num) ->
Num
end, 0, ?AUTH_CACHE);
end, 0, cache_tab(Mod));
false ->
0
end
@ -755,12 +754,16 @@ password_to_scram(Password, IterationCount) ->
%%%----------------------------------------------------------------------
-spec init_cache(map()) -> ok.
init_cache(HostModules) ->
case use_cache(HostModules) of
true ->
ets_cache:new(?AUTH_CACHE, cache_opts());
false ->
ets_cache:delete(?AUTH_CACHE)
end.
CacheOpts = cache_opts(),
{True, False} = use_cache(HostModules),
lists:foreach(
fun(Module) ->
ets_cache:new(cache_tab(Module), CacheOpts)
end, True),
lists:foreach(
fun(Module) ->
ets_cache:delete(cache_tab(Module))
end, False).
-spec cache_opts() -> [proplists:property()].
cache_opts() ->
@ -778,14 +781,22 @@ cache_opts() ->
end,
[{max_size, MaxSize}, {cache_missed, CacheMissed}, {life_time, LifeTime}].
-spec use_cache(map()) -> boolean().
-spec use_cache(map()) -> {True :: [module()], False :: [module()]}.
use_cache(HostModules) ->
lists:any(
fun({Host, Modules}) ->
lists:any(fun(Module) ->
use_cache(Module, Host)
end, Modules)
end, maps:to_list(HostModules)).
{Enabled, Disabled} =
maps:fold(
fun(Host, Modules, Acc) ->
lists:foldl(
fun(Module, {True, False}) ->
case use_cache(Module, Host) of
true ->
{sets:add_element(Module, True), False};
false ->
{True, sets:add_element(Module, False)}
end
end, Acc, Modules)
end, {sets:new(), sets:new()}, HostModules),
{sets:to_list(Enabled), sets:to_list(sets:subtract(Disabled, Enabled))}.
-spec use_cache(module(), binary()) -> boolean().
use_cache(Mod, LServer) ->
@ -804,6 +815,10 @@ cache_nodes(Mod, LServer) ->
false -> ejabberd_cluster:get_nodes()
end.
-spec cache_tab(module()) -> atom().
cache_tab(Mod) ->
list_to_atom(atom_to_list(Mod) ++ "_cache").
%%%----------------------------------------------------------------------
%%% Internal functions
%%%----------------------------------------------------------------------