-
Notifications
You must be signed in to change notification settings - Fork 104
WIP: feat(ldap3): replace python-ldap with ldap3 #208
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
base: master
Are you sure you want to change the base?
Conversation
Currently this PR does not support Python 3.6 since |
It seems like preserving Python 3.6 support is worth doing, since it won't be EOL for quite some time. Certainly downstream projects like Zulip that support all non-EOL Python projects wouldn't be able to use it if Python 3.6 support is removed. |
b5cabd2
to
e5afcf3
Compare
Sorry for the late response, but now Python 3.6 support ist back with some additional improvements. |
Hi! What is the current status here? Do the maintainers intend to merge it and move to ldap3? I am currently trying to generalise the Django Debug Toolbar panel from django-windowsauth, and having django-auth-ldap use ldap3 would ease things a lot. |
Switching to ldap3 sounds good to me. I believe the type hinting should move to a separate PR to keep things focused. Type hinting benefits the project regardless of the change to ldap3. I’ll dive deeper into this PR during the work week. I have an environment to test the changes on, that will certainly come handy. |
Splitting up the PR into ldap3 andy type hinting would of course be possible, but either the ldap3 branch has to sit ontop of the type hinting branch or ldap3 would loose type hinting and therefore would lead to an merge confilct when merging both. Since this is defenetely a breaking change, wouldn't it make sense to keep dropping the deprecaded features together? Furthermore (it's been a long time since i wrote the code, so I could remember wrongly) I think some changes had to be done to get ldap3 working. And thanks for testing the code. This would definitely help to verify the PR. |
I just migrated our staging system with a rather complex setup (including a mass import utility sitting on top of django-ldap-auth) to this PR and it works. One thing to add to the list of breaking changes is that with python-ldap, the attrs dictionaries were guaranteed to have lists as values, even for single-value attributes, and in ldap3 only multi-value attributes are packed in lists. Another nice thing is that ldap3 returns reasonable objects if it detects the attribute correctly, i.e. datetime for LDAP datetime attributes. Apart from that, simply dropping in the code from this PR worked. |
The ldap3 sitting on top of the type hinting branch is fine. Can prefix the commit title with [DO NOT REVIEW] or marking to similar effect to indicate the change is part of another PR.
Removal of deprecated feature is going to happen, regardless of other breaking changes. Making all breaking changes in the same release avoids successively releasing versions with breaking changes, but may break more installations. Not a clear win IMO. I’ll get back to you once I am more familiar with the suggested changes. |
Awesome, that’s very promising! |
For reference, here's the diff in our consuming application: https://edugit.org/AlekSIS/official/AlekSIS-App-LDAP/-/merge_requests/45/diffs |
Thanks for the hint, I adapted the PR message. |
|
Great. Please make it "an LDAP attribute", though, in the final documentation :). |
Done |
29767fd
to
f98d1de
Compare
0fe11dc
to
4ab0369
Compare
Hey @jdufresne and @francoisfreitag! An estimation whether we can expect this to be merged and released and, if we can, when, would be much appreciated. The AlekSIS team has a long-standing and release-critical performance issue with code using django-auth-ldap, and profiling it is close to impossible with the old LDAP backend. |
Hi @Natureshadow, I agree that the full-python implementation of the LDAP backend (ldap3) is easier to install and maintain, and probably easier for library users to interact with. My employer would also benefit from the switch to ldap3. We’re in the process of splitting out this work into smaller increments that are easier to reason about and discuss. When the foundation is integrated, the backend change can be integrated. The author separated the type hinting from backend switch, which is a good step towards getting type hinting integrated and keeping this PR focused on the backend switch. If you want to help integration, you can review the changes and make sure they:
|
- add python 3.6+ type hints - replace applying defaults dict in LDAPSettings with actual variables, allowing type hints, checking if variable exists (e.g. IDE), and preventing supplied defaults dict (LDAPSettings.__init__) to inject undesired variables - add AbstractLDAPSearch as abstract base class - fix (by removing) result of search_s not being checked if None in LDAPSearch.execute - add conversion to string in AbstractLDAPSearch._escape_filterargs - rename AbstractLDAPSearch._begin(...) to AbstractLDAPSearch._search(...) and AbstractLDAPSearch._results(...) to AbstractLDAPSearch._result(...) - add AbstractLDAPSearch._abandon(...) - LDAPSearch._search(...) saves the msgid inside the object instead of returning it - make LDAPGroupType abstract - MemberDNGroupType.is_member(...) now returns bool instead of Union[bool, int] - remove kwargs from LDAPGroupQuery.__init__ - update test mocks corresponding to the AbstractLDAPSearch changes
… dynamic variable name - renaming LDAPSettings._name(str) to LDAPSettings._prepend_prefix(str) - replacing AUTH_LDAP_xyz in strings with LDAPSettings._prepend_prefix(xyz)
…to instance variables - remove unused variables supports_anonymous_user, supports_object_permissions, and supports_inactive_user - move settings_prefix to LDAPSettings - remove default_settings - change _settings and _ldap from class variables to instance variables - add __setstate__ to set excluded properties to the object
- replace defaults dict with __init__ parameters - drop support for CACHE_GROUPS
- add __setstate__ to set excluded properties to the object
- make _LDAPConfig.logger and NestedMemberDNGroupType.find_groups_with_any_member protected - directly convert the group info into a dict in NestedMemberDNGroupType.user_groups - check _group_type and _group_search against their corresponding type instead of None in _LDAPUserGroups._init_group_settings() - use the settings object instead of the django settings to retrieve the global options in LDAPBackend.ldap()
…longer edit LDAPSettings - _LDAPUser._normalize_mirror_settings() no longer edits LDAPSettings and instead returns the normalized Sets
# Conflicts: # django_auth_ldap/backend.py
# Conflicts: # django_auth_ldap/backend.py # tests/tests.py
- adjust type hints - replace python-ldap methods/functions/... with the corresponding ldap3 ones - remove deprecated features (uri call without argument and CACHE_GROUPS) - remove CONNECTION_OPTIONS and GLOBAL_OPTIONS - depends on async connections (`ldap3.ASYNC`)
Why ldap3
ldap3 does not need any C libraries neither must it be compiled and therefore is simpler to deploy.
ldap3:
What has been done and what has not:
TODOs:
Breaking changes:
ldap3.ASYNC
connections (it does not support sync connections). The options may be replaced by something from ldap3 wich does nearly the same. Support for sync connections or other types could be implemented if desired.__init__
's have been updated).ldap
properties andget_ldap
methods.LDAPSearch._process_results
and_DeepStringCoder
.See also the commit messages for more informations.
Disclaimer:
This has not been tested in production only all
tox
envs have been run successfully.