Skip to content

Instantly share code, notes, and snippets.

@brianlittmann
Created July 15, 2013 15:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save brianlittmann/6000826 to your computer and use it in GitHub Desktop.
Save brianlittmann/6000826 to your computer and use it in GitHub Desktop.
Django middleware component that wraps the login_required decorator around all URL patterns be default, with exceptions. Can also require user to belong to a group ("admin" in this gist) or be adapted if using the Django admin app.
"""
Middleware component that wraps the login_required decorator around all URL patterns be default, with exceptions.
Define PUBLIC_URLS and ADMIN_URLS using regex in settings.py, where:
PUBLIC_URLS do not require user to be logged in.
ADMIN_URLS require user to be in admin group.
Source: http://stackoverflow.com/a/2164224/720054
"""
# settings.py
PUBLIC_URLS = (
r'/accounts/register/(.*)$',
r'/accounts/activate/(.*)$',
r'/accounts/password/reset/(.*)$',
r'/accounts/login/(.*)$',
r'/api/(.*)$',
)
ADMIN_URLS = (
r'/admin/(.*)$',
)
MIDDLEWARE_CLASSES = (
# Other middleware...
'middleware.LoginRequiredMiddleware',
)
# middleware.py
import re
from django.conf import settings
from django.contrib.auth.decorators import login_required, user_passes_test
class LoginRequiredMiddleware(object):
def __init__(self):
self.admin = tuple(re.compile(url) for url in settings.ADMIN_URLS)
self.public = tuple(re.compile(url) for url in settings.PUBLIC_URLS)
def process_view(self, request, view_func, view_args, view_kwargs):
# No need to process URLs if user is admin
if request.user.groups.filter(name="admin").exists():
return None
# Requests matching an admin URL pattern are returned wrapped with the user_passes_test decorator
for url in self.admin:
if url.match(request.path):
return user_passes_test(lambda u: u.groups.filter(name="admin").exists())(view_func)(request, *view_args, **view_kwargs)
# No need to process remaining URLs if user already logged in
if request.user.is_authenticated():
return None
# An exception match (public) should immediately return None
for url in self.public:
if url.match(request.path):
return None
# Require login for all non-matching requests
return login_required(view_func)(request, *view_args, **view_kwargs)
@gusarg81
Copy link

Hi, this does not work with django 1.10 or newer, because: https://docs.djangoproject.com/en/1.10/releases/1.10/#new-style-middleware.

Can you fix the example? I've tried but not luck, keeps redirecting me after login I've dont know why.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment