Domanda

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?

È stato utile?

Soluzione

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        
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top