fix: use minirest filter
This commit is contained in:
parent
4e0e755b28
commit
ea9228108b
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
-behaviour(minirest_api).
|
-behaviour(minirest_api).
|
||||||
|
|
||||||
|
-include("emqx_auth_mnesia.hrl").
|
||||||
-include_lib("emqx_auth/include/emqx_authz.hrl").
|
-include_lib("emqx_auth/include/emqx_authz.hrl").
|
||||||
-include_lib("emqx/include/logger.hrl").
|
-include_lib("emqx/include/logger.hrl").
|
||||||
-include_lib("hocon/include/hoconsc.hrl").
|
-include_lib("hocon/include/hoconsc.hrl").
|
||||||
|
@ -55,6 +56,9 @@
|
||||||
format_result/1
|
format_result/1
|
||||||
]).
|
]).
|
||||||
|
|
||||||
|
%% minirest filter callback
|
||||||
|
-export([is_configured_authz_source/2]).
|
||||||
|
|
||||||
-define(BAD_REQUEST, 'BAD_REQUEST').
|
-define(BAD_REQUEST, 'BAD_REQUEST').
|
||||||
-define(NOT_FOUND, 'NOT_FOUND').
|
-define(NOT_FOUND, 'NOT_FOUND').
|
||||||
-define(ALREADY_EXISTS, 'ALREADY_EXISTS').
|
-define(ALREADY_EXISTS, 'ALREADY_EXISTS').
|
||||||
|
@ -85,6 +89,7 @@ paths() ->
|
||||||
schema("/authorization/sources/built_in_database/rules/users") ->
|
schema("/authorization/sources/built_in_database/rules/users") ->
|
||||||
#{
|
#{
|
||||||
'operationId' => users,
|
'operationId' => users,
|
||||||
|
filter => fun ?MODULE:is_configured_authz_source/2,
|
||||||
get =>
|
get =>
|
||||||
#{
|
#{
|
||||||
tags => [<<"authorization">>],
|
tags => [<<"authorization">>],
|
||||||
|
@ -131,6 +136,7 @@ schema("/authorization/sources/built_in_database/rules/users") ->
|
||||||
schema("/authorization/sources/built_in_database/rules/clients") ->
|
schema("/authorization/sources/built_in_database/rules/clients") ->
|
||||||
#{
|
#{
|
||||||
'operationId' => clients,
|
'operationId' => clients,
|
||||||
|
filter => fun ?MODULE:is_configured_authz_source/2,
|
||||||
get =>
|
get =>
|
||||||
#{
|
#{
|
||||||
tags => [<<"authorization">>],
|
tags => [<<"authorization">>],
|
||||||
|
@ -177,6 +183,7 @@ schema("/authorization/sources/built_in_database/rules/clients") ->
|
||||||
schema("/authorization/sources/built_in_database/rules/users/:username") ->
|
schema("/authorization/sources/built_in_database/rules/users/:username") ->
|
||||||
#{
|
#{
|
||||||
'operationId' => user,
|
'operationId' => user,
|
||||||
|
filter => fun ?MODULE:is_configured_authz_source/2,
|
||||||
get =>
|
get =>
|
||||||
#{
|
#{
|
||||||
tags => [<<"authorization">>],
|
tags => [<<"authorization">>],
|
||||||
|
@ -230,6 +237,7 @@ schema("/authorization/sources/built_in_database/rules/users/:username") ->
|
||||||
schema("/authorization/sources/built_in_database/rules/clients/:clientid") ->
|
schema("/authorization/sources/built_in_database/rules/clients/:clientid") ->
|
||||||
#{
|
#{
|
||||||
'operationId' => client,
|
'operationId' => client,
|
||||||
|
filter => fun ?MODULE:is_configured_authz_source/2,
|
||||||
get =>
|
get =>
|
||||||
#{
|
#{
|
||||||
tags => [<<"authorization">>],
|
tags => [<<"authorization">>],
|
||||||
|
@ -283,6 +291,7 @@ schema("/authorization/sources/built_in_database/rules/clients/:clientid") ->
|
||||||
schema("/authorization/sources/built_in_database/rules/all") ->
|
schema("/authorization/sources/built_in_database/rules/all") ->
|
||||||
#{
|
#{
|
||||||
'operationId' => all,
|
'operationId' => all,
|
||||||
|
filter => fun ?MODULE:is_configured_authz_source/2,
|
||||||
get =>
|
get =>
|
||||||
#{
|
#{
|
||||||
tags => [<<"authorization">>],
|
tags => [<<"authorization">>],
|
||||||
|
@ -317,6 +326,7 @@ schema("/authorization/sources/built_in_database/rules/all") ->
|
||||||
schema("/authorization/sources/built_in_database/rules") ->
|
schema("/authorization/sources/built_in_database/rules") ->
|
||||||
#{
|
#{
|
||||||
'operationId' => rules,
|
'operationId' => rules,
|
||||||
|
filter => fun ?MODULE:is_configured_authz_source/2,
|
||||||
delete =>
|
delete =>
|
||||||
#{
|
#{
|
||||||
tags => [<<"authorization">>],
|
tags => [<<"authorization">>],
|
||||||
|
@ -426,210 +436,173 @@ fields(rules) ->
|
||||||
%% HTTP API
|
%% HTTP API
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
-define(IF_CONFIGURED_AUTHZ_SOURCE(EXPR),
|
is_configured_authz_source(Params, _Meta) ->
|
||||||
emqx_authz_api_sources:with_source(
|
emqx_authz_api_sources:with_source(
|
||||||
<<"built_in_database">>,
|
?AUTHZ_TYPE_BIN,
|
||||||
fun(_Source) ->
|
fun(_Source) ->
|
||||||
EXPR
|
{ok, Params}
|
||||||
end
|
end
|
||||||
)
|
).
|
||||||
).
|
|
||||||
|
|
||||||
users(get, #{query_string := QueryString}) ->
|
users(get, #{query_string := QueryString}) ->
|
||||||
?IF_CONFIGURED_AUTHZ_SOURCE(
|
case
|
||||||
case
|
emqx_mgmt_api:node_query(
|
||||||
emqx_mgmt_api:node_query(
|
node(),
|
||||||
node(),
|
?ACL_TABLE,
|
||||||
?ACL_TABLE,
|
QueryString,
|
||||||
QueryString,
|
?ACL_USERNAME_QSCHEMA,
|
||||||
?ACL_USERNAME_QSCHEMA,
|
?QUERY_USERNAME_FUN,
|
||||||
?QUERY_USERNAME_FUN,
|
fun ?MODULE:format_result/1
|
||||||
fun ?MODULE:format_result/1
|
)
|
||||||
)
|
of
|
||||||
of
|
{error, page_limit_invalid} ->
|
||||||
{error, page_limit_invalid} ->
|
{400, #{code => <<"INVALID_PARAMETER">>, message => <<"page_limit_invalid">>}};
|
||||||
{400, #{code => <<"INVALID_PARAMETER">>, message => <<"page_limit_invalid">>}};
|
{error, Node, Error} ->
|
||||||
{error, Node, Error} ->
|
Message = list_to_binary(
|
||||||
Message = list_to_binary(
|
io_lib:format("bad rpc call ~p, Reason ~p", [Node, Error])
|
||||||
io_lib:format("bad rpc call ~p, Reason ~p", [Node, Error])
|
),
|
||||||
),
|
{500, #{code => <<"NODE_DOWN">>, message => Message}};
|
||||||
{500, #{code => <<"NODE_DOWN">>, message => Message}};
|
Result ->
|
||||||
Result ->
|
{200, Result}
|
||||||
{200, Result}
|
end;
|
||||||
end
|
|
||||||
);
|
|
||||||
users(post, #{body := Body}) when is_list(Body) ->
|
users(post, #{body := Body}) when is_list(Body) ->
|
||||||
?IF_CONFIGURED_AUTHZ_SOURCE(
|
case ensure_all_not_exists(<<"username">>, username, Body) of
|
||||||
case ensure_all_not_exists(<<"username">>, username, Body) of
|
[] ->
|
||||||
[] ->
|
lists:foreach(
|
||||||
lists:foreach(
|
fun(#{<<"username">> := Username, <<"rules">> := Rules}) ->
|
||||||
fun(#{<<"username">> := Username, <<"rules">> := Rules}) ->
|
emqx_authz_mnesia:store_rules({username, Username}, Rules)
|
||||||
emqx_authz_mnesia:store_rules({username, Username}, Rules)
|
end,
|
||||||
end,
|
Body
|
||||||
Body
|
),
|
||||||
),
|
{204};
|
||||||
{204};
|
Exists ->
|
||||||
Exists ->
|
{409, #{
|
||||||
{409, #{
|
code => <<"ALREADY_EXISTS">>,
|
||||||
code => <<"ALREADY_EXISTS">>,
|
message => binfmt("Users '~ts' already exist", [binjoin(Exists)])
|
||||||
message => binfmt("Users '~ts' already exist", [binjoin(Exists)])
|
}}
|
||||||
}}
|
end.
|
||||||
end
|
|
||||||
).
|
|
||||||
|
|
||||||
clients(get, #{query_string := QueryString}) ->
|
clients(get, #{query_string := QueryString}) ->
|
||||||
?IF_CONFIGURED_AUTHZ_SOURCE(
|
case
|
||||||
case
|
emqx_mgmt_api:node_query(
|
||||||
emqx_mgmt_api:node_query(
|
node(),
|
||||||
node(),
|
?ACL_TABLE,
|
||||||
?ACL_TABLE,
|
QueryString,
|
||||||
QueryString,
|
?ACL_CLIENTID_QSCHEMA,
|
||||||
?ACL_CLIENTID_QSCHEMA,
|
?QUERY_CLIENTID_FUN,
|
||||||
?QUERY_CLIENTID_FUN,
|
fun ?MODULE:format_result/1
|
||||||
fun ?MODULE:format_result/1
|
)
|
||||||
)
|
of
|
||||||
of
|
{error, page_limit_invalid} ->
|
||||||
{error, page_limit_invalid} ->
|
{400, #{code => <<"INVALID_PARAMETER">>, message => <<"page_limit_invalid">>}};
|
||||||
{400, #{code => <<"INVALID_PARAMETER">>, message => <<"page_limit_invalid">>}};
|
{error, Node, Error} ->
|
||||||
{error, Node, Error} ->
|
Message = list_to_binary(
|
||||||
Message = list_to_binary(
|
io_lib:format("bad rpc call ~p, Reason ~p", [Node, Error])
|
||||||
io_lib:format("bad rpc call ~p, Reason ~p", [Node, Error])
|
),
|
||||||
),
|
{500, #{code => <<"NODE_DOWN">>, message => Message}};
|
||||||
{500, #{code => <<"NODE_DOWN">>, message => Message}};
|
Result ->
|
||||||
Result ->
|
{200, Result}
|
||||||
{200, Result}
|
end;
|
||||||
end
|
|
||||||
);
|
|
||||||
clients(post, #{body := Body}) when is_list(Body) ->
|
clients(post, #{body := Body}) when is_list(Body) ->
|
||||||
?IF_CONFIGURED_AUTHZ_SOURCE(
|
case ensure_all_not_exists(<<"clientid">>, clientid, Body) of
|
||||||
case ensure_all_not_exists(<<"clientid">>, clientid, Body) of
|
[] ->
|
||||||
[] ->
|
lists:foreach(
|
||||||
lists:foreach(
|
fun(#{<<"clientid">> := ClientID, <<"rules">> := Rules}) ->
|
||||||
fun(#{<<"clientid">> := ClientID, <<"rules">> := Rules}) ->
|
emqx_authz_mnesia:store_rules({clientid, ClientID}, Rules)
|
||||||
emqx_authz_mnesia:store_rules({clientid, ClientID}, Rules)
|
end,
|
||||||
end,
|
Body
|
||||||
Body
|
),
|
||||||
),
|
{204};
|
||||||
{204};
|
Exists ->
|
||||||
Exists ->
|
{409, #{
|
||||||
{409, #{
|
code => <<"ALREADY_EXISTS">>,
|
||||||
code => <<"ALREADY_EXISTS">>,
|
message => binfmt("Clients '~ts' already exist", [binjoin(Exists)])
|
||||||
message => binfmt("Clients '~ts' already exist", [binjoin(Exists)])
|
}}
|
||||||
}}
|
end.
|
||||||
end
|
|
||||||
).
|
|
||||||
|
|
||||||
user(get, #{bindings := #{username := Username}}) ->
|
user(get, #{bindings := #{username := Username}}) ->
|
||||||
?IF_CONFIGURED_AUTHZ_SOURCE(
|
case emqx_authz_mnesia:get_rules({username, Username}) of
|
||||||
case emqx_authz_mnesia:get_rules({username, Username}) of
|
not_found ->
|
||||||
not_found ->
|
{404, #{code => <<"NOT_FOUND">>, message => <<"Not Found">>}};
|
||||||
{404, #{code => <<"NOT_FOUND">>, message => <<"Not Found">>}};
|
{ok, Rules} ->
|
||||||
{ok, Rules} ->
|
{200, #{
|
||||||
{200, #{
|
username => Username,
|
||||||
username => Username,
|
rules => format_rules(Rules)
|
||||||
rules => format_rules(Rules)
|
}}
|
||||||
}}
|
end;
|
||||||
end
|
|
||||||
);
|
|
||||||
user(put, #{
|
user(put, #{
|
||||||
bindings := #{username := Username},
|
bindings := #{username := Username},
|
||||||
body := #{<<"username">> := Username, <<"rules">> := Rules}
|
body := #{<<"username">> := Username, <<"rules">> := Rules}
|
||||||
}) ->
|
}) ->
|
||||||
?IF_CONFIGURED_AUTHZ_SOURCE(
|
emqx_authz_mnesia:store_rules({username, Username}, Rules),
|
||||||
begin
|
{204};
|
||||||
emqx_authz_mnesia:store_rules({username, Username}, Rules),
|
|
||||||
{204}
|
|
||||||
end
|
|
||||||
);
|
|
||||||
user(delete, #{bindings := #{username := Username}}) ->
|
user(delete, #{bindings := #{username := Username}}) ->
|
||||||
?IF_CONFIGURED_AUTHZ_SOURCE(
|
case emqx_authz_mnesia:get_rules({username, Username}) of
|
||||||
case emqx_authz_mnesia:get_rules({username, Username}) of
|
not_found ->
|
||||||
not_found ->
|
{404, #{code => <<"NOT_FOUND">>, message => <<"Username Not Found">>}};
|
||||||
{404, #{code => <<"NOT_FOUND">>, message => <<"Username Not Found">>}};
|
{ok, _Rules} ->
|
||||||
{ok, _Rules} ->
|
emqx_authz_mnesia:delete_rules({username, Username}),
|
||||||
emqx_authz_mnesia:delete_rules({username, Username}),
|
{204}
|
||||||
{204}
|
end.
|
||||||
end
|
|
||||||
).
|
|
||||||
|
|
||||||
client(get, #{bindings := #{clientid := ClientID}}) ->
|
client(get, #{bindings := #{clientid := ClientID}}) ->
|
||||||
?IF_CONFIGURED_AUTHZ_SOURCE(
|
case emqx_authz_mnesia:get_rules({clientid, ClientID}) of
|
||||||
case emqx_authz_mnesia:get_rules({clientid, ClientID}) of
|
not_found ->
|
||||||
not_found ->
|
{404, #{code => <<"NOT_FOUND">>, message => <<"Not Found">>}};
|
||||||
{404, #{code => <<"NOT_FOUND">>, message => <<"Not Found">>}};
|
{ok, Rules} ->
|
||||||
{ok, Rules} ->
|
{200, #{
|
||||||
{200, #{
|
clientid => ClientID,
|
||||||
clientid => ClientID,
|
rules => format_rules(Rules)
|
||||||
rules => format_rules(Rules)
|
}}
|
||||||
}}
|
end;
|
||||||
end
|
|
||||||
);
|
|
||||||
client(put, #{
|
client(put, #{
|
||||||
bindings := #{clientid := ClientID},
|
bindings := #{clientid := ClientID},
|
||||||
body := #{<<"clientid">> := ClientID, <<"rules">> := Rules}
|
body := #{<<"clientid">> := ClientID, <<"rules">> := Rules}
|
||||||
}) ->
|
}) ->
|
||||||
?IF_CONFIGURED_AUTHZ_SOURCE(
|
emqx_authz_mnesia:store_rules({clientid, ClientID}, Rules),
|
||||||
begin
|
{204};
|
||||||
emqx_authz_mnesia:store_rules({clientid, ClientID}, Rules),
|
|
||||||
{204}
|
|
||||||
end
|
|
||||||
);
|
|
||||||
client(delete, #{bindings := #{clientid := ClientID}}) ->
|
client(delete, #{bindings := #{clientid := ClientID}}) ->
|
||||||
?IF_CONFIGURED_AUTHZ_SOURCE(
|
case emqx_authz_mnesia:get_rules({clientid, ClientID}) of
|
||||||
case emqx_authz_mnesia:get_rules({clientid, ClientID}) of
|
not_found ->
|
||||||
not_found ->
|
{404, #{code => <<"NOT_FOUND">>, message => <<"ClientID Not Found">>}};
|
||||||
{404, #{code => <<"NOT_FOUND">>, message => <<"ClientID Not Found">>}};
|
{ok, _Rules} ->
|
||||||
{ok, _Rules} ->
|
emqx_authz_mnesia:delete_rules({clientid, ClientID}),
|
||||||
emqx_authz_mnesia:delete_rules({clientid, ClientID}),
|
{204}
|
||||||
{204}
|
end.
|
||||||
end
|
|
||||||
).
|
|
||||||
|
|
||||||
all(get, _) ->
|
all(get, _) ->
|
||||||
?IF_CONFIGURED_AUTHZ_SOURCE(
|
case emqx_authz_mnesia:get_rules(all) of
|
||||||
case emqx_authz_mnesia:get_rules(all) of
|
not_found ->
|
||||||
not_found ->
|
{200, #{rules => []}};
|
||||||
{200, #{rules => []}};
|
{ok, Rules} ->
|
||||||
{ok, Rules} ->
|
{200, #{
|
||||||
{200, #{
|
rules => format_rules(Rules)
|
||||||
rules => format_rules(Rules)
|
}}
|
||||||
}}
|
end;
|
||||||
end
|
|
||||||
);
|
|
||||||
all(post, #{body := #{<<"rules">> := Rules}}) ->
|
all(post, #{body := #{<<"rules">> := Rules}}) ->
|
||||||
?IF_CONFIGURED_AUTHZ_SOURCE(
|
emqx_authz_mnesia:store_rules(all, Rules),
|
||||||
begin
|
{204};
|
||||||
emqx_authz_mnesia:store_rules(all, Rules),
|
|
||||||
{204}
|
|
||||||
end
|
|
||||||
);
|
|
||||||
all(delete, _) ->
|
all(delete, _) ->
|
||||||
?IF_CONFIGURED_AUTHZ_SOURCE(
|
emqx_authz_mnesia:store_rules(all, []),
|
||||||
begin
|
{204}.
|
||||||
emqx_authz_mnesia:store_rules(all, []),
|
|
||||||
{204}
|
|
||||||
end
|
|
||||||
).
|
|
||||||
|
|
||||||
rules(delete, _) ->
|
rules(delete, _) ->
|
||||||
?IF_CONFIGURED_AUTHZ_SOURCE(
|
case emqx_authz_api_sources:get_raw_source(<<"built_in_database">>) of
|
||||||
case emqx_authz_api_sources:get_raw_source(<<"built_in_database">>) of
|
[#{<<"enable">> := false}] ->
|
||||||
[#{<<"enable">> := false}] ->
|
ok = emqx_authz_mnesia:purge_rules(),
|
||||||
ok = emqx_authz_mnesia:purge_rules(),
|
{204};
|
||||||
{204};
|
[#{<<"enable">> := true}] ->
|
||||||
[#{<<"enable">> := true}] ->
|
{400, #{
|
||||||
{400, #{
|
code => <<"BAD_REQUEST">>,
|
||||||
code => <<"BAD_REQUEST">>,
|
message =>
|
||||||
message =>
|
<<"'built_in_database' type source must be disabled before purge.">>
|
||||||
<<"'built_in_database' type source must be disabled before purge.">>
|
}};
|
||||||
}};
|
[] ->
|
||||||
[] ->
|
{404, #{
|
||||||
{404, #{
|
code => <<"BAD_REQUEST">>,
|
||||||
code => <<"BAD_REQUEST">>,
|
message => <<"'built_in_database' type source is not found.">>
|
||||||
message => <<"'built_in_database' type source is not found.">>
|
}}
|
||||||
}}
|
end.
|
||||||
end
|
|
||||||
).
|
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% QueryString to MatchSpec
|
%% QueryString to MatchSpec
|
||||||
|
|
|
@ -415,7 +415,9 @@ run_examples(Code, Examples) when is_number(Code) ->
|
||||||
run_examples(
|
run_examples(
|
||||||
fun
|
fun
|
||||||
({ok, ResCode, _}) when Code =:= ResCode -> true;
|
({ok, ResCode, _}) when Code =:= ResCode -> true;
|
||||||
(_) -> false
|
(_Res) ->
|
||||||
|
ct:pal("check failed: ~p", [_Res]),
|
||||||
|
false
|
||||||
end,
|
end,
|
||||||
Examples
|
Examples
|
||||||
).
|
).
|
||||||
|
@ -455,7 +457,9 @@ make_examples(ApiMod, Replacements) ->
|
||||||
end,
|
end,
|
||||||
{replace_parts(to_parts(Path), Replacements), Op, Body}
|
{replace_parts(to_parts(Path), Replacements), Op, Body}
|
||||||
end,
|
end,
|
||||||
lists:sort(fun op_sort/2, maps:to_list(maps:remove('operationId', Schema)))
|
lists:sort(
|
||||||
|
fun op_sort/2, maps:to_list(maps:with([get, put, post, delete], Schema))
|
||||||
|
)
|
||||||
)
|
)
|
||||||
end,
|
end,
|
||||||
Paths
|
Paths
|
||||||
|
|
Loading…
Reference in New Issue