Django-autocomplete-light: How To Properly Authenticate Requests

Created on 23 Apr 2018  路  9Comments  路  Source: yourlabs/django-autocomplete-light

I apologize if this is less of an issue, and more clarification in the documentation. The following example is provided in the documentation in regards to enforcing authentication on the autocomplete endpoints:

http://django-autocomplete-light.readthedocs.io/en/master/tutorial.html#create-an-autocomplete-view

In this example, if the user is unauthenticated, an empty queryset is returned. I would instead like to return the appropriate status code on the endpoint (401). Since responses can not be returned directly from get_queryset, I attempted to use other standard methods of enforcing authentication on the viewset, such as permission_classes, and has_permission, but none of them seem to be able to properly handle permissions on the endpoint. Is returning an empty queryset the only way to handle this, or is there a reasonable way to return a 401 from an autocomplete endpoint if the user is not authenticated?

All 9 comments

I have not tested it, but a simple way to solve it may look like this

(this does not replace the default login_required. I also do not know if it works together with it. )

class LoginRequiredAjaxMixin(object):
    def dispatch(self, request, *args, **kwargs):
        if request.is_ajax() and not request.user.is_authenticated():
            return JsonResponse(data={'results': [], 'pagination': {}}, status=401)
        return super(LoginRequiredAjaxMixin, self).dispatch(request, *args, **kwargs)


class FooBarAutocomplete(LoginRequiredAjaxMixin, autocomplete.Select2QuerySetView):
    #...

Thanks @luzfcb, overriding dispatch does indeed work. I am using DRF, so it would be nice if there is somewhere I could raise NotAuthenticated, but this is an appropriate hack in the meantime, appreciate it.

@mrname about DRF. I do not know where DRF fits here, since DRF is not a dependency of django-autocomplete-light and is not used anywhere on this project.

Yes I understand that it is not built to support DRF specific constructs, I only meant that a majority of django compatible modules also play well with DRF. This is not a fault of this library at all, and the workaround you provide works perfectly, thanks!

DAL was designed with security against malicious users, not to prevent the UI from presenting an autocomplete widget the user does not have permission to use at all.

However, patches for better DRF support are welcome for review.

Definitely, will dig into it and open a PR when I get some free time. Technically, returning an empty queryset accomplishes the same goal, it is simply not as obvious in terms of debugging and understanding (i.e. - the HTTP status code does not match what actually happened, a permissions issue).

If you want to prevent the user from accessing the HTTP resource at all in a Django view then overriding the dispatch() method as suggested by @luzfcb is the best way imho.

Yes agreed @jpic, it works as expected. I was just hoping for a simpler approach like I can do with standard DRF viewsets, like:

class MyViewSet(viewsets.Viewset):

    permission_classes = (IsAuthenticated,)

As I mentioned, I will try to work up a PR when I have some time, feel free to close the issue in the meantime, as it is definitely not an issue with this library itself.

There is a bunch of permission systems you can use with django really, hopefuly i like how crudlfa+ handles them, rely on Django's system by default and lets you override the allowed method either on a ModelRouter or view directly.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

bennyrock20 picture bennyrock20  路  4Comments

cfblaeb picture cfblaeb  路  8Comments

rg3l3dr picture rg3l3dr  路  6Comments

todorvelichkov picture todorvelichkov  路  3Comments

Schnouki picture Schnouki  路  7Comments