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