diff --git a/apps/emqx_authn/src/emqx_authn_utils.erl b/apps/emqx_authn/src/emqx_authn_utils.erl index 70d6a0b5f..a41a27d2a 100644 --- a/apps/emqx_authn/src/emqx_authn_utils.erl +++ b/apps/emqx_authn/src/emqx_authn_utils.erl @@ -73,14 +73,21 @@ start_resource_if_enabled(Result, _ResourceId, _Config) -> check_password_from_selected_map(_Algorithm, _Selected, undefined) -> {error, bad_username_or_password}; check_password_from_selected_map(Algorithm, Selected, Password) -> - Hash = maps:get(<<"password_hash">>, Selected, - maps:get(<<"password">>>, Selected, undefined)), + Hash = maps:get( + <<"password_hash">>, + Selected, + maps:get(<<"password">>, Selected, undefined) + ), case Hash of - undefined -> {error, bad_username_or_password}; + undefined -> + {error, bad_username_or_password}; _ -> Salt = maps:get(<<"salt">>, Selected, <<>>), - case emqx_authn_password_hashing:check_password( - Algorithm, Salt, Hash, Password) of + case + emqx_authn_password_hashing:check_password( + Algorithm, Salt, Hash, Password + ) + of true -> ok; false -> {error, bad_username_or_password} end @@ -165,10 +172,14 @@ make_resource_id(Name) -> handle_var({var, Name}, undefined) -> error({cannot_get_variable, Name}); +handle_var({var, <<"peerhost">>}, PeerHost) -> + emqx_placeholder:bin(inet:ntoa(PeerHost)); handle_var(_, Value) -> emqx_placeholder:bin(Value). handle_sql_var({var, Name}, undefined) -> error({cannot_get_variable, Name}); +handle_sql_var({var, <<"peerhost">>}, PeerHost) -> + emqx_placeholder:bin(inet:ntoa(PeerHost)); handle_sql_var(_, Value) -> emqx_placeholder:sql_data(Value). diff --git a/apps/emqx_authn/test/emqx_authn_http_SUITE.erl b/apps/emqx_authn/test/emqx_authn_http_SUITE.erl index fc79970af..4d17c7191 100644 --- a/apps/emqx_authn/test/emqx_authn_http_SUITE.erl +++ b/apps/emqx_authn/test/emqx_authn_http_SUITE.erl @@ -29,8 +29,10 @@ -define(HTTP_PORT, 32333). -define(HTTP_PATH, "/auth"). -define(CREDENTIALS, #{ + clientid => <<"clienta">>, username => <<"plain">>, password => <<"plain">>, + peerhost => {127, 0, 0, 1}, listener => 'tcp:default', protocol => mqtt }). @@ -390,6 +392,32 @@ samples() -> result => {ok, #{is_superuser => false}} }, + %% simple post request for placeholders, application/json + #{ + handler => fun(Req0, State) -> + {ok, RawBody, Req1} = cowboy_req:read_body(Req0), + #{ + <<"username">> := <<"plain">>, + <<"password">> := <<"plain">>, + <<"clientid">> := <<"clienta">>, + <<"peerhost">> := <<"127.0.0.1">> + } = jiffy:decode(RawBody, [return_maps]), + Req = cowboy_req:reply(200, Req1), + {ok, Req, State} + end, + config_params => #{ + <<"method">> => <<"post">>, + <<"headers">> => #{<<"content-type">> => <<"application/json">>}, + <<"body">> => #{ + <<"clientid">> => ?PH_CLIENTID, + <<"username">> => ?PH_USERNAME, + <<"password">> => ?PH_PASSWORD, + <<"peerhost">> => ?PH_PEERHOST + } + }, + result => {ok, #{is_superuser => false}} + }, + %% custom headers #{ handler => fun(Req0, State) ->