chore: treat 200/204 as acl nomatch

This commit is contained in:
JianBo He 2022-07-01 20:29:21 +08:00
parent 371d24549a
commit 4c17b38102
3 changed files with 57 additions and 48 deletions

View File

@ -80,28 +80,26 @@ authorize(
) -> ) ->
Request = generate_request(PubSub, Topic, Client, Config), Request = generate_request(PubSub, Topic, Client, Config),
case emqx_resource:query(ResourceID, {Method, Request, RequestTimeout}) of case emqx_resource:query(ResourceID, {Method, Request, RequestTimeout}) of
{ok, 200, _Headers} ->
{matched, allow};
{ok, 204, _Headers} -> {ok, 204, _Headers} ->
{matched, allow}; {matched, allow};
{ok, 200, Headers, Body} -> {ok, 200, Headers, Body} ->
ContentType = content_type(Headers), ContentType = emqx_authz_utils:content_type(Headers),
case emqx_authz_utils:parse_http_resp_body(ContentType, Body) of case emqx_authz_utils:parse_http_resp_body(ContentType, Body) of
error -> error ->
?SLOG(error, #{ ?SLOG(error, #{
msg => authz_http_response_incorrect, msg => authz_http_response_incorrect,
content_type => proplists:get_value( content_type => ContentType,
<<"content-type">>, Headers
),
body => Body body => Body
}), }),
nomatch; nomatch;
Result -> Result ->
{matched, Result} {matched, Result}
end; end;
{ok, _Status, _Headers} -> {ok, Status, Headers} ->
log_nomtach_msg(Status, Headers, undefined),
nomatch; nomatch;
{ok, _Status, _Headers, _Body} -> {ok, Status, Headers, Body} ->
log_nomtach_msg(Status, Headers, Body),
nomatch; nomatch;
{error, Reason} -> {error, Reason} ->
?SLOG(error, #{ ?SLOG(error, #{
@ -112,6 +110,17 @@ authorize(
ignore ignore
end. end.
log_nomtach_msg(Status, Headers, Body) ->
?SLOG(
debug,
#{
msg => unexpected_authz_http_response,
status => Status,
content_type => emqx_authz_utils:content_type(Headers),
body => Body
}
).
parse_config( parse_config(
#{ #{
url := RawUrl, url := RawUrl,
@ -218,15 +227,6 @@ serialize_body(<<"application/json">>, Body) ->
serialize_body(<<"application/x-www-form-urlencoded">>, Body) -> serialize_body(<<"application/x-www-form-urlencoded">>, Body) ->
query_string(Body). query_string(Body).
content_type(Headers) when is_list(Headers) ->
content_type(maps:from_list(Headers));
content_type(#{<<"content-type">> := Type}) ->
Type;
content_type(#{<<"Content-Type">> := Type}) ->
Type;
content_type(Headers) when is_map(Headers) ->
<<"application/json">>.
client_vars(Client, PubSub, Topic) -> client_vars(Client, PubSub, Topic) ->
Client#{ Client#{
action => PubSub, action => PubSub,

View File

@ -34,7 +34,10 @@
render_sql_params/2 render_sql_params/2
]). ]).
-export([parse_http_resp_body/2]). -export([
parse_http_resp_body/2,
content_type/1
]).
-define(DEFAULT_RESOURCE_OPTS, #{ -define(DEFAULT_RESOURCE_OPTS, #{
auto_retry_interval => 6000, auto_retry_interval => 6000,
@ -151,6 +154,16 @@ result(#{<<"result">> := <<"deny">>}) -> deny;
result(#{<<"result">> := <<"ignore">>}) -> ignore; result(#{<<"result">> := <<"ignore">>}) -> ignore;
result(_) -> error. result(_) -> error.
-spec content_type(cow_http:headers()) -> binary().
content_type(Headers) when is_list(Headers) ->
%% header name is lower case, see:
%% https://github.com/ninenines/cowlib/blob/ce6798c6b2e95b6a34c6a76d2489eaf159827d80/src/cow_http.erl#L192
proplists:get_value(
<<"content-type">>,
Headers,
<<"application/json">>
).
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
%% Internal functions %% Internal functions
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------

View File

@ -26,6 +26,15 @@
-define(HTTP_PORT, 33333). -define(HTTP_PORT, 33333).
-define(HTTP_PATH, "/authz/[...]"). -define(HTTP_PATH, "/authz/[...]").
-define(AUTHZ_HTTP_RESP(Result, Req),
cowboy_req:reply(
200,
#{<<"content-type">> => <<"application/json">>},
"{\"result\": \"" ++ atom_to_list(Result) ++ "\"}",
Req
)
).
all() -> all() ->
emqx_common_test_helpers:all(?MODULE). emqx_common_test_helpers:all(?MODULE).
@ -69,27 +78,10 @@ t_response_handling(_Config) ->
listener => {tcp, default} listener => {tcp, default}
}, },
%% OK, get, no body
ok = setup_handler_and_config(
fun(Req0, State) ->
Req = cowboy_req:reply(200, Req0),
{ok, Req, State}
end,
#{}
),
allow = emqx_access_control:authorize(ClientInfo, publish, <<"t">>),
%% OK, get, body & headers %% OK, get, body & headers
ok = setup_handler_and_config( ok = setup_handler_and_config(
fun(Req0, State) -> fun(Req0, State) ->
Req = cowboy_req:reply( {ok, ?AUTHZ_HTTP_RESP(allow, Req0), State}
200,
#{<<"content-type">> => <<"application/json">>},
"{\"result\": \"allow\"}",
Req0
),
{ok, Req, State}
end, end,
#{} #{}
), ),
@ -99,6 +91,17 @@ t_response_handling(_Config) ->
emqx_access_control:authorize(ClientInfo, publish, <<"t">>) emqx_access_control:authorize(ClientInfo, publish, <<"t">>)
), ),
%% Not OK, get, no body
ok = setup_handler_and_config(
fun(Req0, State) ->
Req = cowboy_req:reply(200, Req0),
{ok, Req, State}
end,
#{}
),
deny = emqx_access_control:authorize(ClientInfo, publish, <<"t">>),
%% OK, get, 204 %% OK, get, 204
ok = setup_handler_and_config( ok = setup_handler_and_config(
fun(Req0, State) -> fun(Req0, State) ->
@ -169,8 +172,7 @@ t_query_params(_Config) ->
], ],
Req0 Req0
), ),
Req = cowboy_req:reply(200, Req0), {ok, ?AUTHZ_HTTP_RESP(allow, Req0), State}
{ok, Req, State}
end, end,
#{ #{
<<"url">> => << <<"url">> => <<
@ -217,8 +219,7 @@ t_path(_Config) ->
>>, >>,
cowboy_req:path(Req0) cowboy_req:path(Req0)
), ),
Req = cowboy_req:reply(200, Req0), {ok, ?AUTHZ_HTTP_RESP(allow, Req0), State}
{ok, Req, State}
end, end,
#{ #{
<<"url">> => << <<"url">> => <<
@ -271,9 +272,7 @@ t_json_body(_Config) ->
}, },
jiffy:decode(RawBody, [return_maps]) jiffy:decode(RawBody, [return_maps])
), ),
{ok, ?AUTHZ_HTTP_RESP(allow, Req1), State}
Req = cowboy_req:reply(200, Req1),
{ok, Req, State}
end, end,
#{ #{
<<"method">> => <<"post">>, <<"method">> => <<"post">>,
@ -326,9 +325,7 @@ t_form_body(_Config) ->
}, },
jiffy:decode(PostVars, [return_maps]) jiffy:decode(PostVars, [return_maps])
), ),
{ok, ?AUTHZ_HTTP_RESP(allow, Req1), State}
Req = cowboy_req:reply(200, Req1),
{ok, Req, State}
end, end,
#{ #{
<<"method">> => <<"post">>, <<"method">> => <<"post">>,
@ -372,8 +369,7 @@ t_create_replace(_Config) ->
%% Create with valid URL %% Create with valid URL
ok = setup_handler_and_config( ok = setup_handler_and_config(
fun(Req0, State) -> fun(Req0, State) ->
Req = cowboy_req:reply(200, Req0), {ok, ?AUTHZ_HTTP_RESP(allow, Req0), State}
{ok, Req, State}
end, end,
#{ #{
<<"url">> => <<"url">> =>