aboutsummaryrefslogtreecommitdiff
path: root/src/ejabberd_auth.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/ejabberd_auth.erl')
-rw-r--r--src/ejabberd_auth.erl151
1 files changed, 58 insertions, 93 deletions
diff --git a/src/ejabberd_auth.erl b/src/ejabberd_auth.erl
index a3256364e..c5fda7d34 100644
--- a/src/ejabberd_auth.erl
+++ b/src/ejabberd_auth.erl
@@ -25,7 +25,6 @@
-module(ejabberd_auth).
-behaviour(gen_server).
--behaviour(ejabberd_config).
-author('alexey@process-one.net').
@@ -47,15 +46,16 @@
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3]).
--export([auth_modules/1, opt_type/1]).
+-export([auth_modules/1]).
-include("scram.hrl").
-include("logger.hrl").
-define(SALT_LENGTH, 16).
--record(state, {host_modules = #{} :: map()}).
+-record(state, {host_modules = #{} :: host_modules()}).
+-type host_modules() :: #{binary => [module()]}.
-type password() :: binary() | #scram{}.
-type digest_fun() :: fun((binary()) -> binary()).
-export_type([password/0]).
@@ -72,14 +72,16 @@
-callback reload(binary()) -> any().
-callback plain_password_required(binary()) -> boolean().
-callback store_type(binary()) -> plain | external | scram.
--callback set_password(binary(), binary(), binary()) -> ok | {error, atom()}.
--callback remove_user(binary(), binary()) -> ok | {error, any()}.
--callback user_exists(binary(), binary()) -> boolean() | {error, atom()}.
--callback check_password(binary(), binary(), binary(), binary()) -> boolean().
--callback try_register(binary(), binary(), password()) -> ok | {error, atom()}.
+-callback set_password(binary(), binary(), password()) ->
+ {ets_cache:tag(), {ok, password()} | {error, db_failure | not_allowed}}.
+-callback remove_user(binary(), binary()) -> ok | {error, db_failure | not_allowed}.
+-callback user_exists(binary(), binary()) -> {ets_cache:tag(), boolean() | {error, db_failure}}.
+-callback check_password(binary(), binary(), binary(), binary()) -> {ets_cache:tag(), boolean()}.
+-callback try_register(binary(), binary(), password()) ->
+ {ets_cache:tag(), {ok, password()} | {error, exists | db_failure | not_allowed}}.
-callback get_users(binary(), opts()) -> [{binary(), binary()}].
-callback count_users(binary(), opts()) -> number().
--callback get_password(binary(), binary()) -> {ok, password()} | error.
+-callback get_password(binary(), binary()) -> {ets_cache:tag(), {ok, password()} | error}.
-callback use_cache(binary()) -> boolean().
-callback cache_nodes(binary()) -> boolean().
@@ -107,7 +109,7 @@ init([]) ->
fun(Host, Acc) ->
Modules = auth_modules(Host),
maps:put(Host, Modules, Acc)
- end, #{}, ejabberd_config:get_myhosts()),
+ end, #{}, ejabberd_option:hosts()),
lists:foreach(
fun({Host, Modules}) ->
start(Host, Modules)
@@ -141,11 +143,11 @@ handle_cast(config_reloaded, #state{host_modules = HostModules} = State) ->
stop(Host, OldModules -- NewModules),
reload(Host, misc:intersection(OldModules, NewModules)),
maps:put(Host, NewModules, Acc)
- end, HostModules, ejabberd_config:get_myhosts()),
+ end, HostModules, ejabberd_option:hosts()),
init_cache(NewHostModules),
{noreply, State#state{host_modules = NewHostModules}};
handle_cast(Msg, State) ->
- ?WARNING_MSG("unexpected cast: ~p", [Msg]),
+ ?WARNING_MSG("Unexpected cast: ~p", [Msg]),
{noreply, State}.
handle_info(_Info, State) ->
@@ -250,7 +252,9 @@ check_password_with_authmodule(User, AuthzId, Server, Password, Digest, DigestGe
false
end.
--spec set_password(binary(), binary(), password()) -> ok | {error, atom()}.
+-spec set_password(binary(), binary(), password()) -> ok | {error,
+ db_failure | not_allowed |
+ invalid_jid | invalid_password}.
set_password(User, Server, Password) ->
case validate_credentials(User, Server, Password) of
{ok, LUser, LServer} ->
@@ -264,7 +268,9 @@ set_password(User, Server, Password) ->
Err
end.
--spec try_register(binary(), binary(), password()) -> ok | {error, atom()}.
+-spec try_register(binary(), binary(), password()) -> ok | {error,
+ db_failure | not_allowed | exists |
+ invalid_jid | invalid_password}.
try_register(User, Server, Password) ->
case validate_credentials(User, Server, Password) of
{ok, LUser, LServer} ->
@@ -530,11 +536,12 @@ backend_type(Mod) ->
-spec password_format(binary() | global) -> plain | scram.
password_format(LServer) ->
- ejabberd_config:get_option({auth_password_format, LServer}, plain).
+ ejabberd_option:auth_password_format(LServer).
%%%----------------------------------------------------------------------
%%% Backend calls
%%%----------------------------------------------------------------------
+-spec db_try_register(binary(), binary(), password(), module()) -> ok | {error, exists | db_failure | not_allowed}.
db_try_register(User, Server, Password, Mod) ->
case erlang:function_exported(Mod, try_register, 3) of
true ->
@@ -542,22 +549,24 @@ db_try_register(User, Server, Password, Mod) ->
scram -> password_to_scram(Password);
_ -> Password
end,
- case use_cache(Mod, Server) of
- true ->
- case ets_cache:update(
- cache_tab(Mod), {User, Server}, {ok, Password},
- fun() -> Mod:try_register(User, Server, Password1) end,
- cache_nodes(Mod, Server)) of
- {ok, _} -> ok;
- {error, _} = Err -> Err
- end;
- false ->
- ets_cache:untag(Mod:try_register(User, Server, Password1))
+ Ret = case use_cache(Mod, Server) of
+ true ->
+ ets_cache:update(
+ cache_tab(Mod), {User, Server}, {ok, Password},
+ fun() -> Mod:try_register(User, Server, Password1) end,
+ cache_nodes(Mod, Server));
+ false ->
+ ets_cache:untag(Mod:try_register(User, Server, Password1))
+ end,
+ case Ret of
+ {ok, _} -> ok;
+ {error, _} = Err -> Err
end;
false ->
{error, not_allowed}
end.
+-spec db_set_password(binary(), binary(), password(), module()) -> ok | {error, db_failure | not_allowed}.
db_set_password(User, Server, Password, Mod) ->
case erlang:function_exported(Mod, set_password, 3) of
true ->
@@ -565,17 +574,18 @@ db_set_password(User, Server, Password, Mod) ->
scram -> password_to_scram(Password);
_ -> Password
end,
- case use_cache(Mod, Server) of
- true ->
- case ets_cache:update(
- cache_tab(Mod), {User, Server}, {ok, Password},
- fun() -> Mod:set_password(User, Server, Password1) end,
- cache_nodes(Mod, Server)) of
- {ok, _} -> ok;
- {error, _} = Err -> Err
- end;
- false ->
- ets_cache:untag(Mod:set_password(User, Server, Password1))
+ Ret = case use_cache(Mod, Server) of
+ true ->
+ ets_cache:update(
+ cache_tab(Mod), {User, Server}, {ok, Password},
+ fun() -> Mod:set_password(User, Server, Password1) end,
+ cache_nodes(Mod, Server));
+ false ->
+ ets_cache:untag(Mod:set_password(User, Server, Password1))
+ end,
+ case Ret of
+ {ok, _} -> ok;
+ {error, _} = Err -> Err
end;
false ->
{error, not_allowed}
@@ -610,9 +620,6 @@ db_user_exists(User, Server, Mod) ->
cache_tab(Mod), {User, Server},
fun() ->
case Mod:user_exists(User, Server) of
- true -> {ok, exists};
- false -> error;
- {error, _} = Err -> Err;
{CacheTag, true} -> {CacheTag, {ok, exists}};
{CacheTag, false} -> {CacheTag, error};
{_, {error, _}} = Err -> Err
@@ -645,8 +652,6 @@ db_check_password(User, AuthzId, Server, ProvidedPassword,
fun() ->
case Mod:check_password(
User, AuthzId, Server, ProvidedPassword) of
- true -> {ok, ProvidedPassword};
- false -> error;
{CacheTag, true} -> {CacheTag, {ok, ProvidedPassword}};
{CacheTag, false} -> {CacheTag, error}
end
@@ -667,7 +672,7 @@ db_check_password(User, AuthzId, Server, ProvidedPassword,
db_remove_user(User, Server, Mod) ->
case erlang:function_exported(Mod, remove_user, 2) of
true ->
- case ets_cache:untag(Mod:remove_user(User, Server)) of
+ case Mod:remove_user(User, Server) of
ok ->
case use_cache(Mod, Server) of
true ->
@@ -686,7 +691,7 @@ db_remove_user(User, Server, Mod) ->
db_get_users(Server, Opts, Mod) ->
case erlang:function_exported(Mod, get_users, 2) of
true ->
- ets_cache:untag(Mod:get_users(Server, Opts));
+ Mod:get_users(Server, Opts);
false ->
case use_cache(Mod, Server) of
true ->
@@ -704,7 +709,7 @@ db_get_users(Server, Opts, Mod) ->
db_count_users(Server, Opts, Mod) ->
case erlang:function_exported(Mod, count_users, 2) of
true ->
- ets_cache:untag(Mod:count_users(Server, Opts));
+ Mod:count_users(Server, Opts);
false ->
case use_cache(Mod, Server) of
true ->
@@ -752,7 +757,7 @@ password_to_scram(Password, IterationCount) ->
%%%----------------------------------------------------------------------
%%% Cache stuff
%%%----------------------------------------------------------------------
--spec init_cache(map()) -> ok.
+-spec init_cache(host_modules()) -> ok.
init_cache(HostModules) ->
CacheOpts = cache_opts(),
{True, False} = use_cache(HostModules),
@@ -767,21 +772,12 @@ init_cache(HostModules) ->
-spec cache_opts() -> [proplists:property()].
cache_opts() ->
- MaxSize = ejabberd_config:get_option(
- auth_cache_size,
- ejabberd_config:cache_size(global)),
- CacheMissed = ejabberd_config:get_option(
- auth_cache_missed,
- ejabberd_config:cache_missed(global)),
- LifeTime = case ejabberd_config:get_option(
- auth_cache_life_time,
- ejabberd_config:cache_life_time(global)) of
- infinity -> infinity;
- I -> timer:seconds(I)
- end,
+ MaxSize = ejabberd_option:auth_cache_size(),
+ CacheMissed = ejabberd_option:auth_cache_missed(),
+ LifeTime = ejabberd_option:auth_cache_life_time(),
[{max_size, MaxSize}, {cache_missed, CacheMissed}, {life_time, LifeTime}].
--spec use_cache(map()) -> {True :: [module()], False :: [module()]}.
+-spec use_cache(host_modules()) -> {True :: [module()], False :: [module()]}.
use_cache(HostModules) ->
{Enabled, Disabled} =
maps:fold(
@@ -803,9 +799,7 @@ use_cache(Mod, LServer) ->
case erlang:function_exported(Mod, use_cache, 1) of
true -> Mod:use_cache(LServer);
false ->
- ejabberd_config:get_option(
- {auth_use_cache, LServer},
- ejabberd_config:use_cache(LServer))
+ ejabberd_option:auth_use_cache(LServer)
end.
-spec cache_nodes(module(), binary()) -> [node()].
@@ -827,13 +821,12 @@ auth_modules() ->
lists:flatmap(
fun(Host) ->
[{Host, Mod} || Mod <- auth_modules(Host)]
- end, ejabberd_config:get_myhosts()).
+ end, ejabberd_option:hosts()).
-spec auth_modules(binary()) -> [module()].
auth_modules(Server) ->
LServer = jid:nameprep(Server),
- Default = ejabberd_config:default_db(LServer, ?MODULE),
- Methods = ejabberd_config:get_option({auth_method, LServer}, [Default]),
+ Methods = ejabberd_option:auth_method(LServer),
[ejabberd:module_name([<<"ejabberd">>, <<"auth">>,
misc:atom_to_binary(M)])
|| M <- Methods].
@@ -911,31 +904,3 @@ import(Server, {sql, _}, riak, <<"users">>, Fields) ->
ejabberd_auth_riak:import(Server, Fields);
import(_LServer, {sql, _}, sql, <<"users">>, _) ->
ok.
-
--spec opt_type(atom()) -> fun((any()) -> any()) | [atom()].
-opt_type(auth_method) ->
- fun (V) when is_list(V) ->
- lists:map(fun(M) -> ejabberd_config:v_db(?MODULE, M) end, V);
- (V) -> [ejabberd_config:v_db(?MODULE, V)]
- end;
-opt_type(auth_password_format) ->
- fun (plain) -> plain;
- (scram) -> scram
- end;
-opt_type(auth_use_cache) ->
- fun(B) when is_boolean(B) -> B end;
-opt_type(auth_cache_missed) ->
- fun(B) when is_boolean(B) -> B end;
-opt_type(auth_cache_life_time) ->
- fun(I) when is_integer(I), I>0 -> I;
- (unlimited) -> infinity;
- (infinity) -> infinity
- end;
-opt_type(auth_cache_size) ->
- fun(I) when is_integer(I), I>0 -> I;
- (unlimited) -> infinity;
- (infinity) -> infinity
- end;
-opt_type(_) ->
- [auth_method, auth_password_format, auth_use_cache,
- auth_cache_missed, auth_cache_life_time, auth_cache_size].