Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

get_object() throws a KeyError exception when user not found #86

Open
Yakuza-UA opened this issue Aug 7, 2020 · 2 comments
Open

get_object() throws a KeyError exception when user not found #86

Yakuza-UA opened this issue Aug 7, 2020 · 2 comments
Labels
Milestone

Comments

@Yakuza-UA
Copy link

This issue only happens whenever I want to user get_user_info_for_username() and search applies to Base DN only (i.e. User DN is None). The way our AD is structured is there are following elements at its root

  • DC=domain,DC=com
    all user and group OUs/CNs are here
    • OU=Global Users
    • OU=Privileged Users
    • etc
  • CN=Configuration,DC=domain,DC=com
  • CN=Schema,CN=Configuration,DC=domain,DC=com
  • DC=ForestDnsZones,DC=domain,DC=com
  • DC=DomainDnsZones,DC=domain,DC=com

Unfortunately, if I use get_user_info_for_username(username) it throws the following error:

  File "./app/forms.py", line 159, in __call__
    portalUser = ldap3.get_user_info_for_username(field.data)
  File "/home/admin/venv/byod-management/lib/python3.7/site-packages/flask_ldap3_login/__init__.py", line 639, in get_user_info_for_username
    _connection=_connection,
  File "/home/admin/venv/byod-management/lib/python3.7/site-packages/flask_ldap3_login/__init__.py", line 702, in get_object
    data = connection.response[0]['attributes']
KeyError: 'attributes'

I had to modify source code of get_object() as per below to get some debug data:

        log.error(dn)
        log.error(filter)
        log.error(attributes)

        data = None
        if len(connection.response) > 0:
            log.error(connection.response)
            data = connection.response[0]['attributes']

It returned the following

ERROR:flask_ldap3_login:DC=domain,DC=com
ERROR:flask_ldap3_login:(&(sAMAccountName=asdasd)(objectclass=person))
ERROR:flask_ldap3_login:*
ERROR:flask_ldap3_login:[{'uri': ['ldap://DomainDnsZones.domain.com/DC=DomainDnsZones,DC=domain,DC=com'], 'type': 'searchResRef'}, {'uri': ['ldap://ForestDnsZones.domain.com/DC=ForestDnsZones,DC=domain,DC=com'], 'type': 'searchResRef'}, {'uri': ['ldap://domain.com/CN=Configuration,DC=domain,DC=com'], 'type': 'searchResRef'}]

So, even though user does not exist under DC=domain,DC=com, LDAP plugin searches through parallel structures and returns a list as seen above. Because get_object() only checks for len(connection.response) > 0, this results into condition as if user was found. Last line in the code then raises KeyError exception because first item (in fact all those in the response) has no 'attributes' key in its list.

Would you be so kind to advise if I have to apply an alternative approach? At the moment I ended up capturing this exception in my code, but it doesn't seem CLEAN. This exception is due to Flask-LDAP3-Login not processing the data properly, imho.

@Yakuza-UA
Copy link
Author

I had to go through LDAP3 documentation thoroughly to understand what's going on. So... the biggest limitation of this module is that it's built around RAW response object, rather than ENTRIES. For example, here's a slightly modified code that does not suffer from the same problem

        data = None
        if len(connection.entries) > 0:
            data = connection.entries[0].entry_attributes_to_dict

Even better if it was just returning an entry object as it's so much more powerful. Few examples:

entry.entry_dn
entry.entry_attributes_as_dict
entry.entry_to_json()

Anyway, by playing with LDAP3 I figured out that this plugin is TOO heavy for my needs. Therefore I will move away to use pure LDAP3 instead. Leaving this issue open for future potential improvements. Consider using connection.entries in future code releases, even if you're going to preserve public interface, at least use this internally 😄

@gmacon gmacon added the bug label Aug 12, 2020
@gmacon gmacon added this to the 1.0 milestone Aug 12, 2020
@gmacon
Copy link
Collaborator

gmacon commented Aug 12, 2020

I think this is most likely a real bug; I've added it to the 1.0 milestone.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants