"""Security enchancement middleware Allows to use `public` decorator for few public views instead of `login_required` for almost everything. Maybe we should contribute this to Django -Alex (с) Alex Lebedev , Februray 2009 """ import re from functools import partial from django.contrib.auth import REDIRECT_FIELD_NAME from django.conf import settings from django.http import HttpResponseRedirect from django.utils.http import urlquote def public(function): """Decorator for public views that do not require authentication """ function.is_public_view = True return function def is_public(function): if function.__module__.startswith('django.') and not function.__module__.startswith('django.views.generic') : return True class NonpublicMiddleware(object): def process_view(self, request, view_func, view_args, view_kwargs): if isinstance(view_func, partial): # if partial - use original function for authorization view_func = view_func.func if getattr(view_func, 'is_public_view', None): return None elif is_public(view_func): return None else: if not getattr(view_func, 'login_required', None): view_func.login_required = True if view_func.login_required and not request.user.is_authenticated(): return self.redirect_to_login(request.get_full_path()) def redirect_to_login(self, original_target, login_url=settings.LOGIN_URL): return HttpResponseRedirect("%s?%s=%s" % ( login_url, REDIRECT_FIELD_NAME, urlquote(original_target)))