Skip to content

Commit

Permalink
Fix encoding issues (fix #18) + add tests for unicode LDAP data
Browse files Browse the repository at this point in the history
  • Loading branch information
minijackson committed Jan 7, 2018
1 parent 86a4ecc commit efaba26
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 16 deletions.
7 changes: 7 additions & 0 deletions .travis/ldap/test_data.ldif
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,10 @@ objectClass: room
commonName: meetingRoom
roomNumber: 42
description: The Room where meetings happens

dn: commonName=ùnícödəR°°m,ou=Rooms,dc=test,dc=com
objectClass: top
objectClass: room
commonName: ùnícödəR°°m
roomNumber: 8
description: The Room where ùnícödə happens 🏰
16 changes: 12 additions & 4 deletions lib/paddle.ex
Original file line number Diff line number Diff line change
Expand Up @@ -291,12 +291,12 @@ defmodule Paddle do
"""
def authenticate(kwdn, password) when is_list(kwdn) do
dn = Parsing.construct_dn(kwdn, config(:base))
GenServer.call(Paddle, {:authenticate, dn, String.to_charlist(password)})
GenServer.call(Paddle, {:authenticate, dn, :binary.bin_to_list(password)})
end

def authenticate(username, password) do
dn = Parsing.construct_dn([{config(:account_identifier), username}], config(:account_base))
GenServer.call(Paddle, {:authenticate, dn, String.to_charlist(password)})
GenServer.call(Paddle, {:authenticate, dn, :binary.bin_to_list(password)})
end

@spec get_dn(Paddle.Class.t) :: {:ok, binary} | {:error, :missing_unique_identifier}
Expand Down Expand Up @@ -589,6 +589,14 @@ defmodule Paddle do
add: {"description", "This is a description"},
delete: "gecos",
replace: {"o", ["Club *Nix", "Linux Foundation"]})
Or, using class objects:
Paddle.modify(%MyApp.PosixAccount{uid: "testuser"},
add: {"description", "This is a description"},
delete: "gecos",
replace: {"o", ["Club *Nix", "Linux Foundation"]})
"""
def modify(kwdn, mods) when is_list(kwdn) or is_binary(kwdn) do
GenServer.call(Paddle, {:modify, kwdn, :base, mods})
Expand Down Expand Up @@ -629,9 +637,9 @@ defmodule Paddle do
def config(:sslopts), do: config(:sslopts, [])
def config(:port), do: config(:port, 389)
def config(:timeout), do: config(:timeout, nil)
def config(:base), do: config(:base, "") |> String.to_charlist
def config(:base), do: config(:base, "") |> :binary.bin_to_list
def config(:account_base), do: config(:account_subdn) ++ ',' ++ config(:base)
def config(:account_subdn), do: config(:account_subdn, "ou=People") |> String.to_charlist
def config(:account_subdn), do: config(:account_subdn, "ou=People") |> :binary.bin_to_list
def config(:account_identifier), do: config(:account_identifier, :uid)
def config(:schema_files), do: config(:schema_files, [])

Expand Down
23 changes: 12 additions & 11 deletions lib/paddle/parsing.ex
Original file line number Diff line number Diff line change
Expand Up @@ -30,31 +30,32 @@ defmodule Paddle.Parsing do
reordered and because they can be mistaken for a class object (see
`Paddle.Class`).
"""
def construct_dn(subdn, base) when is_binary(base) do
construct_dn(subdn, :binary.bin_to_list(base))
end

def construct_dn(map, base \\ '')

def construct_dn([], base) when is_list(base), do: base
def construct_dn([], base), do: String.to_charlist(base)

def construct_dn(subdn, base) when is_binary(subdn) and is_list(base), do:
String.to_charlist(subdn) ++ ',' ++ base
def construct_dn(subdn, base) when is_binary(subdn), do:
String.to_charlist(subdn) ++ ',' ++ String.to_charlist(base)
:binary.bin_to_list(subdn) ++ ',' ++ base

def construct_dn(nil, base) when is_list(base), do: base
def construct_dn(nil, base), do: String.to_charlist(base)

def construct_dn(map, '') do
',' ++ dn = map
|> Enum.reduce('', fn {key, value}, acc -> acc ++ ',#{key}=#{ldap_escape value}' end)
',' ++ dn = Enum.reduce(map,
'',
fn {key, value}, acc ->
acc ++ ',#{key}=#{ldap_escape value}'
end)
dn
end

def construct_dn(map, base) when is_list(base) do
construct_dn(map, '') ++ ',' ++ base
end

def construct_dn(map, base), do: construct_dn(map, String.to_charlist(base))

@spec dn_to_kwlist(charlist | binary) :: [{binary, binary}]

@doc ~S"""
Expand Down Expand Up @@ -108,7 +109,7 @@ defmodule Paddle.Parsing do
escaped_char ++ ldap_escape(rest)
end

def ldap_escape(token), do: ldap_escape(String.to_charlist(token))
def ldap_escape(token), do: ldap_escape(:binary.bin_to_list(token))

# =============
# == Entries ==
Expand Down Expand Up @@ -308,7 +309,7 @@ defmodule Paddle.Parsing do

defp attribute_to_binary({key, values}) do
{List.to_string(key),
values |> Enum.map(&List.to_string/1)}
values |> Enum.map(&:binary.list_to_bin/1)}
end

end
4 changes: 4 additions & 0 deletions test/obsolete.schema
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
objectclass ( 1.3.6.1.4.1.1466.344 NAME 'dcObject'
DESC 'RFC2247: domain component object'
OBSOLETE
SUP top AUXILIARY MUST dc )
3 changes: 2 additions & 1 deletion test/paddle_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ defmodule PaddleTest do
doctest Paddle

test "class generator helper macro" do
assert Paddle.get!(%MyApp.Room{}) == [%MyApp.Room{cn: ["meetingRoom"], description: ["The Room where meetings happens"], roomNumber: ["42"]}]
assert Paddle.get!(%MyApp.Room{}) == [%MyApp.Room{cn: ["ùnícödəR°°m"], description: ["The Room where ùnícödə happens 🏰"], roomNumber: ["8"]},
%MyApp.Room{cn: ["meetingRoom"], description: ["The Room where meetings happens"], roomNumber: ["42"]}]
assert Paddle.get!(%MyApp.Room{cn: "meetingRoom"}) == [%MyApp.Room{cn: ["meetingRoom"], description: ["The Room where meetings happens"], roomNumber: ["42"]}]
assert Paddle.get!(%MyApp.Room{roomNumber: 42}) == [%MyApp.Room{cn: ["meetingRoom"], description: ["The Room where meetings happens"], roomNumber: ["42"]}]
end
Expand Down

0 comments on commit efaba26

Please sign in to comment.