Commit 505ea790 by Brodie Rao

decorators: Only return a 403 if the user is authenticated.

This was the original intention of the replacement decorators, which would
incorrectly give 403s to users who aren't logged in. This is especially
confusing when @login_required doesn't send you to the login page.
parent cb131887
...@@ -6,7 +6,9 @@ except ImportError: ...@@ -6,7 +6,9 @@ except ImportError:
from django.utils.functional import wraps from django.utils.functional import wraps
from django.contrib.auth import REDIRECT_FIELD_NAME from django.contrib.auth import REDIRECT_FIELD_NAME
from django.http import HttpResponseForbidden from django.contrib.auth.decorators import login_required
from django.http import HttpResponseForbidden, HttpResponseRedirect
from django.utils.http import urlquote
__all__ = ['permission_required', 'user_passes_test'] __all__ = ['permission_required', 'user_passes_test']
...@@ -16,31 +18,25 @@ def user_passes_test(test_func, login_url=None, ...@@ -16,31 +18,25 @@ def user_passes_test(test_func, login_url=None,
returns 403 Forbidden if the user is already logged in. returns 403 Forbidden if the user is already logged in.
""" """
if not login_url:
from django.conf import settings
login_url = settings.LOGIN_URL
def decorator(view_func): def decorator(view_func):
@wraps(view_func) @wraps(view_func)
def wrapper(request, *args, **kwargs): def wrapper(request, *args, **kwargs):
if test_func(request.user): if test_func(request.user):
return view_func(request, *args, **kwargs) return view_func(request, *args, **kwargs)
else: elif request.user.is_authenticated():
return HttpResponseForbidden('<h1>Permission denied</h1>') return HttpResponseForbidden('<h1>Permission denied</h1>')
else:
path = '%s?%s=%s' % (login_url, redirect_field_name,
urlquote(request.get_full_path()))
return HttpResponseRedirect(path)
return wrapper return wrapper
return decorator return decorator
def login_required(function=None, redirect_field_name=REDIRECT_FIELD_NAME):
"""Replacement for django.contrib.auth.decorators.login_required that
returns 403 Forbidden if the user is already logged in.
"""
actual_decorator = user_passes_test(
lambda u: u.is_authenticated(),
redirect_field_name=redirect_field_name
)
if function:
return actual_decorator(function)
return actual_decorator
def permission_required(perm, login_url=None): def permission_required(perm, login_url=None):
"""Replacement for django.contrib.auth.decorators.permission_required that """Replacement for django.contrib.auth.decorators.permission_required that
returns 403 Forbidden if the user is already logged in. returns 403 Forbidden if the user is already logged in.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment