Skip to content

Commit

Permalink
Strip the base DN from eldap search results (fix #17)
Browse files Browse the repository at this point in the history
  • Loading branch information
minijackson committed Dec 20, 2017
1 parent 3bc5443 commit 86a4ecc
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 24 deletions.
18 changes: 10 additions & 8 deletions lib/paddle.ex
Original file line number Diff line number Diff line change
Expand Up @@ -202,20 +202,22 @@ defmodule Paddle do

@impl GenServer
def handle_call({:get, filter, kwdn, base}, _from, ldap_conn) do
dn = Parsing.construct_dn(kwdn, config(base))
base = config(base)
dn = Parsing.construct_dn(kwdn, base)
filter = Filters.construct_filter(filter)

Logger.debug("Getting entries with dn: #{dn} and filter: #{inspect filter, pretty: true}")

{:reply,
:eldap.search(ldap_conn, base: dn, filter: filter)
|> Parsing.clean_eldap_search_results,
|> Parsing.clean_eldap_search_results(base),
ldap_conn}
end

@impl GenServer
def handle_call({:get_single, filter, kwdn, base}, _from, ldap_conn) do
dn = Parsing.construct_dn(kwdn, config(base))
base = config(base)
dn = Parsing.construct_dn(kwdn, base)
filter = Filters.construct_filter(filter)

Logger.debug("Getting single entry with dn: #{dn} and filter: #{inspect filter, pretty: true}")
Expand All @@ -225,7 +227,7 @@ defmodule Paddle do
base: dn,
scope: :eldap.baseObject,
filter: filter)
|> Parsing.clean_eldap_search_results
|> Parsing.clean_eldap_search_results(base)
|> ensure_single_result,
ldap_conn}
end
Expand Down Expand Up @@ -339,7 +341,7 @@ defmodule Paddle do
iex> Paddle.get(base: [uid: "testuser", ou: "People"])
{:ok,
[%{"cn" => ["Test User"],
"dn" => "uid=testuser,ou=People,dc=test,dc=com",
"dn" => "uid=testuser,ou=People",
"gecos" => ["Test User,,,,"], "gidNumber" => ["120"],
"homeDirectory" => ["/home/testuser"],
"loginShell" => ["/bin/bash"],
Expand All @@ -350,7 +352,7 @@ defmodule Paddle do
iex> Paddle.get(base: "uid=testuser,ou=People")
{:ok,
[%{"cn" => ["Test User"],
"dn" => "uid=testuser,ou=People,dc=test,dc=com",
"dn" => "uid=testuser,ou=People",
"gecos" => ["Test User,,,,"], "gidNumber" => ["120"],
"homeDirectory" => ["/home/testuser"],
"loginShell" => ["/bin/bash"],
Expand All @@ -364,7 +366,7 @@ defmodule Paddle do
iex> Paddle.get(filter: [uid: "testuser"], base: [ou: "People"])
{:ok,
[%{"cn" => ["Test User"],
"dn" => "uid=testuser,ou=People,dc=test,dc=com",
"dn" => "uid=testuser,ou=People",
"gecos" => ["Test User,,,,"], "gidNumber" => ["120"],
"homeDirectory" => ["/home/testuser"],
"loginShell" => ["/bin/bash"],
Expand Down Expand Up @@ -454,7 +456,7 @@ defmodule Paddle do
iex> Paddle.get_single(base: [ou: "People"])
{:ok,
%{"dn" => "ou=People,dc=test,dc=com",
%{"dn" => "ou=People",
"objectClass" => ["top", "organizationalUnit"], "ou" => ["People"]}}
iex> Paddle.get_single(filter: [uid: "nothing"])
Expand Down
56 changes: 40 additions & 16 deletions lib/paddle/parsing.ex
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,8 @@ defmodule Paddle.Parsing do

@spec clean_eldap_search_results(
{:ok, {:eldap_search_result, [eldap_entry]}}
| {:error, atom}
| {:error, atom},
charlist
) :: {:ok, [Paddle.ldap_entry]} | {:error, Paddle.search_ldap_error}

@doc ~S"""
Expand All @@ -130,25 +131,29 @@ defmodule Paddle.Parsing do
Examples:
iex> eldap_entry = {:eldap_entry, 'uid=testuser,ou=People', [{'uid', ['testuser']}]}
iex> Paddle.Parsing.clean_eldap_search_results({:ok, {:eldap_search_result, [eldap_entry], []}})
iex> Paddle.Parsing.clean_eldap_search_results({:ok, {:eldap_search_result, [eldap_entry], []}}, '')
{:ok, [%{"dn" => "uid=testuser,ou=People", "uid" => ["testuser"]}]}
iex> Paddle.Parsing.clean_eldap_search_results({:ok, {:eldap_search_result, [], []}})
iex> Paddle.Parsing.clean_eldap_search_results({:ok, {:eldap_search_result, [], []}}, '')
{:error, :noSuchObject}
iex> Paddle.Parsing.clean_eldap_search_results({:error, :insufficientAccessRights})
iex> Paddle.Parsing.clean_eldap_search_results({:error, :insufficientAccessRights}, '')
{:error, :insufficientAccessRights}
iex> eldap_entry = {:eldap_entry, 'uid=testuser,ou=People', [{'uid', ['testuser']}]}
iex> Paddle.Parsing.clean_eldap_search_results({:ok, {:eldap_search_result, [eldap_entry], []}}, 'ou=People')
{:ok, [%{"dn" => "uid=testuser", "uid" => ["testuser"]}]}
"""
def clean_eldap_search_results({:error, error}) do
def clean_eldap_search_results({:error, error}, _base) do
{:error, error}
end

def clean_eldap_search_results({:ok, {:eldap_search_result, [], []}}) do
def clean_eldap_search_results({:ok, {:eldap_search_result, [], []}}, _base) do
{:error, :noSuchObject}
end

def clean_eldap_search_results({:ok, {:eldap_search_result, entries, []}}) do
{:ok, clean_entries(entries)}
def clean_eldap_search_results({:ok, {:eldap_search_result, entries, []}}, base) do
{:ok, clean_entries(entries, base)}
end

@spec entry_to_class_object(Paddle.ldap_entry, Paddle.Class.t) :: Paddle.Class.t
Expand All @@ -174,38 +179,57 @@ defmodule Paddle.Parsing do
Map.merge(target, entry)
end

@spec clean_entries([eldap_entry]) :: [Paddle.ldap_entry]
@spec clean_entries([eldap_entry], charlist) :: [Paddle.ldap_entry]

@doc ~S"""
Get a binary map representation of several eldap entries.
The `base` argument corresponds to the DN base which should be stripped from
the result's `"dn"` attribute.
Example:
iex> Paddle.Parsing.clean_entries([{:eldap_entry, 'uid=testuser,ou=People', [{'uid', ['testuser']}]}])
iex> Paddle.Parsing.clean_entries([{:eldap_entry, 'uid=testuser,ou=People', [{'uid', ['testuser']}]}], '')
[%{"dn" => "uid=testuser,ou=People", "uid" => ["testuser"]}]
iex> Paddle.Parsing.clean_entries([{:eldap_entry, 'uid=testuser,ou=People', [{'uid', ['testuser']}]}], 'ou=People')
[%{"dn" => "uid=testuser", "uid" => ["testuser"]}]
"""
def clean_entries(entries) do
def clean_entries(entries, base) do
base_length = length(base)
entries
|> Enum.map(&clean_entry/1)
|> Enum.map(&(clean_entry(&1, base_length)))
end

@spec clean_entry(eldap_entry) :: Paddle.ldap_entry
@spec clean_entry(eldap_entry, integer) :: Paddle.ldap_entry

@doc ~S"""
Get a binary map representation of a single eldap entry.
The `base_length` argument corresponds to the DN base length which should be
stripped from the result's `"dn"` attribute.
Example:
iex> Paddle.Parsing.clean_entry({:eldap_entry, 'uid=testuser,ou=People', [{'uid', ['testuser']}]})
iex> Paddle.Parsing.clean_entry({:eldap_entry, 'uid=testuser,ou=People', [{'uid', ['testuser']}]}, 0)
%{"dn" => "uid=testuser,ou=People", "uid" => ["testuser"]}
iex> Paddle.Parsing.clean_entry({:eldap_entry, 'uid=testuser,ou=People', [{'uid', ['testuser']}]}, 9)
%{"dn" => "uid=testuser", "uid" => ["testuser"]}
"""
def clean_entry({:eldap_entry, dn, attributes}) do
%{"dn" => List.to_string(dn)}
def clean_entry({:eldap_entry, dn, attributes}, base_length) do
%{"dn" => dn |> List.to_string |> strip_base_from_dn(base_length)}
|> Map.merge(attributes
|> attributes_to_binary
|> Enum.into(%{}))
end

defp strip_base_from_dn(dn, 0) when is_binary(dn), do: dn
defp strip_base_from_dn(dn, base_length) when is_binary(dn) do
dn_length = String.length(dn)
String.slice(dn, 0, dn_length - base_length - 1)
end

# ===================
# == Modifications ==
# ===================
Expand Down

0 comments on commit 86a4ecc

Please sign in to comment.