The keys and values are used to render templates for authz rules, such as topic names, and SQL statements etc.
@@ -207,10 +207,20 @@ is_superuser(#{}) ->
#{is_superuser => false}.
client_attrs(#{<<"client_attrs">> := Attrs}) ->
- #{client_attrs => Attrs};
+ #{client_attrs => drop_invalid_attr(Attrs)};
client_attrs(_) ->
#{client_attrs => #{}}.
+drop_invalid_attr(Map) when is_map(Map) ->
+ maps:from_list(do_drop_invalid_attr(maps:to_list(Map))).
+
+do_drop_invalid_attr(KVL) ->
+ F = fun({K, V}) ->
+ emqx_utils:is_restricted_str(K) andalso
+ emqx_utils:is_restricted_str(V)
+ end,
+ lists:filter(F, KVL).
ensure_apps_started(bcrypt) ->
{ok, _} = application:ensure_all_started(bcrypt),
ok;
@@ -542,13 +542,21 @@ samples() ->
Req = cowboy_req:reply(
200,
#{<<"content-type">> => <<"application/json">>},
- emqx_utils_json:encode(#{result => allow, is_superuser => true}),
+ emqx_utils_json:encode(#{
+ result => allow,
+ is_superuser => true,
+ client_attrs => #{
+ fid => <<"n11">>,
+ <<"_bad_key">> => <<"v">>,
+ <<"ok_key">> => <<"but bad value">>
+ }
+ }),
Req0
),
{ok, Req, State}
end,
config_params => #{},
- result => {ok, #{is_superuser => true, client_attrs => #{}}}
+ result => {ok, #{is_superuser => true, client_attrs => #{<<"fid">> => <<"n11">>}}}
},
%% get request with url-form-encoded body response
@@ -67,7 +67,8 @@
format/1,
call_first_defined/1,
ntoa/1,
- foldl_while/3
+ foldl_while/3,
+ is_restricted_str/1
]).
-export([
@@ -861,6 +862,13 @@ ntoa({0, 0, 0, 0, 0, 16#ffff, AB, CD}) ->
ntoa(IP) ->
inet_parse:ntoa(IP).
+%% @doc Return true if the provided string is a restricted string:
+%% Start with a letter or a digit,
+%% remaining characters can be '-' or '_' in addition to letters and digits
+is_restricted_str(String) ->
+ RE = <<"^[A-Za-z0-9]+[A-Za-z0-9-_]*$">>,
+ match =:= re:run(String, RE, [{capture, none}]).
-ifdef(TEST).
-include_lib("eunit/include/eunit.hrl").