Question

I am using django-auth-ldap to connect to an LDAP server for authentication. django-auth-ldap provides the setting AUTH_LDAP_REQUIRE_GROUP, which can be used to allow access only for users placed in a specific group. This works fine, but the option only allows to check one group; I want to check if a users is placed in either one or another group.

In the module django_auth_ldap/backend.py I could modify the method _check_required_groups of the class LDAPUser(object) to implement this behaviour. Modifying it directly works fine, but since changing the source would endup in a maintenance hell, I am searching for a solution to change this method without touching the source. Two ideas I had:

1) Monkey Patching

Change the _check_required_groups method of an instance of the LDAPUser class. The problem is that I have no idea where it is beeing instantiated. I am just using LDAPSearch and GroupOfNamesType imported from django_auth_ldap.config in the settings file, and passing the string django_auth_ldap.backend.LDAPBackend into the AUTHENTICATION_BACKENDS tuple.

2) Extending the module

Create an own module, extending the original django_auth_ldap and using this instead of the original. I tried to create a new directory, adding an __init__.py with the line:

from django_auth_ldap import *

But using this module does not work, since it can't import custom_auth.config.

Any other suggestions or hints how to make one of those attempts to work?

Was it helpful?

Solution

To be modular, DRY and true to the django philosophy in general, you need to create a class named LDAPBackendEx that would inherit from LDAPBackend and use this class to your AUTHENTICATION_BACKENDS instead of django_auth_ldap.backend.LDAPBackend. Also, you'dd create an LDAPUserEx that would inhert from _LDAPUser and override the _check_required_groups method.

So, the LDAPUserEx would be something like:

class LDAPUserEx(_LDAPUser):
    def _check_required_group(self):
        pass # Put your implementation here !

Now, concerning the implementation of LDAPBackendEx: Unfortuanately there is no way of defining a custom _LDAPUser class so you'd have to search every method that uses the _LDAPUser class and override it with LDAPUserEx. The correct methdod of implementing django-auth-ldap (and if we actually needed to be modular) would be to add an user_class attribute to LDAPBackend, initialize it to _LDAPUser and use that instead of _LDAPUser.

Checking the code here, I found out that the methods of LDAPBackend that refer _LDAPUser are authenticate, get_user and get_group_permissions. So, the implementation of LDAPBackendEx would be something like this:

class LDAPBackendEx(LDAPBackend):
    def authenticate(self, username, password):
        ldap_user = LDAPUserEx(self, username=username)
        user = ldap_user.authenticate(password)
        return user

   def get_user(self, user_id):
       pass # please put definition of get_user here changing _LDAPUser to LDAPUserEx

   def get_group_permissions(self, user):
       pass # please put definition of get_group_permissions here changing _LDAPUser to LDAPUserEx        
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top