I'm working on an application with a DRF base, requiring LDAP authentication. I have run across a problem, by which I am seeing different behaviours for users logging in directly via the DRF API and those accessing it from an external application - ie Curl/Postman.
In the application, once logged in I present a series of views/urls that users can access, ie the url below to view 'samples':
http://:8000/api/samples
I have applied DjangoModelPermissions using a custom permission class to my Sample view which requires model permission to view the model, ie:
class HasModelPermission(permissions.DjangoModelPermissions):
perms_map = {
'GET': ['%(app_label)s.read_%(model_name)s'],
'OPTIONS': ['%(app_label)s.read_%(model_name)s'],
'HEAD': ['%(app_label)s.read_%(model_name)s'],
'POST': ['%(app_label)s.add_%(model_name)s'],
'PUT': ['%(app_label)s.change_%(model_name)s'],
'PATCH': ['%(app_label)s.change_%(model_name)s'],
'DELETE': ['%(app_label)s.delete_%(model_name)s'],
}
class SampleView(generics.ListAPIView):
queryset = Sample.objects.all()
serializer_class = SampleSerializer
permission_classes = [HasModelPermission]
As per https://django-auth-ldap.readthedocs.io/en/latest/permissions.html#group-mirroring, I've configured my ldap setup with AUTH_LDAP_FIND_GROUP_PERMS=true and have created matching DJANGO groups for LDAP groups I care about - and I have allocated model permissions to these groups. This is working as I'd expect - only users who are members of groups with permission to view the list are able to see it.
The key issue I am seeing is that while the internal DRF API is correctly determining user permissions, users logging in externally and then submitting GET requests are determined NOT to have permission to view.
I have identified via some debugging that the cause is a failed test in the following code from django_auth_ldap.backend.py which gets called from the view dispatcher in DRF, essentially, when I access the url from built in the DRF API, "hasattr(user, 'ldap_user'):" returns true, when I connect via postman or curl etc, "hasattr(user, 'ldap_user'):" returns false - obviously meaning no user permissions are determined to exist.
def get_group_permissions(self, user, obj=None):
if not hasattr(user, 'ldap_user') and self.settings.AUTHORIZE_ALL_USERS:
_LDAPUser(self, user=user) # This sets user.ldap_user
if hasattr(user, 'ldap_user'):
permissions = user.ldap_user.get_group_permissions()
else:
permissions = set()
return permissions
So I guess ultimately my question is, how should I be populating/maintaining the user.ldap_user attribute between HTTP operations from remote endpoints. (note I am using session and token authentication ATM). I'm guessing my issue is more to do with either maintaining a users lda_user attribute data between operations, or being able to retrieve it on each successive operation.