I am trying to define a decorator to check if the user has admin certain privileges:
def admin_required(function=None, redirect_field_name=REDIRECT_FIELD_NAME, login_url=None):
actual_decorator = user_passes_test(
lambda u: u.is_staff and u.is_authenticated() and not Association.objects.filter(admins=u).exists(),
login_url=login_url,
redirect_field_name=redirect_field_name
)
if function:
return actual_decorator(function)
return actual_decorator
The aim is to use this throught the views. Particularly, I am using it in a class-based view:
class MyCBV(CreateView):
@method_decorator(admin_required)
def dispatch(self, request, *args, **kwargs):
return super(MyCBV, self).dispatch(request, *args, **kwargs)
The problem is that this view is loaded via AJAX, so the redirect doesn't happen. Also, the HTTP status the view returns is success even when the user authentication fails, so the client (JS) has no way of telling when the action really succeeded or not.
I usually have trouble understanding decorators and Django authentication, so my question is: how can I raise an exception (preferably the PermissionDenied exception) when the authentication decoration function fails?
In Django 1.9+, you can use the
UserPassesTestMixininstead of a decorator, and setraise_exceptiontoTrue.Since you are using Django 1.4, which is insecure and obsolete, you won't be able to do this. There isn't an option to make
user_passes_testraisePermissionDeniedrather than redirect. You could either try to detect the redirect in your JavaScript, or look at theuser_passes_testsource code and implement something similar that returns the response you want.