{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 check_password(binary(), binary(), binary(), binary()) -> {ets_cache:tag(), boolean() | {stop, 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()}].
error ->
false;
LAuthzId ->
- lists:foldl(
- fun(Mod, false) ->
- case db_check_password(
- LUser, LAuthzId, LServer, Password,
- Digest, DigestGen, Mod) of
- true -> {true, Mod};
- false -> false
- end;
- (_, Acc) ->
- Acc
- end, false, auth_modules(LServer))
+ untag_stop(
+ lists:foldl(
+ fun(Mod, false) ->
+ case db_check_password(
+ LUser, LAuthzId, LServer, Password,
+ Digest, DigestGen, Mod) of
+ true -> {true, Mod};
+ false -> false;
+ {stop, true} -> {stop, {true, Mod}};
+ {stop, false} -> {stop, false}
+ end;
+ (_, Acc) ->
+ Acc
+ end, false, auth_modules(LServer)))
end;
_ ->
false
<<"">>, undefined, Mod) of
true ->
db_remove_user(LUser, LServer, Mod);
+ {stop, true} ->
+ db_remove_user(LUser, LServer, Mod);
false ->
+ {error, not_allowed};
+ {stop, false} ->
{error, not_allowed}
end
end, {error, not_allowed}, auth_modules(Server)) of
case Mod:check_password(
User, AuthzId, Server, ProvidedPassword) of
{CacheTag, true} -> {CacheTag, {ok, ProvidedPassword}};
- {CacheTag, false} -> {CacheTag, error}
+ {CacheTag, {stop, true}} -> {CacheTag, {ok, ProvidedPassword}};
+ {CacheTag, false} -> {CacheTag, error};
+ {CacheTag, {stop, false}} -> {CacheTag, error}
end
end) of
{ok, _} ->
end
end.
+untag_stop({stop, Val}) -> Val;
+untag_stop(Val) -> Val.
+
import_info() ->
[{<<"users">>, 3}].
-export([start/1, stop/1, check_password/4,
store_type/1, plain_password_required/1,
- user_exists/2
+ user_exists/2, use_cache/1
]).
-include("xmpp.hrl").
store_type(_Host) -> external.
--spec check_password(binary(), binary(), binary(), binary()) -> {ets_cache:tag(), boolean()}.
+-spec check_password(binary(), binary(), binary(), binary()) -> {ets_cache:tag(), boolean() | {stop, boolean()}}.
check_password(User, AuthzId, Server, Token) ->
%% MREMOND: Should we move the AuthzId check at a higher level in
%% the call stack?
true ->
if Token == <<"">> -> {nocache, false};
true ->
- {nocache, check_jwt_token(User, Server, Token)}
+ Res = check_jwt_token(User, Server, Token),
+ Rule = ejabberd_option:jwt_auth_only_rule(Server),
+ case acl:match_rule(Server, Rule,
+ jid:make(User, Server, <<"">>)) of
+ deny ->
+ {nocache, Res};
+ allow ->
+ {nocache, {stop, Res}}
+ end
end
end.
user_exists(_User, _Host) -> {nocache, false}.
+use_cache(_) ->
+ false.
+
%%%----------------------------------------------------------------------
%%% Internal functions
%%%----------------------------------------------------------------------
-export([host_config/0]).
-export([hosts/0]).
-export([include_config_file/0, include_config_file/1]).
+-export([jwt_auth_only_rule/0, jwt_auth_only_rule/1]).
-export([jwt_key/0, jwt_key/1]).
-export([language/0, language/1]).
-export([ldap_backups/0, ldap_backups/1]).
include_config_file(Host) ->
ejabberd_config:get_option({include_config_file, Host}).
+-spec jwt_auth_only_rule() -> atom().
+jwt_auth_only_rule() ->
+ jwt_auth_only_rule(global).
+-spec jwt_auth_only_rule(global | binary()) -> atom().
+jwt_auth_only_rule(Host) ->
+ ejabberd_config:get_option({jwt_auth_only_rule, Host}).
+
-spec jwt_key() -> jose_jwk:key() | 'undefined'.
jwt_key() ->
jwt_key(global).