GithubHelp home page GithubHelp logo

minijackson / paddle Goto Github PK

View Code? Open in Web Editor NEW
53.0 6.0 13.0 129 KB

A library simplifying LDAP usage in Elixir projects

License: MIT License

Elixir 85.43% Erlang 12.99% Nix 1.58%
elixir ldap ldap-library ldap-authentication

paddle's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

paddle's Issues

no function clause matching errors

I seem to be getting a lot of errors such as

phonedb-57c69655fc-mfdj8 phonedb 02:40:08.704 [info] Stopped LDAP
phonedb-57c69655fc-mfdj8 phonedb 02:40:08.705 [error] GenServer Paddle terminating
phonedb-57c69655fc-mfdj8 phonedb ** (FunctionClauseError) no function clause matching in Paddle.Parsing.clean_eldap_search_results/2
phonedb-57c69655fc-mfdj8 phonedb     (paddle 0.1.4) lib/paddle/parsing.ex:148: Paddle.Parsing.clean_eldap_search_results({:ok, {:eldap_search
_result, [], [], :asn1_NOVALUE}}, 'dc=pri')
phonedb-57c69655fc-mfdj8 phonedb     (paddle 0.1.4) lib/paddle.ex:204: Paddle.handle_call/3
phonedb-57c69655fc-mfdj8 phonedb     (stdlib 3.17.1) gen_server.erl:721: :gen_server.try_handle_call/4
phonedb-57c69655fc-mfdj8 phonedb     (stdlib 3.17.1) gen_server.erl:750: :gen_server.handle_msg/6
phonedb-57c69655fc-mfdj8 phonedb     (stdlib 3.17.1) proc_lib.erl:226: :proc_lib.init_p_do_apply/3
phonedb-57c69655fc-mfdj8 phonedb Last message (from #PID<0.9786.10>): {:get, {:and, [equalityMatch: {:AttributeValueAssertion, 'telephoneNumb
er', '0438539906'}, equalityMatch: {:AttributeValueAssertion, 'objectClass', 'person'}]}, "ou=people", :base}
phonedb-57c69655fc-mfdj8 phonedb 02:40:08.708 [info] Connecting to ldap://['ldap.pri']:389
phonedb-57c69655fc-mfdj8 phonedb 02:40:08.709 [error] #PID<0.9786.10> running PhoneDbWeb.Endpoint (connection #PID<0.9787.10>, stream id 1) t
erminated
phonedb-57c69655fc-mfdj8 phonedb Server: phonedb.linuxpenguins.xyz:80 (http)
phonedb-57c69655fc-mfdj8 phonedb Request: POST /api/incoming_call/
phonedb-57c69655fc-mfdj8 phonedb ** (exit) exited in: GenServer.call(Paddle, {:get, {:and, [equalityMatch: {:AttributeValueAssertion, 'telephoneNumber', '0438539906'}, equalityMatch: {:AttributeValueAssertion, 'objectClass', 'person'}]}, "ou=people", :base}, 5000)
phonedb-57c69655fc-mfdj8 phonedb     ** (EXIT) an exception was raised:
phonedb-57c69655fc-mfdj8 phonedb         ** (FunctionClauseError) no function clause matching in Paddle.Parsing.clean_eldap_search_results/2
phonedb-57c69655fc-mfdj8 phonedb             (paddle 0.1.4) lib/paddle/parsing.ex:148: Paddle.Parsing.clean_eldap_search_results({:ok, {:eldap_search_result, [], [], :asn1_NOVALUE}}, 'dc=pri')
phonedb-57c69655fc-mfdj8 phonedb             (paddle 0.1.4) lib/paddle.ex:204: Paddle.handle_call/3
phonedb-57c69655fc-mfdj8 phonedb             (stdlib 3.17.1) gen_server.erl:721: :gen_server.try_handle_call/4
phonedb-57c69655fc-mfdj8 phonedb             (stdlib 3.17.1) gen_server.erl:750: :gen_server.handle_msg/6
phonedb-57c69655fc-mfdj8 phonedb             (stdlib 3.17.1) proc_lib.erl:226: :proc_lib.init_p_do_apply/3

I think this might be on a get request:

case Paddle.get(%PhoneDb.Contacts.Ldap.Person{telephoneNumber: contact.phone_number}, nil) do

Where I expect it to return {:error, :noSuchObject} in this case.

Unfortunately this is not an error I can reproduce on demand. Just searching for a non-existent object produces the excepted results.

Feature: Paddle.authenticate() with optional post auth filter

It would be highly useful to include an LDAP filter along with the authenticate, even though the authenticate constructs a full DN. The handiness of this is in being able to do an authenticate+ authorize all in one step, ala:

Paddle.authenticate([cn: username], password, filter:[memberOf: "cn=SpecialGroup,ou=..."])

Ability to configure SSL certificates for LDAPS

In testing this my connection is failing, but I can connect with ldapsearch to my ldapserver. However, ldapsearch does report that it doesn't like the certificate because the root CA is untrusted. My speculation is that this might be happening under the hood, and it is just bubbling up to the top as a connection failure?

Application exits when LDAP is not reachable

Hello!

Here's my scenario:

I have built an umbrella project with 2 applications: LdapInterface, which does some LDAP user management, and a Slack bot which passes user commands to the other app.

Sometimes our LDAP will be unavailable due to external factors, say, VPN hiccups, and connecting to LDAP would fail preventing the app from starting. When this happens, my Slack bot doesn't connect as well.

Instead, I wanted to give feedback on Slack when the LDAP connection is not available.

This may not be the best approach and I may be missing something, but here's what I did:
Forked the repo and let the app start without holding a connection to LDAP, and when a message arrives it returns {:error, :not_connected} so I can gracefully handle it, send a message on Slack and try a reconnection.

Those are the changes: shamanime@7efb4a0

This solves my issue. Is there a better approach to achieve this result? Do you think this would be valuable for anyone else? Would you be interested in a PR?

Thank you for your work on this project!

password change?

I have a need to allow my users to change their password. Is this possible with Paddle? I don't see any mention of it in the docs.

authenticate assumes all users in one ou, always uses uid attribute

In our ldap, we have a whole tree of different organizations - for example, my dn looks something like this:
cn=andymc,ou=myOrg,ou=New York,ou=US,o=myCo

and other users might be in other countries or states, etc...
It would be great if authenticate could accept a form of username that was just the whole DN, and didn't mess with it at all. If I have time I'll implement it, but not sure how you'd like it done.

Paddle enlève la possibilité de passer une liste d'hôtes à eldap.

La signature de eldap:open est open([Host], [Option]) -> {ok, Handle} | {error, Reason}, et pourtant dans la configuration de Paddle, il ne semble être prévu qu'un seul hôte soit supporté, ainsi que dans paddle.ex où l'hôte (unique, donc) est mis dans une liste.
C'est relativement dommage si on a une réplique du LDAP et que le primaire tombe.

(PS: j'espère que tu t'amuses au Canada ❤️)

Uncaught exception

phoenix_1 | 22:34:50.538 level=error GenServer Paddle terminating
phoenix_1 | ** (CaseClauseError) no case clause matching: :other
phoenix_1 | (paddle) lib/paddle.ex:612: Paddle.clean_eldap_search_results/1
phoenix_1 | (paddle) lib/paddle.ex:206: Paddle.handle_call/3
phoenix_1 | (stdlib) gen_server.erl:636: :gen_server.try_handle_call/4
phoenix_1 | (stdlib) gen_server.erl:665: :gen_server.handle_msg/6
phoenix_1 | (stdlib) proc_lib.erl:247: :proc_lib.init_p_do_apply/3

I don't know if it is in your plans, but have you considered setting up a supervisor process so when it does die like this, we can recover?

Thanks,

Uninformative README

I could not deduce the use of the library from the README, nor find any link to the documentation or a tutorial.
Moreover, the Wiki is empty :(

encoding issue

I created an Active Directory user with the following value.

  • sn
  • givenName 阿翔
  • cn 張阿翔

Result

cn: [<<195, 165, 194, 188, 194, 181, 195, 169, 194, 152, 194, 191, 195, 167,
       194, 191, 194, 148>>]
givenName: [<<195, 169, 194, 152, 194, 191, 195, 167, 194, 191, 194, 148>>],
sn: ["å¼µ"]

Detail Log

iex(4)> Paddle.get(%Gaia.AdUser{sAMAccountName: "PaddleTest"})
[debug] Getting entries with dn: CN=Users,DC=jourdeness,DC=com,DC=tw and filter: {:and,
 [equalityMatch: {:AttributeValueAssertion, 'sAMAccountName', 'PaddleTest'},
  equalityMatch: {:AttributeValueAssertion, 'objectClass', 'person'},
  equalityMatch: {:AttributeValueAssertion, 'objectClass',
   'organizationalPerson'},
  equalityMatch: {:AttributeValueAssertion, 'objectClass', 'user'}]}
[debug] search request = {'SearchRequest',"CN=Users,DC=jourdeness,DC=com,DC=tw",
                     wholeSubtree,derefAlways,0,0,false,
                     {'and',
                         [{equalityMatch,
                              {'AttributeValueAssertion',"sAMAccountName",
                                  "PaddleTest"}},
                          {equalityMatch,
                              {'AttributeValueAssertion',"objectClass",
                                  "person"}},
                          {equalityMatch,
                              {'AttributeValueAssertion',"objectClass",
                                  "organizationalPerson"}},
                          {equalityMatch,
                              {'AttributeValueAssertion',"objectClass",
                                  "user"}}]},
                     []}

[debug] search reply = {ok,{'LDAPMessage',3,
                       {searchResEntry,
                           {'SearchResultEntry',
                               [67,78,61,229,188,181,233,152,191,231,191,148,
                                44,67,78,61,85,115,101,114,115,44,68,67,61,
                                106,111,117,114,100,101,110,101,115,115,44,68,
                                67,61,99,111,109,44,68,67,61,116,119],
                               [{'PartialAttribute',"objectClass",
                                    ["top","person","organizationalPerson",
                                     "user"]},
                                {'PartialAttribute',"cn",
                                    [[229,188,181,233,152,191,231,191,148]]},
                                {'PartialAttribute',"sn",["å¼µ"]},
                                {'PartialAttribute',"description",
                                    [[80,97,100,100,108,101,32,230,184,172,
                                      232,169,166,229,184,179,232,153,159]]},
                                {'PartialAttribute',"givenName",
                                    [[233,152,191,231,191,148]]},
                                {'PartialAttribute',"distinguishedName",
                                    [[67,78,61,229,188,181,233,152,191,231,
                                      191,148,44,67,78,61,85,115,101,114,115,
                                      44,68,67,61,106,111,117,114,100,101,110,
                                      101,115,115,44,68,67,61,99,111,109,44,
                                      68,67,61,116,119]]},
                                {'PartialAttribute',"instanceType",["4"]},
                                {'PartialAttribute',"whenCreated",
                                    ["20171222032945.0Z"]},
                                {'PartialAttribute',"whenChanged",
                                    ["20171222033009.0Z"]},
                                {'PartialAttribute',"displayName",
                                    [[229,188,181,233,152,191,231,191,148]]},
                                {'PartialAttribute',"uSNCreated",["13734606"]},
                                {'PartialAttribute',"uSNChanged",["13734624"]},
                                {'PartialAttribute',"name",
                                    [[229,188,181,233,152,191,231,191,148]]},
                                {'PartialAttribute',"objectGUID",
                                    [[6,229,41,227,165,153,107,75,170,160,77,
                                      74,103,237,250,7]]},
                                {'PartialAttribute',"userAccountControl",
                                    ["512"]},
                                {'PartialAttribute',"codePage",["0"]},
                                {'PartialAttribute',"countryCode",["0"]},
                                {'PartialAttribute',"pwdLastSet",["0"]},
                                {'PartialAttribute',"primaryGroupID",["513"]},
                                {'PartialAttribute',"objectSid",
                                    [[1,5,0,0,0,0,0,5,21,0,0,0,14,34,35,12,84,
                                      61,232,41,62,12,155,179,58,53,0,0]]},
                                {'PartialAttribute',"accountExpires",
                                    ["9223372036854775807"]},
                                {'PartialAttribute',"sAMAccountName",
                                    ["PaddleTest"]},
                                {'PartialAttribute',"sAMAccountType",
                                    ["805306368"]},
                                {'PartialAttribute',"userPrincipalName",
                                    ["[email protected]"]},
                                {'PartialAttribute',"objectCategory",
                                    ["CN=Person,CN=Schema,CN=Configuration,DC=jourdeness,DC=com,DC=tw"]},
                                {'PartialAttribute',"dSCorePropagationData",
                                    ["16010101000000.0Z"]}]}},
                       asn1_NOVALUE}}

[debug] search reply = {ok,{'LDAPMessage',3,
                       {searchResDone,
                           {'LDAPResult',success,[],[],asn1_NOVALUE}},
                       asn1_NOVALUE}}

[debug] search reply = searchResDone

{:ok,
 [%{__struct__: Gaia.AdUser, accountExpires: ["9223372036854775807"],
    cn: [<<195, 165, 194, 188, 194, 181, 195, 169, 194, 152, 194, 191, 195, 167,
       194, 191, 194, 148>>], codePage: ["0"], countryCode: ["0"],
    dSCorePropagationData: ["16010101000000.0Z"],
    description: [<<80, 97, 100, 100, 108, 101, 32, 195, 166, 194, 184, 194,
       172, 195, 168, 194, 169, 194, 166, 195, 165, 194, 184, 194, 179, 195,
       168, 194, 153, 194, 159>>],
    displayName: [<<195, 165, 194, 188, 194, 181, 195, 169, 194, 152, 194, 191,
       195, 167, 194, 191, 194, 148>>],
    distinguishedName: [<<67, 78, 61, 195, 165, 194, 188, 194, 181, 195, 169,
       194, 152, 194, 191, 195, 167, 194, 191, 194, 148, 44, 67, 78, 61, 85,
       115, 101, 114, 115, 44, 68, 67, 61, 106, 111, 117, 114, 100, 101, ...>>],
    givenName: [<<195, 169, 194, 152, 194, 191, 195, 167, 194, 191, 194, 148>>],
    instanceType: ["4"], mail: nil, mobile: nil,
    name: [<<195, 165, 194, 188, 194, 181, 195, 169, 194, 152, 194, 191, 195,
       167, 194, 191, 194, 148>>],
    objectCategory: ["CN=Person,CN=Schema,CN=Configuration,DC=jourdeness,DC=com,DC=tw"],
    objectGUID: [<<6, 195, 165, 41, 195, 163, 194, 165, 194, 153, 107, 75, 194,
       170, 194, 160, 77, 74, 103, 195, 173, 195, 186, 7>>],
    objectSid: [<<1, 5, 0, 0, 0, 0, 0, 5, 21, 0, 0, 0, 14, 34, 35, 12, 84, 61,
       195, 168, 41, 62, 12, 194, 155, 194, 179, 58, 53, 0, 0>>],
    primaryGroupID: ["513"], pwdLastSet: ["0"], sAMAccountName: ["PaddleTest"],
    sAMAccountType: ["805306368"], sn: ["å¼µ"], telephoneNumber: nil,
    uSNChanged: ["13734624"], uSNCreated: ["13734606"],
    userAccountControl: ["512"],
    userPrincipalName: ["[email protected]"],
    whenChanged: ["20171222033009.0Z"], whenCreated: ["20171222032945.0Z"]}]}

Ajouter un flag inet6

Yo, y'a une option pour avoir l'IPv6 dans eldap un peu planquée dans les notes de version.
Apparemment ça fonctionne avec :eldap.open(['cimmeria.rezel.enst.fr'], [tcpopts: [:inet6], port: 389]), du coup si y'a moyen d'avoir un booléen v6?, ça serait chouette :)

No success in class generation

Dear all,

First of, thanks for the amazing work with this library.

I am currently trying to generate a class for inetorgperson.schema, but with no success so far, and I would be really grateful if you could provide some hints on how to solve my issue. Please have my apologies, as I am still pretty new to Elixir (and LDAP, actually).

I have my schema installed in /etc/openldap/schema/*.schema, and thus have configured

config :paddle, Paddle,
  host: "myserver.com"
  base: "dc=myserver,dc=com",
  ssl: false,
  account_subdn: "ou=users",
  port: 389,
  schema_files: Path.wildcard("/etc/openldap/schema/*.schema")

as suggested by the documentation.

I then have created, in a file api/ldap.ex, my helper module to authenticate my users, etc., and, after the module

defmodule Api.Ldap do
    ....
end

require Paddle.Class.Helper
Paddle.Class.Helper.gen_class_from_schema(Api.Ldap.InetOrgPerson, ["inetOrgPerson"], "ou=users")

If I get this right, the first parameter tells the macro to generate a module named Api.Ldap.InetOrgPerson, based on the LDAP schema inetOrgPerson, and that such entries should be stored under, in my case, ou=users,dc=myserver,dc=com. If I am not mistaken, Paddle is able to guess in which .schema file inetOrgPerson is defined, but this might really be where I get this wrong. However, I don't understand how it should then be specified which .schema defines inetOrgPerson.

Indeed, I get the following error from mix:

Erlang/OTP 23 [erts-11.0.3] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe]

Compiling 20 files (.ex)

== Compilation error in file lib/ldap.ex ==
** (RuntimeError) Missing object classe(s) definition(s): inetOrgPerson
    lib/paddle/schema_parser.ex:114: Paddle.SchemaParser.filter_definitions/3
    lib/paddle/schema_parser.ex:48: Paddle.SchemaParser.attributes/1
    lib/paddle/class.ex:186: Paddle.Class.Helper."MACRO-gen_class_from_schema"/6
    expanding macro: Paddle.Class.Helper.gen_class_from_schema/3
    lib/ldap.ex:38: (file)

Which would mean, I think, that Paddle is not able to guess where to find the inetOrgPerson definition.

Could you indicate me

  • if this is really the issue?
  • how to inform Paddle which file it should be reading the class from?
  • what is your process for debugging those kind of mistakes ?

Best regards

Caracter with accent error

Maybe I am making something wrong but when I try to add this entry

[
  objectClass: ["top", "person", "inetOrgPerson"],
  cn: "rodrigo+1@email",
  sn: "Rodrigo Rebouças",
  displayName: "Rodrigo Rebouças",
  uid: "na",
  mail: "rodrigo+1@email",
  userPassword: 123
]

I receive:

14:47:07.844 [debug] add request = {'AddRequest',
                  "cn=rodrigo\\+1@email,ou=users,ou=opengalaxy,dc=opengalaxy",
                  [{'AddRequest_attributes',"objectClass",
                       ["top","person","inetOrgPerson"]},
                   {'AddRequest_attributes',"cn",["rodrigo+1@email"]},
                   {'AddRequest_attributes',"sn",["Rodrigo Rebouças"]},
                   {'AddRequest_attributes',"displayName",
                       ["Rodrigo Rebouças"]},
                   {'AddRequest_attributes',"uid",["na"]},
                   {'AddRequest_attributes',"mail",["rodrigo+1@email"]},
                   {'AddRequest_attributes',"userPassword",["123"]}]}

14:47:07.845 [debug] add reply = {ok,{'LDAPMessage',2,
                    {addResponse,
                        {'LDAPResult',invalidAttributeSyntax,[],
                            "sn: value #0 invalid per syntax",asn1_NOVALUE}},
                    asn1_NOVALUE}}

Sounds like encoding to me or if I done something wrong please tell me, thanks!!

Is there a way to manage pagination of results?

Hi, I see that in the LDAP v3 there is pagination to deal with the limit exceed results exception but that is not implemented neither in eldap nor paddle.

Do you have plans to add it or have an idea what to do?

Thanks!

Debug help? Problem w/paddle or underlying eldap?

I don't know whom to contact, but I'm feeling like I've hit a dead-end. I can run an ldap query using ldapsearch and it returns valid results. But the seemingly same query from paddle returns no results.

A redacted ldapsearch (which runs successfully) looks like:

$ ldapsearch -W -H ldaps://ldap.domain\
  -D cn=username@loc,ou=users,dc=domain\
  -b ou=users,dc=domain\
  '(&(cn=username@loc)(memberOf=cn=Developers,cn=roles,dc=domain))'
... data with valid search result
# search result
search: 2
result: 0 Success
# numResponses: 2
# numEntries: 1

The code I have in elixir looks like:

result = Paddle.get(filter: [cn: username,
                             memberOf: "cn=Developers,cn=roles,dc=domain"])
Logger.error("GROUP result=#{inspect result}")

And the output from this makes it /appear/ that the search query ran in the same manner as the ldapsearch command above, but it has no results.

20:51:40.691  level=debug Getting entries with dn: ou=users,dc=domain and filter: {:and,
             [equalityMatch: {:AttributeValueAssertion, 'cn', 'username@loc'},
              equalityMatch: {:AttributeValueAssertion, 'memberOf', 'cn=Developers,cn=roles,dc=domain'}]}
20:51:40.692  level=debug search request = {'SearchRequest',"ou=users,dc=domain",
                     wholeSubtree,derefAlways,0,0,false,
                     {'and',
                         [{equalityMatch,
                              {'AttributeValueAssertion',"cn",
                                  "username@loc"}},
                          {equalityMatch,
                              {'AttributeValueAssertion',"memberOf",
                                  "cn=Developers,cn=roles,dc=domain"}}]},
                     []} 
20:51:40.729  level=debug search reply = {ok,{'LDAPMessage',4,
                       {searchResDone,
                           {'LDAPResult',success,[],[],asn1_NOVALUE}},
                       asn1_NOVALUE}} 
20:51:40.729  level=debug search reply = searchResDone   
20:51:40.729  level=error GROUP result={:error, :noSuchObject}

I am not certain what the debug line2 wholeSubtree... is, and how it relates to the search. My guess is something with the context of the search is different enough that it is not matching.

Any help would be greatly appreciated. Thx.

Connection Timeout

The problem may be on our end, but Paddle's LDAP connection appears to be timing out. The application works for a while, but the connection seems to go bad after a while. What is the best way to reestablish the connection when this happens?

14:38:45.708 request_id=10arplb3dffjiu9pcleek143qaptqve1 [info] POST /authenticate
14:38:47.748 [error] #PID<0.1971.0> running MyApp.Endpoint terminated
Server: myproject-api:8080 (http)
Request: POST /authenticate
** (exit) exited in: GenServer.call(Paddle, {:authenticate, 'uid=user,ou=People,dc=domain,dc=com', 'user'}, 5000)
   ** (EXIT) time out
14:38:48.962 [error] #PID<0.1972.0> running MyApp.Endpoint terminated
Server: myproject-api:8080 (http)
Request: POST /authenticate
** (exit) exited in: GenServer.call(Paddle, {:authenticate, 'uid=user,ou=People,dc=domain,dc=com', 'user'}, 5000)
   ** (EXIT) time out
14:38:50.712 [error] #PID<0.1973.0> running MyApp.Endpoint terminated
Server: myproject-api:8080 (http)
Request: POST /authenticate
** (exit) exited in: GenServer.call(Paddle, {:authenticate, 'uid=user,ou=People,dc=domain,dc=com', 'user'}, 5000)
   ** (EXIT) time out
14:38:55.092 request_id=8l0msrlt26jl7t3fo1tulf4k8f1nl4at [info] POST /authenticate
14:39:00.099 [error] #PID<0.1974.0> running MyApp.Endpoint terminated
Server: myproject-api:8080 (http)
Request: POST /authenticate
** (exit) exited in: GenServer.call(Paddle, {:authenticate, 'uid=user,ou=People,dc=domain,dc=com', 'user'}, 5000)
   ** (EXIT) time out
14:39:01.802 request_id=nq8cd2l5jsch6nsu37bqmmjiop7s3qcg [info] POST /authenticate
14:39:06.807 [error] #PID<0.1975.0> running MyApp.Endpoint terminated
Server: myproject-api:8080 (http)
Request: POST /authenticate
** (exit) exited in: GenServer.call(Paddle, {:authenticate, 'uid=user,ou=People,dc=domain,dc=com', 'user'}, 5000)
   ** (EXIT) time out
14:39:08.415 request_id=vfo18ec9f30tqi2aaa8dj6pucobu9h0c [info] POST /authenticate
14:39:10.238 request_id=33hoql67t1qvak09t2iap446keutnog0 [info] POST /authenticate
14:39:13.423 [error] #PID<0.1976.0> running MyApp.Endpoint terminated
Server: myproject-api:8080 (http)
Request: POST /authenticate
** (exit) exited in: GenServer.call(Paddle, {:authenticate, 'uid=user,ou=People,dc=domain,dc=com', 'user'}, 5000)
   ** (EXIT) time out
14:39:15.245 [error] #PID<0.1977.0> running MyApp.Endpoint terminated
Server: myproject-api:8080 (http)
Request: POST /authenticate
** (exit) exited in: GenServer.call(Paddle, {:authenticate, 'uid=user,ou=People,dc=domain,dc=com', 'user'}, 5000)
   ** (EXIT) time out

modify object with full DN

I need to modify user's attribute, say mobile in Active Directory. But the dn or distinguishedName in return value contains base dn like DC=example,DC=com.

{:ok, result} = Paddle.get(filter: [sAMAccountName: "wendy"], base: [ou: "user", ou: "mail"])
wendy = List.first(result)
# Not worked here
Paddle.modify(wendy["dn"], replace: {"mobile", "0912345678"})

workaround for now
remove base dn from object["dn"].

String.replace(wendy["dn"], ",DC=example,DC=com", "")
# remove some data for brevity
%{"sAMAccountType" => ["805306368"],
  "lastLogonTimestamp" => ["131580319435909134"],
  "whenChanged" => ["20171218005223.0Z"], "sAMAccountName" => ["wendyyao"],
  "cn" => [<<195, 165, 194, 167, 194, 154, 195, 164, 194, 189, 194, 169, 195,
     165, 194, 189, 194, 164>>], "lastLogon" => ["131581226138521747"],
   <<67, 78, 61, 72, 81, 45, 195, 168, 194, 179, 194, 135, 195, 168, 194, 168,
     194, 138, 195, 169, 194, 131, 194, 168, 44, 79, 85, 61, 195, 168, 194, 179,
     ...>>, "CN=Remote Desktop Users,CN=Builtin,DC=jourdeness,DC=com,DC=tw",
   "CN=Account Operators,CN=Builtin,DC=jourdeness,DC=com,DC=tw"],
  "givenName" => ["佩彤"], "sn" => [<<195, 165, 194, 167, 194, 154>>],
  "logonCount" => ["209"], "primaryGroupID" => ["513"],
  "uSNChanged" => ["13653562"], "accountExpires" => ["9223372036854775807"],
  "dn" => <<67, 78, 61, 195, 165, 194, 167, 194, 154, 195, 164, 194, 189, 194,
    169, 195, 165, 194, 189, 194, 164, 44, 79, 85, 61, 195, 168, 194, 179, 194,
    135, 195, ...>>, "postalCode" => ["007429"],
  "name" => [<<195, 165, 194, 167, 194, 154, 195, 164, 194, 189, 194, 169, 195,
     165, 194, 189, 194, 164>>],
  "objectSid" => [<<1, 5, 0, 0, 0, 0, 0, 5, 21, 0, 0, 0, 14, 34, 35, 12, 84, 61,
     195, 168, 41, 62, 12, 194, 155, 194, 179, 121, 36, ...>>],
  "objectClass" => ["top", "person", "organizationalPerson", "user"],
  "distinguishedName" => [<<67, 78, 61, 195, 165, 194, 167, 194, 154, 195, 164,
     194, 189, 194, 169, 195, 165, 194, 189, 194, 164, 44, 79, 85, ...>>],
  "displayName" => [<<195, 165, 194, 167, 194, 154, 195, 164, 194, 189, 194,
     169, 195, 165, 194, 189, 194, 164>>], "countryCode" => ["0"]}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.