From a181de36ddf4815e81c3c50dd0571932ad4cb657 Mon Sep 17 00:00:00 2001 From: 5HT Date: Sat, 22 Jul 2023 14:10:29 +0300 Subject: [PATCH] search query builder --- lib/ldap.ex | 45 +++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/lib/ldap.ex b/lib/ldap.ex index 95fad0e..3443361 100644 --- a/lib/ldap.ex +++ b/lib/ldap.ex @@ -16,26 +16,25 @@ defmodule LDAP.TCP do def collect(db,st,:done, acc), do: acc def collect(db,st,{:row,x}, acc), do: collect(db,st,step(db,st),[:erlang.list_to_tuple(x)|acc]) -#09:12:30.882 [info] SEARCH Filter: {:and, -# [ -# or: [ -# equalityMatch: {:AttributeValueAssertion, "objectClass", "top"}, -# substrings: {:SubstringFilter, "cn", [final: "a"]}, -# present: "objectClass" -# ], -# substrings: {:SubstringFilter, "objectClass", [any: "a"]} -# ]} - - def query(name) do - {:ok, db} = open(name) - {:ok, st} = prepare(db, "select * from ldap where rdn in (select rdn from ldap where " <> - " (att = 'objectClass' and val like '%a%') " <> - " and " <> - " ((att = 'objectClass') or " <> - "(att = 'cn' and val like '%a%') or" <> - "(att = 'objectClass' and val='top')))" ) - res = step(db,st) - collect(db,st,res,[]) + def query(q), do: + "select * from ldap where rdn in (select rdn from ldap where " <> match(q) <> ")" + + def join(list, op), do: + :string.join(:lists.map(fn x -> :erlang.binary_to_list("(" <> match(x) <> ")") end, list), op) + |> :erlang.iolist_to_binary + + def match({:equalityMatch, {_, a, v}}), do: "(att = '#{a}' and val = '#{v}')" + def match({:substrings, {_, a, [final: v]}}), do: "(att = '#{a}' and val like '#{v}%')" + def match({:substrings, {_, a, [initial: v]}}), do: "(att = '#{a}' and val like '%#{v}')" + def match({:substrings, {_, a, [any: v]}}), do: "(att = '#{a}' and val like '%#{v}%')" + def match({:present, a}), do: "(att = '#{a}')" + def match({:and, list}), do: "(" <> join(list, 'and') <> ")" + def match({:or, list}), do: "(" <> join(list, 'or') <> ")" + def match({:not, x}), do: "(not(" <> match(x) <> "))" + + def select(db, filter) do + {:ok, st} = prepare(db, query(filter)) + collect(db,st,step(db,st),[]) end def list(name) do @@ -131,10 +130,12 @@ defmodule LDAP.TCP do bindDN = "dc=synrc,dc=com" :logger.info 'SEARCH DN: ~p', [bindDN] :logger.info 'SEARCH Scope: ~p', [scope] - :logger.info 'SEARCH Filter: ~p', [filter] + :logger.info 'SEARCH Filter Raw: ~p', [filter] + :logger.info 'SEARCH Filter Parsed: ~p', [query(filter)] + :logger.info 'SEARCH Filter Executed: ~p', [select(db, filter)] :logger.info 'SEARCH Attr: ~p', [attributes] - synrc = + synrc = [node("dc=synrc,dc=com", [ attr("dc",["synrc"]), attr("objectClass",['domain','top'])])