diff --git a/apps/emqx_ldap/.gitignore b/apps/emqx_ldap/.gitignore new file mode 100644 index 000000000..b912731cf --- /dev/null +++ b/apps/emqx_ldap/.gitignore @@ -0,0 +1,2 @@ +src/emqx_ldap_filter_lexer.erl +src/emqx_ldap_filter_parser.erl \ No newline at end of file diff --git a/apps/emqx_ldap/src/emqx_ldap.erl b/apps/emqx_ldap/src/emqx_ldap.erl index 4b43bb6f6..390c34501 100644 --- a/apps/emqx_ldap/src/emqx_ldap.erl +++ b/apps/emqx_ldap/src/emqx_ldap.erl @@ -167,14 +167,22 @@ on_query( [] -> do_ldap_query(InstId, [{base, Base} | SearchOptions], State); _ -> - FilterBin = emqx_placeholder:proc_tmpl(FilterTks, Data), - %% TODO - Filter = FilterBin, - do_ldap_query( - InstId, - [{base, Base}, {filter, Filter} | SearchOptions], - State - ) + FilterBin = emqx_placeholder:proc_tmpl(FilterTks, Data, #{return => rawlist}), + case emqx_ldap_filter_parser:scan_and_parse(FilterBin) of + {ok, Filter} -> + do_ldap_query( + InstId, + [{base, Base}, {filter, Filter} | SearchOptions], + State + ); + {error, Reason} = Error -> + ?SLOG(error, #{ + msg => "filter_parse_failed", + filter => FilterBin, + reason => Reason + }), + Error + end end. do_ldap_query( diff --git a/apps/emqx_ldap/src/emqx_ldap_filter_lexer.xrl b/apps/emqx_ldap/src/emqx_ldap_filter_lexer.xrl index ae5c0cdbf..e30531e2a 100644 --- a/apps/emqx_ldap/src/emqx_ldap_filter_lexer.xrl +++ b/apps/emqx_ldap/src/emqx_ldap_filter_lexer.xrl @@ -1,5 +1,6 @@ Definitions. +Control = [()&|!=~><:*] NonControl = [^()&|!=~><:*] String = {NonControl}* White = [\s\t\n\r]+ @@ -20,5 +21,7 @@ Rules. dn : {token, {dn, TokenLine}}. {White} : skip_token. {String} : {token, {string, TokenLine, TokenChars}}. +%% Leex will hang if a composite operation is missing a character +{Control} : {error, lists:flatten(io_lib:format("Unexpected Tokens:~ts", [TokenChars]))}. Erlang code. diff --git a/apps/emqx_ldap/src/emqx_ldap_filter_parser.yrl b/apps/emqx_ldap/src/emqx_ldap_filter_parser.yrl index 2e9cf193d..266d126c1 100644 --- a/apps/emqx_ldap/src/emqx_ldap_filter_parser.yrl +++ b/apps/emqx_ldap/src/emqx_ldap_filter_parser.yrl @@ -94,6 +94,8 @@ matchingrule -> colon value: {matchingRule, '$2'}. Erlang code. +-export([scan_and_parse/1]). +-ignore_xref({return_error, 2}). 'and'(Value) -> eldap:'and'(Value). @@ -131,3 +133,13 @@ flatten(List) -> lists:flatten(List). get_value({_Token, _Line, Value}) -> Value. + +scan_and_parse(Bin) when is_binary(Bin) -> + scan_and_parse(erlang:binary_to_list(Bin)); +scan_and_parse(String) -> + case emqx_ldap_filter_lexer:string(String) of + {ok, Tokens, _} -> + parse(Tokens); + {error, Reason, _} -> + {error, Reason} + end.