fix(authn_redis): Add new clause for non-existent key check

fix #8800
when the key not-existing, redis may return a list that all elements are `undefined`
This commit is contained in:
firest 2022-09-14 11:23:31 +08:00
parent 2c7d518c19
commit 9e97760520
2 changed files with 47 additions and 24 deletions

View File

@ -141,6 +141,11 @@ authenticate(
{ok, []} ->
ignore;
{ok, Values} ->
case lists:all(fun(E) -> E =:= undefined end, Values) of
true ->
%% key not exists
ignore;
_ ->
Selected = merge(Fields, Values),
case
emqx_authn_utils:check_password_from_selected_map(
@ -149,8 +154,9 @@ authenticate(
of
ok ->
{ok, emqx_authn_utils:is_superuser(Selected)};
{error, _Reason} ->
ignore
{error, _Reason} = Error ->
Error
end
end;
{error, Reason} ->
?TRACE_AUTHN_PROVIDER(error, "redis_query_failed", #{

View File

@ -161,11 +161,13 @@ t_authenticate(_Config) ->
user_seeds()
).
test_user_auth(#{
test_user_auth(
#{
credentials := Credentials0,
config_params := SpecificConfigParams,
result := Result
}) ->
} = Config
) ->
AuthConfig = maps:merge(raw_redis_auth_config(), SpecificConfigParams),
{ok, _} = emqx:update_config(
@ -183,14 +185,12 @@ test_user_auth(#{
?assertEqual(Result, emqx_access_control:authenticate(Credentials)),
AuthnResult =
case Result of
{error, _} ->
ignore;
Any ->
Any
case maps:get(redis_result, Config, undefined) of
undefined ->
ok;
RedisResult ->
?assertEqual(RedisResult, emqx_authn_redis:authenticate(Credentials, State))
end,
?assertEqual(AuthnResult, emqx_authn_redis:authenticate(Credentials, State)),
emqx_authn_test_lib:delete_authenticators(
[authentication],
@ -478,7 +478,7 @@ user_seeds() ->
<<"cmd">> => <<"HMGET mqtt_user:${username} password_hash salt is_superuser">>,
<<"password_hash_algorithm">> => #{<<"name">> => <<"bcrypt">>}
},
result => {error, not_authorized}
result => {error, bad_username_or_password}
},
#{
@ -547,6 +547,23 @@ user_seeds() ->
}
},
result => {ok, #{is_superuser => true}}
},
%% user not exists
#{
data => #{
password_hash => <<"plainsalt">>,
salt => <<"salt">>,
is_superuser => <<"1">>
},
credentials => #{
username => <<"not_exists">>,
password => <<"plain">>
},
key => <<"mqtt_user:plain">>,
config_params => #{},
result => {error, not_authorized},
redis_result => ignore
}
].