diff --git a/apps/emqx_authz/include/emqx_authz.hrl b/apps/emqx_authz/include/emqx_authz.hrl index 7b584b59b..245f19c1f 100644 --- a/apps/emqx_authz/include/emqx_authz.hrl +++ b/apps/emqx_authz/include/emqx_authz.hrl @@ -34,10 +34,10 @@ -define(CMD_APPEND, append). -define(CMD_MOVE, move). --define(CMD_MOVE_TOP, <<"top">>). --define(CMD_MOVE_BOTTOM, <<"bottom">>). --define(CMD_MOVE_BEFORE(Before), {<<"before">>, Before}). --define(CMD_MOVE_AFTER(After), {<<"after">>, After}). +-define(CMD_MOVE_TOP, top). +-define(CMD_MOVE_BOTTOM, bottom). +-define(CMD_MOVE_BEFORE(Before), {before, Before}). +-define(CMD_MOVE_AFTER(After), {'after', After}). -define(CONF_KEY_PATH, [authorization, sources]). diff --git a/apps/emqx_authz/src/emqx_authz.erl b/apps/emqx_authz/src/emqx_authz.erl index a51e78719..4ff06f697 100644 --- a/apps/emqx_authz/src/emqx_authz.erl +++ b/apps/emqx_authz/src/emqx_authz.erl @@ -110,10 +110,10 @@ lookup(Type) -> {Source, _Front, _Rear} = take(Type), Source. -move(Type, #{<<"before">> := Before}) -> +move(Type, {before, Before}) -> emqx_authz_utils:update_config( ?CONF_KEY_PATH, {?CMD_MOVE, type(Type), ?CMD_MOVE_BEFORE(type(Before))}); -move(Type, #{<<"after">> := After}) -> +move(Type, {'after', After}) -> emqx_authz_utils:update_config( ?CONF_KEY_PATH, {?CMD_MOVE, type(Type), ?CMD_MOVE_AFTER(type(After))}); move(Type, Position) -> @@ -334,7 +334,7 @@ take(Type, Sources) -> {Front, Rear} = lists:splitwith(fun(T) -> type(T) =/= type(Type) end, Sources), case Rear =:= [] of true -> - error({authz_source_of_type_not_found, Type}); + error({not_found_source, Type}); _ -> {hd(Rear), Front, tl(Rear)} end. diff --git a/apps/emqx_authz/src/emqx_authz_api_schema.erl b/apps/emqx_authz/src/emqx_authz_api_schema.erl index 8cfcf3033..882d1581f 100644 --- a/apps/emqx_authz/src/emqx_authz_api_schema.erl +++ b/apps/emqx_authz/src/emqx_authz_api_schema.erl @@ -74,11 +74,10 @@ fields(file) -> , example => <<"acl.conf">>}}]; fields(position) -> [ { position - , mk( hoconsc:union([binary(), map()]) + , mk( string() , #{ desc => <<"Where to place the source">> , required => true - , in => body - , example => #{<<"before">> => <<"file">>}})}]. + , in => body})}]. %%------------------------------------------------------------------------------ %% http type funcs diff --git a/apps/emqx_authz/src/emqx_authz_api_sources.erl b/apps/emqx_authz/src/emqx_authz_api_sources.erl index 731c5d40f..bddfddb49 100644 --- a/apps/emqx_authz/src/emqx_authz_api_sources.erl +++ b/apps/emqx_authz/src/emqx_authz_api_sources.erl @@ -262,14 +262,25 @@ move_source(Method, #{bindings := #{type := Type} = Bindings } = Req) when is_atom(Type) -> move_source(Method, Req#{bindings => Bindings#{type => atom_to_binary(Type, utf8)}}); move_source(post, #{bindings := #{type := Type}, body := #{<<"position">> := Position}}) -> - case emqx_authz:move(Type, Position) of - {ok, _} -> {204}; - {error, not_found_source} -> - {404, #{code => <<"NOT_FOUND">>, - message => <<"source ", Type/binary, " not found">>}}; - {error, {emqx_conf_schema, _}} -> - {400, #{code => <<"BAD_REQUEST">>, - message => <<"BAD_SCHEMA">>}}; + case parse_position(Position) of + {ok, NPosition} -> + try emqx_authz:move(Type, NPosition) of + {ok, _} -> {204}; + {error, {not_found_source, _Type}} -> + {404, #{code => <<"NOT_FOUND">>, + message => <<"source ", Type/binary, " not found">>}}; + {error, {emqx_conf_schema, _}} -> + {400, #{code => <<"BAD_REQUEST">>, + message => <<"BAD_SCHEMA">>}}; + {error, Reason} -> + {400, #{code => <<"BAD_REQUEST">>, + message => bin(Reason)}} + catch + error : {unknown_authz_source_type, Unknown} -> + NUnknown = bin(Unknown), + {400, #{code => <<"BAD_REQUEST">>, + message => <<"Unknown authz Source Type: ", NUnknown/binary>>}} + end; {error, Reason} -> {400, #{code => <<"BAD_REQUEST">>, message => bin(Reason)}} @@ -457,8 +468,6 @@ do_write_file(Filename, Bytes) -> error(Reason) end. -bin(Term) -> erlang:iolist_to_binary(io_lib:format("~p", [Term])). - acl_conf_file() -> emqx_authz:acl_conf_file(). @@ -468,8 +477,34 @@ parameters_field() -> } ]. +parse_position(<<"top">>) -> + {ok, ?CMD_MOVE_TOP}; +parse_position(<<"bottom">>) -> + {ok, ?CMD_MOVE_BOTTOM}; +parse_position(<<"before:", Before/binary>>) -> + {ok, ?CMD_MOVE_BEFORE(Before)}; +parse_position(<<"after:", After/binary>>) -> + {ok, ?CMD_MOVE_AFTER(After)}; +parse_position(<<"before:">>) -> + {error, {invalid_parameter, position}}; +parse_position(<<"after:">>) -> + {error, {invalid_parameter, position}}; +parse_position(_) -> + {error, {invalid_parameter, position}}. + position_example() -> - #{<<"position">> => #{<<"before">> => <<"file">>}}. + #{ top => + #{ summary => <<"top example">> + , value => #{<<"position">> => <<"top">>}} + , bottom => + #{ summary => <<"bottom example">> + , value => #{<<"position">> => <<"bottom">>}} + , relative => + #{ summary => <<"relative example">> + , value => #{<<"position">> => <<"before:file">>}} + }. authz_sources_types(Type) -> emqx_authz_api_schema:authz_sources_types(Type). + +bin(Term) -> erlang:iolist_to_binary(io_lib:format("~p", [Term])).