views:

468

answers:

2

Can a middleware check to see if a value is in the url, such as an image id ("/image/152/"), and if it is then do some checks to make sure the current user has permission to view that image and if not redirect to another url?

I had to roll my own permissions for this site I am working on and I don't want to clog up almost every view I write for the whole site with the same code, so I thought a middleware would be a good idea for this, but I'm not sure how to go about doing it.

+6  A: 

Yes, this is possible. The django middleware docs for process_request indicate that:

def process_request(self, request)

request is an HttpRequest object. This method is called on each request, before Django decides which view to execute.

process_request() should return either None or an HttpResponse object. If it returns None, Django will continue processing this request, executing any other middleware and, then, the appropriate view. If it returns an HttpResponse object, Django won't bother calling ANY other request, view or exception middleware, or the appropriate view; it'll return that HttpResponse.

The HttpRequest object has a path attribute that will give you the URL that was requested.

If you prefer, however, note that you can also extend Django's system for authentication backends to populate the user in the request with permissions based on any arbitrary criteria, such as perhaps your hand-rolled permissions scheme. This way, you can leverage the default authentication decorators (@permission_required and @user_passes_test), and other apps/the admin site will be able to honour your permissions as well. The User object and permissions created do not need to reside in Django's user/permission tables, and can be created virtually on login; I've had a fair amount of success with this.

See Writing an authentication backend if this appeals.

Jarret Hardie
A: 

If you implement authorization (Permission system) in middleware, you will end up with two options:

  1. Check URL and allow to access
  2. Check URL and reject access

If your requirement is that much simple, it is fine, since you don't have to touch views.

But in general, Permission system is much complex than that, for example:

  1. User can access FOO/show_all/
  2. But, he can't see or access foo instance, i.e, FOO/show/foo_1/
  3. Since, he can't access foo_1 instance, we should not show them in show_all (all foo instances)

If you want implement above 3 together, I suggest writing your own authorization backend, which DJango happy to work with. All you need to do is implement few methods (your specific logic) and attach as backend.

Read: http://docs.djangoproject.com/en/dev/topics/auth/#handling-authorization-in-custom-backends

Narendra Kamma