Skip to content

Instantly share code, notes, and snippets.

@r14c
Created May 30, 2014 21:16
Show Gist options
  • Save r14c/0d58063520c934509c48 to your computer and use it in GitHub Desktop.
Save r14c/0d58063520c934509c48 to your computer and use it in GitHub Desktop.
LoginRequiredMiddleware
try:
from functools import update_wrapper
except ImportError:
from django.utils.functional import update_wrapper # Python 2.3, 2.4 fallback.
from django.contrib.auth.decorators import _CheckLogin
def login_not_required(view_func):
"""
Decorator which marks the given view as public (no login required).
"""
return PublicView(view_func)
class PublicView(object):
"""
Forces a view to be public (no login required).
"""
def __init__(self, view_func):
if isinstance(view_func, _CheckLogin):
self.view_func = view_func.view_func
else:
self.view_func = view_func
update_wrapper(self, view_func)
def __get__(self, obj, cls=None):
view_func = self.view_func.__get__(obj, cls)
return _PublicView(view_func)
def __call__(self, request, *args, **kwargs):
return self.view_func(request, *args, **kwargs)
import re
from django.conf import settings
from django.contrib.auth.decorators import login_required
from path.to.your.decorators import PublicView
class LoginRequiredMiddleware(object):
def __init__(self):
self.public_patterns = []
self.public_views = []
if hasattr(settings, 'PUBLIC_VIEWS'):
for view_path in settings.PUBLIC_VIEWS:
view = self.get_view(view_path)
self.public_views.append(view)
if hasattr(settings, 'PUBLIC_PATHS'):
for public_path in settings.PUBLIC_PATHS:
self.public_patterns.append(re.compile(public_path))
def get_view(self, view_path):
i = view_path.rfind('.')
module_path, view_name = view_path[:i], view_path[i+1:]
module = __import__(module_path, globals(), locals(), [view_name])
return getattr(module, view_name)
def matches_public_view(self, view):
if self.public_views:
for public_view in self.public_views:
if view == public_view:
return True
return False
def matches_public_path(self, path):
if self.public_patterns:
for pattern in self.public_patterns:
if pattern.match(path) is not None:
return True
return False
def process_view(self, request, view_func, view_args, view_kwargs):
if request.user.is_authenticated() or isinstance(view_func, PublicView) or self.matches_public_path(request.path) or self.matches_public_view(view_func):
return None
else:
return login_required(view_func)(request, *view_args, **view_kwargs)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment