Merge pull request #9871 from lafirest/fix/authz_rules
feat(authz): allow the placeholder to be anywhere in the topic for authz rules
This commit is contained in:
commit
3d59be6ab6
|
@ -1,7 +1,7 @@
|
|||
%% -*- mode: erlang -*-
|
||||
{application, emqx_authz, [
|
||||
{description, "An OTP application"},
|
||||
{vsn, "0.1.12"},
|
||||
{vsn, "0.1.13"},
|
||||
{registered, []},
|
||||
{mod, {emqx_authz_app, []}},
|
||||
{applications, [
|
||||
|
|
|
@ -100,15 +100,17 @@ compile_topic(<<"eq ", Topic/binary>>) ->
|
|||
compile_topic({eq, Topic}) ->
|
||||
{eq, emqx_topic:words(bin(Topic))};
|
||||
compile_topic(Topic) ->
|
||||
Words = emqx_topic:words(bin(Topic)),
|
||||
case pattern(Words) of
|
||||
true -> {pattern, Words};
|
||||
false -> Words
|
||||
TopicBin = bin(Topic),
|
||||
case
|
||||
emqx_placeholder:preproc_tmpl(
|
||||
TopicBin,
|
||||
#{placeholders => [?PH_USERNAME, ?PH_CLIENTID]}
|
||||
)
|
||||
of
|
||||
[{str, _}] -> emqx_topic:words(TopicBin);
|
||||
Tokens -> {pattern, Tokens}
|
||||
end.
|
||||
|
||||
pattern(Words) ->
|
||||
lists:member(?PH_USERNAME, Words) orelse lists:member(?PH_CLIENTID, Words).
|
||||
|
||||
atom(B) when is_binary(B) ->
|
||||
try
|
||||
binary_to_existing_atom(B, utf8)
|
||||
|
@ -202,8 +204,8 @@ match_who(_, _) ->
|
|||
match_topics(_ClientInfo, _Topic, []) ->
|
||||
false;
|
||||
match_topics(ClientInfo, Topic, [{pattern, PatternFilter} | Filters]) ->
|
||||
TopicFilter = feed_var(ClientInfo, PatternFilter),
|
||||
match_topic(emqx_topic:words(Topic), TopicFilter) orelse
|
||||
TopicFilter = emqx_placeholder:proc_tmpl(PatternFilter, ClientInfo),
|
||||
match_topic(emqx_topic:words(Topic), emqx_topic:words(TopicFilter)) orelse
|
||||
match_topics(ClientInfo, Topic, Filters);
|
||||
match_topics(ClientInfo, Topic, [TopicFilter | Filters]) ->
|
||||
match_topic(emqx_topic:words(Topic), TopicFilter) orelse
|
||||
|
@ -213,18 +215,3 @@ match_topic(Topic, {'eq', TopicFilter}) ->
|
|||
Topic =:= TopicFilter;
|
||||
match_topic(Topic, TopicFilter) ->
|
||||
emqx_topic:match(Topic, TopicFilter).
|
||||
|
||||
feed_var(ClientInfo, Pattern) ->
|
||||
feed_var(ClientInfo, Pattern, []).
|
||||
feed_var(_ClientInfo, [], Acc) ->
|
||||
lists:reverse(Acc);
|
||||
feed_var(ClientInfo = #{clientid := undefined}, [?PH_CLIENTID | Words], Acc) ->
|
||||
feed_var(ClientInfo, Words, [?PH_CLIENTID | Acc]);
|
||||
feed_var(ClientInfo = #{clientid := ClientId}, [?PH_CLIENTID | Words], Acc) ->
|
||||
feed_var(ClientInfo, Words, [ClientId | Acc]);
|
||||
feed_var(ClientInfo = #{username := undefined}, [?PH_USERNAME | Words], Acc) ->
|
||||
feed_var(ClientInfo, Words, [?PH_USERNAME | Acc]);
|
||||
feed_var(ClientInfo = #{username := Username}, [?PH_USERNAME | Words], Acc) ->
|
||||
feed_var(ClientInfo, Words, [Username | Acc]);
|
||||
feed_var(ClientInfo, [W | Words], Acc) ->
|
||||
feed_var(ClientInfo, Words, [W | Acc]).
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
]},
|
||||
publish, [?PH_S_USERNAME, ?PH_S_CLIENTID]}
|
||||
).
|
||||
-define(SOURCE6, {allow, {username, "test"}, publish, ["t/foo${username}boo"]}).
|
||||
|
||||
all() ->
|
||||
emqx_common_test_helpers:all(?MODULE).
|
||||
|
@ -80,7 +81,7 @@ t_compile(_) ->
|
|||
{{127, 0, 0, 1}, {127, 0, 0, 1}, 32},
|
||||
{{192, 168, 1, 0}, {192, 168, 1, 255}, 24}
|
||||
]},
|
||||
subscribe, [{pattern, [?PH_CLIENTID]}]},
|
||||
subscribe, [{pattern, [{var, {var, <<"clientid">>}}]}]},
|
||||
emqx_authz_rule:compile(?SOURCE3)
|
||||
),
|
||||
|
||||
|
@ -97,9 +98,18 @@ t_compile(_) ->
|
|||
{username, {re_pattern, _, _, _, _}},
|
||||
{clientid, {re_pattern, _, _, _, _}}
|
||||
]},
|
||||
publish, [{pattern, [?PH_USERNAME]}, {pattern, [?PH_CLIENTID]}]},
|
||||
publish, [
|
||||
{pattern, [{var, {var, <<"username">>}}]}, {pattern, [{var, {var, <<"clientid">>}}]}
|
||||
]},
|
||||
emqx_authz_rule:compile(?SOURCE5)
|
||||
),
|
||||
|
||||
?assertEqual(
|
||||
{allow, {username, {eq, <<"test">>}}, publish, [
|
||||
{pattern, [{str, <<"t/foo">>}, {var, {var, <<"username">>}}, {str, <<"boo">>}]}
|
||||
]},
|
||||
emqx_authz_rule:compile(?SOURCE6)
|
||||
),
|
||||
ok.
|
||||
|
||||
t_match(_) ->
|
||||
|
@ -307,4 +317,24 @@ t_match(_) ->
|
|||
emqx_authz_rule:compile(?SOURCE5)
|
||||
)
|
||||
),
|
||||
|
||||
?assertEqual(
|
||||
nomatch,
|
||||
emqx_authz_rule:match(
|
||||
ClientInfo1,
|
||||
publish,
|
||||
<<"t/foo${username}boo">>,
|
||||
emqx_authz_rule:compile(?SOURCE6)
|
||||
)
|
||||
),
|
||||
|
||||
?assertEqual(
|
||||
{matched, allow},
|
||||
emqx_authz_rule:match(
|
||||
ClientInfo4,
|
||||
publish,
|
||||
<<"t/footestboo">>,
|
||||
emqx_authz_rule:compile(?SOURCE6)
|
||||
)
|
||||
),
|
||||
ok.
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
Allow the placeholder to be anywhere in the topic for `authz` rules.
|
||||
e.g:
|
||||
`{allow, {username, "who"}, publish, ["t/foo${username}boo/${clientid}xxx"]}.`
|
|
@ -0,0 +1,3 @@
|
|||
允许占位符出现在 `authz` 规则中的主题里的任意位置。
|
||||
例如:
|
||||
`{allow, {username, "who"}, publish, ["t/foo${username}boo/${clientid}xxx"]}.`
|
Loading…
Reference in New Issue