Merge pull request #6639 from HJianBo/fix-client-fuzzy-matching
fix(mgmt): fix substring matching alg
This commit is contained in:
commit
be12e179f5
|
@ -297,10 +297,12 @@ to_integer(I) when is_integer(I) ->
|
|||
to_integer(B) when is_binary(B) ->
|
||||
binary_to_integer(B).
|
||||
|
||||
%% @doc The input timestamp time is in seconds, which needs to be
|
||||
%% converted to internal milliseconds here
|
||||
to_timestamp(I) when is_integer(I) ->
|
||||
I;
|
||||
I * 1000;
|
||||
to_timestamp(B) when is_binary(B) ->
|
||||
binary_to_integer(B).
|
||||
binary_to_integer(B) * 1000.
|
||||
|
||||
aton(B) when is_binary(B) ->
|
||||
list_to_tuple([binary_to_integer(T) || T <- re:split(B, "[.]")]).
|
||||
|
@ -332,7 +334,7 @@ params2qs_test() ->
|
|||
ExpectedQs = [{str, '=:=', <<"abc">>},
|
||||
{int, '=:=', 123},
|
||||
{atom, '=:=', connected},
|
||||
{ts, '=:=', 156000},
|
||||
{ts, '=:=', 156000000},
|
||||
{range, '>=', 1, '=<', 5}
|
||||
],
|
||||
FuzzyQs = [{fuzzy, like, <<"user">>},
|
||||
|
|
|
@ -333,31 +333,24 @@ query({Qs, Fuzzy}, Start, Limit) ->
|
|||
|
||||
match_fun(Ms, Fuzzy) ->
|
||||
MsC = ets:match_spec_compile(Ms),
|
||||
REFuzzy = lists:map(fun({K, like, S}) ->
|
||||
{ok, RE} = re:compile(escape(S)),
|
||||
{K, like, RE}
|
||||
end, Fuzzy),
|
||||
fun(Rows) ->
|
||||
case ets:match_spec_run(Rows, MsC) of
|
||||
[] -> [];
|
||||
Ls ->
|
||||
lists:filter(fun(E) ->
|
||||
run_fuzzy_match(E, REFuzzy)
|
||||
run_fuzzy_match(E, Fuzzy)
|
||||
end, Ls)
|
||||
end
|
||||
end.
|
||||
|
||||
escape(B) when is_binary(B) ->
|
||||
re:replace(B, <<"\\\\">>, <<"\\\\\\\\">>, [{return, binary}, global]).
|
||||
|
||||
run_fuzzy_match(_, []) ->
|
||||
true;
|
||||
run_fuzzy_match(E = {_, #{clientinfo := ClientInfo}, _}, [{Key, _, RE}|Fuzzy]) ->
|
||||
Val = case maps:get(Key, ClientInfo, "") of
|
||||
undefined -> "";
|
||||
run_fuzzy_match(E = {_, #{clientinfo := ClientInfo}, _}, [{Key, like, SubStr}|Fuzzy]) ->
|
||||
Val = case maps:get(Key, ClientInfo, undefined) of
|
||||
undefined -> <<>>;
|
||||
V -> V
|
||||
end,
|
||||
re:run(Val, RE, [{capture, none}]) == match andalso run_fuzzy_match(E, Fuzzy).
|
||||
binary:match(Val, SubStr) /= nomatch andalso run_fuzzy_match(E, Fuzzy).
|
||||
|
||||
%%--------------------------------------------------------------------
|
||||
%% QueryString to Match Spec
|
||||
|
@ -442,10 +435,10 @@ params2qs_test() ->
|
|||
proto_ver => 4,
|
||||
connected_at => '$3'},
|
||||
session => #{created_at => '$2'}},
|
||||
ExpectedCondi = [{'>=','$2', 1},
|
||||
{'=<','$2', 5},
|
||||
{'>=','$3', 1},
|
||||
{'=<','$3', 5}],
|
||||
ExpectedCondi = [{'>=','$2', 1000},
|
||||
{'=<','$2', 5000},
|
||||
{'>=','$3', 1000},
|
||||
{'=<','$3', 5000}],
|
||||
{10, {Qs1, []}} = emqx_mgmt_api:params2qs(Params, QsSchema),
|
||||
[{{'$1', MtchHead, _}, Condi, _}] = qs2ms(Qs1),
|
||||
?assertEqual(ExpectedMtchHead, MtchHead),
|
||||
|
@ -453,9 +446,24 @@ params2qs_test() ->
|
|||
|
||||
[{{'$1', #{}, '_'}, [], ['$_']}] = qs2ms([]).
|
||||
|
||||
escape_test() ->
|
||||
Str = <<"\\n">>,
|
||||
{ok, Re} = re:compile(escape(Str)),
|
||||
{match, _} = re:run(<<"\\name">>, Re).
|
||||
fuzzy_match_test() ->
|
||||
Info = {emqx_channel_info,
|
||||
#{clientinfo =>
|
||||
#{ clientid => <<"abcde">>
|
||||
, username => <<"abc\\name*[]()">>
|
||||
}}, []
|
||||
},
|
||||
true = run_fuzzy_match(Info, [{clientid, like, <<"abcde">>}]),
|
||||
true = run_fuzzy_match(Info, [{clientid, like, <<"bcd">>}]),
|
||||
false = run_fuzzy_match(Info, [{clientid, like, <<"defh">>}]),
|
||||
|
||||
true = run_fuzzy_match(Info, [{username, like, <<"\\name">>}]),
|
||||
true = run_fuzzy_match(Info, [{username, like, <<"*">>}]),
|
||||
true = run_fuzzy_match(Info, [{username, like, <<"[]">>}]),
|
||||
true = run_fuzzy_match(Info, [{username, like, <<"()">>}]),
|
||||
false = run_fuzzy_match(Info, [{username, like, <<"))">>}]),
|
||||
|
||||
true = run_fuzzy_match(Info, [{clientid, like, <<"de">>},
|
||||
{username, like, <<"[]">>}]).
|
||||
|
||||
-endif.
|
||||
|
|
Loading…
Reference in New Issue