Merge pull request #13238 from thalesmg/fix-authz-http-content-type-handling-r57-20240612

fix(http authz): handle unknown content types in responses
This commit is contained in:
Thales Macedo Garitezi 2024-06-13 09:10:43 -03:00 committed by GitHub
commit 6ccf1dcbf9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 74 additions and 2 deletions

View File

@ -188,7 +188,7 @@ render_sql_params(ParamList, Values) ->
),
Row.
-spec parse_http_resp_body(binary(), binary()) -> allow | deny | ignore | error.
-spec parse_http_resp_body(binary(), binary()) -> allow | deny | ignore | error | {error, term()}.
parse_http_resp_body(<<"application/x-www-form-urlencoded", _/binary>>, Body) ->
try
result(maps:from_list(cow_qs:parse_qs(Body)))
@ -200,7 +200,9 @@ parse_http_resp_body(<<"application/json", _/binary>>, Body) ->
result(emqx_utils_json:decode(Body, [return_maps]))
catch
_:_ -> error
end.
end;
parse_http_resp_body(ContentType = <<_/binary>>, _Body) ->
{error, <<"unsupported content-type: ", ContentType/binary>>}.
result(#{<<"result">> := <<"allow">>}) -> allow;
result(#{<<"result">> := <<"deny">>}) -> deny;

View File

@ -105,6 +105,9 @@ authorize(
body => Body
}),
nomatch;
{error, Reason} ->
?tp(error, bad_authz_http_response, #{reason => Reason}),
nomatch;
Result ->
{matched, Result}
end;

View File

@ -463,6 +463,72 @@ t_placeholder_and_body(_Config) ->
emqx_access_control:authorize(ClientInfo, ?AUTHZ_PUBLISH, <<"t">>)
).
%% Checks that we don't crash when receiving an unsupported content-type back.
t_bad_response_content_type(_Config) ->
ok = setup_handler_and_config(
fun(Req0, State) ->
?assertEqual(
<<"/authz/users/">>,
cowboy_req:path(Req0)
),
{ok, _PostVars, Req1} = cowboy_req:read_urlencoded_body(Req0),
Req = cowboy_req:reply(
200,
#{<<"content-type">> => <<"text/csv">>},
"hi",
Req1
),
{ok, Req, State}
end,
#{
<<"method">> => <<"post">>,
<<"body">> => #{
<<"username">> => <<"${username}">>,
<<"clientid">> => <<"${clientid}">>,
<<"peerhost">> => <<"${peerhost}">>,
<<"proto_name">> => <<"${proto_name}">>,
<<"mountpoint">> => <<"${mountpoint}">>,
<<"topic">> => <<"${topic}">>,
<<"action">> => <<"${action}">>,
<<"access">> => <<"${access}">>,
<<"CN">> => ?PH_CERT_CN_NAME,
<<"CS">> => ?PH_CERT_SUBJECT
},
<<"headers">> => #{
<<"accept">> => <<"text/plain">>,
<<"content-type">> => <<"application/json">>
}
}
),
ClientInfo = #{
clientid => <<"client id">>,
username => <<"user name">>,
peerhost => {127, 0, 0, 1},
protocol => <<"MQTT">>,
mountpoint => <<"MOUNTPOINT">>,
zone => default,
listener => {tcp, default},
cn => ?PH_CERT_CN_NAME,
dn => ?PH_CERT_SUBJECT
},
?check_trace(
?assertEqual(
deny,
emqx_access_control:authorize(ClientInfo, ?AUTHZ_PUBLISH, <<"t">>)
),
fun(Trace) ->
?assertMatch(
[#{reason := <<"unsupported content-type", _/binary>>}],
?of_kind(bad_authz_http_response, Trace)
),
ok
end
).
t_no_value_for_placeholder(_Config) ->
ok = setup_handler_and_config(
fun(Req0, State) ->

View File

@ -0,0 +1 @@
Improved the logged error messages when an HTTP authorization request with an unsupported content-type header is returned.