diff options
-rw-r--r-- | lib/eldap/doc/src/eldap.xml | 12 | ||||
-rw-r--r-- | lib/eldap/src/eldap.erl | 23 | ||||
-rw-r--r-- | lib/eldap/test/eldap_basic_SUITE.erl | 10 |
3 files changed, 43 insertions, 2 deletions
diff --git a/lib/eldap/doc/src/eldap.xml b/lib/eldap/doc/src/eldap.xml index dbd478fb17..4417551aa8 100644 --- a/lib/eldap/doc/src/eldap.xml +++ b/lib/eldap/doc/src/eldap.xml @@ -48,7 +48,7 @@ scope() See baseObject/0, singleLevel/0, wholeSubtree/0 dereference() See neverDerefAliases/0, derefInSearching/0, derefFindingBaseObj/0, derefAlways/0 filter() See present/1, substrings/2, equalityMatch/2, greaterOrEqual/2, lessOrEqual/2, - approxMatch/2, + approxMatch/2, extensibleMatch/2, 'and'/1, 'or'/1, 'not'/1. </pre> <p></p> @@ -348,6 +348,16 @@ filter() See present/1, substrings/2, <desc> <p>Create a approximation match filter.</p> </desc> </func> <func> + <name>extensibleMatch(MatchValue, OptionalAttrs) -> filter()</name> + <fsummary>Create search filter option.</fsummary> + <type> + <v>MatchValue = string()</v> + <v>OptionalAttrs = [Attr]</v> + <v>Attr = {matchingRule,string()} | {type,string()} | {dnAttributes,boolean()}</v> + </type> + <desc> <p>Creates an extensible match filter. For example, <c>eldap:extensibleMatch("Bar",[{type,"sn"},{matchingRule,"caseExactMatch"}]))</c> creates a filter which performs a <c>caseExactMatch</c> on the attribute <c>sn</c> and matches with the value <c>"Bar"</c>. The default value of <c>dnAttributes</c> is <c>false</c>.</p> </desc> + </func> + <func> <name>'and'([Filter]) -> filter()</name> <fsummary>Create search filter option.</fsummary> <type> diff --git a/lib/eldap/src/eldap.erl b/lib/eldap/src/eldap.erl index 416334e365..3fa440d37d 100644 --- a/lib/eldap/src/eldap.erl +++ b/lib/eldap/src/eldap.erl @@ -15,6 +15,7 @@ getopts/2, baseObject/0,singleLevel/0,wholeSubtree/0,close/1, equalityMatch/2,greaterOrEqual/2,lessOrEqual/2, + extensibleMatch/2, approxMatch/2,search/2,substrings/2,present/1, 'and'/1,'or'/1,'not'/1,modify/3, mod_add/2, mod_delete/2, mod_replace/2, add/3, delete/2, modify_dn/5,parse_dn/1, @@ -350,6 +351,27 @@ substrings(Type, SubStr) when is_list(Type), is_list(SubStr) -> {substrings,#'SubstringFilter'{type = Type, substrings = Ss}}. +%%% +%%% Filter for extensibleMatch +%%% +extensibleMatch(MatchValue, OptArgs) -> + MatchingRuleAssertion = + mra(OptArgs, #'MatchingRuleAssertion'{matchValue = MatchValue}), + {extensibleMatch, MatchingRuleAssertion}. + +mra([{matchingRule,Val}|T], Ack) when is_list(Val) -> + mra(T, Ack#'MatchingRuleAssertion'{matchingRule=Val}); +mra([{type,Val}|T], Ack) when is_list(Val) -> + mra(T, Ack#'MatchingRuleAssertion'{type=Val}); +mra([{dnAttributes,true}|T], Ack) -> + mra(T, Ack#'MatchingRuleAssertion'{dnAttributes="TRUE"}); +mra([{dnAttributes,false}|T], Ack) -> + mra(T, Ack#'MatchingRuleAssertion'{dnAttributes="FALSE"}); +mra([H|_], _) -> + throw({error,{extensibleMatch_arg,H}}); +mra([], Ack) -> + Ack. + %%% -------------------------------------------------------------------- %%% Worker process. We keep track of a controlling process to %%% be able to terminate together with it. @@ -862,6 +884,7 @@ v_filter({lessOrEqual,AV}) -> {lessOrEqual,AV}; v_filter({approxMatch,AV}) -> {approxMatch,AV}; v_filter({present,A}) -> {present,A}; v_filter({substrings,S}) when is_record(S,'SubstringFilter') -> {substrings,S}; +v_filter({extensibleMatch,S}) when is_record(S,'MatchingRuleAssertion') -> {extensibleMatch,S}; v_filter(_Filter) -> throw({error,concat(["unknown filter: ",_Filter])}). v_modifications(Mods) -> diff --git a/lib/eldap/test/eldap_basic_SUITE.erl b/lib/eldap/test/eldap_basic_SUITE.erl index 6c3d303da0..d87f3ac4ac 100644 --- a/lib/eldap/test/eldap_basic_SUITE.erl +++ b/lib/eldap/test/eldap_basic_SUITE.erl @@ -106,7 +106,9 @@ api(doc) -> "Basic test that all api functions works as expected"; api(suite) -> []; api(Config) -> {Host,Port} = proplists:get_value(ldap_server, Config), - {ok, H} = eldap:open([Host], [{port,Port}]), + {ok, H} = eldap:open([Host], [{port,Port} + ,{log,fun(Lvl,Fmt,Args)-> io:format("~p: ~s",[Lvl,io_lib:format(Fmt,Args)]) end} + ]), %% {ok, H} = eldap:open([Host], [{port,Port+1}, {ssl, true}]), do_api_checks(H, Config), eldap:close(H), @@ -232,6 +234,12 @@ chk_search(H, BasePath) -> {ok, #eldap_search_result{entries=[#eldap_entry{}]}} = Search(F_AND), F_NOT = eldap:'and'([eldap:present("objectclass"), eldap:'not'(eldap:present("ou"))]), {ok, #eldap_search_result{entries=[#eldap_entry{}, #eldap_entry{}]}} = Search(F_NOT), + {ok, #eldap_search_result{entries=[#eldap_entry{}]}} = Search(eldap:extensibleMatch("Bar",[{type,"sn"},{matchingRule,"caseExactMatch"}])), + {ok, #eldap_search_result{entries=[#eldap_entry{}]}} = Search(eldap:extensibleMatch("Bar",[{type,"sn"},{matchingRule,"2.5.13.5"}])), + {ok, #eldap_search_result{entries=[#eldap_entry{}]}} = Search(eldap:extensibleMatch("Bar",[{type,"sn"},{matchingRule,"caseIgnoreMatch"}])), + {ok, #eldap_search_result{entries=[#eldap_entry{}]}} = Search(eldap:extensibleMatch("bar",[{type,"sn"},{matchingRule,"caseIgnoreMatch"}])), + {ok, #eldap_search_result{entries=[]}} = Search(eldap:extensibleMatch("bar",[{type,"sn"},{matchingRule,"gluffgluff"}])), + {ok, #eldap_search_result{entries=[]}} = Search(eldap:extensibleMatch("bar",[{type,"sn"},{matchingRule,"caseExactMatch"}])), {ok,FB}. %% FIXME chk_modify(H, FB) -> |