Python ldap3 how return mail as string (no dict, or list)

135 Views Asked by At

I need to get all mail address from ldap for a given cn...

The issue is when I try to put:

  • In a list like: mylist = [cn, mail]
  • In a dict like: mydict[cn] = mail

But I get something like ['cn', mail: [email protected]] and the result I want is this [cn, [email protected]].

Here's the code:

    basedn = config['ldap']['basedn']
    attribs = ['mail']
    data = []
    
    for account in logon_name:
    
        sfilter = f'(cn={account})'
        ldap_conn.search(
            basedn,
            sfilter,
            attributes=attribs
        )
        if ldap_conn.entries:
            test = ldap_conn.entries[0].mail
            data.append([account, test])
            print(test)
            print(data)

And the result:

print(test)

The output:

[email protected]

When I try to put the variable test value give:

[['xxxxx', mail: [email protected]]]

I don't know where the mail is provided, and why I don't see it in the test variable and the print(test).

Someone has an idea?

1

There are 1 best solutions below

1
larsks On

I've set up a simple test environment using the bitnami openldap image and the following test data:

dn: cn=alice,ou=users,dc=example,dc=com
objectClass: inetOrgPerson
cn: alice
sn: example
mail: [email protected]

dn: cn=bob,ou=users,dc=example,dc=com
objectClass: inetOrgPerson
cn: bob
sn: example
mail: [email protected]

This lets us attempt to reproduce your issue:

>>> import ldap3
>>> ldap_conn = ldap3.Connection('ldap://localhost:1389', 'cn=admin,dc=example,dc=com', 'secret')
>>> basedn = 'dc=example,dc=com'
>>> attribs = ['mail']
>>> sfilter = f'(cn=alice)'
>>> ldap_conn.open()
>>> ldap_conn.search(basedn, sfilter, attributes=attribs)
True
>>> test = ldap_conn.entries[0].mail
>>> test
mail: [email protected]
>>>
>>> print(test)
[email protected]
>>> type(test)
<class 'ldap3.abstract.attribute.Attribute'>

So here we see that when you ask for ldap_conn.entries[0].mail, you're getting back an Attribute object. Let's look at the attributes available on an Attribute:

>>> dir(test)
['__class__', '__delattr__', '__dict__', '__dir__',
'__doc__', '__eq__', '__format__', '__ge__',
'__getattribute__', '__getitem__', '__getstate__',
'__gt__', '__hash__', '__init__', '__init_subclass__',
'__iter__', '__le__', '__len__', '__lt__', '__module__',
'__ne__', '__new__', '__reduce__', '__reduce_ex__',
'__repr__', '__setattr__', '__sizeof__', '__str__',
'__subclasshook__', '__weakref__', 'cursor', 'definition',
'entry', 'key', 'other_names', 'raw_values', 'response',
'value', 'values']

The value attribute looks promising:

>>> test.value
[email protected]

Which suggests you actually want:

data.append(test.value)

Here's a runnable example:

import ldap3


ldap_conn = ldap3.Connection(
    "ldap://localhost:1389", "cn=admin,dc=example,dc=com", "secret"
)
basedn = "dc=example,dc=com"
attribs = ["mail"]
data = []

for account in ["alice", "bob"]:
    sfilter = f"(cn={account})"
    ldap_conn.open()
    ldap_conn.search(basedn, sfilter, attributes=attribs)
    test = ldap_conn.entries[0].mail
    data.append(test.value)

print(data)

Which produces as output:

['[email protected]', '[email protected]']