Refactor permission_required/any_permission_required to allow substituting other kinds of permission test

pull/2045/merge
Matt Westcott 2015-09-24 13:02:17 +01:00 zatwierdzone przez Karl Hobley
rodzic 039db5ed89
commit 63cd666fd4
1 zmienionych plików z 23 dodań i 24 usunięć

Wyświetl plik

@ -74,21 +74,18 @@ def permission_denied(request):
return redirect('wagtailadmin_home')
def permission_required(permission_name):
def user_passes_test(test):
"""
Replacement for django.contrib.auth.decorators.permission_required which returns a
more meaningful 'permission denied' response than just redirecting to the login page.
(The latter doesn't work anyway because Wagtail doesn't define LOGIN_URL...)
Given a test function that takes a user object and returns a boolean,
return a view decorator that denies access to the user if the test returns false.
"""
# Construct and return a decorator function specific to the permission name
# that has been passed in
def decorator(view_func):
# decorator takes the view function, and returns the view wrapped in
# a permission check
@wraps(view_func)
def wrapped_view_func(request, *args, **kwargs):
if request.user.has_perm(permission_name):
if test(request.user):
# permission check succeeds; run the view function as normal
return view_func(request, *args, **kwargs)
else:
@ -100,30 +97,32 @@ def permission_required(permission_name):
return decorator
def permission_required(permission_name):
"""
Replacement for django.contrib.auth.decorators.permission_required which returns a
more meaningful 'permission denied' response than just redirecting to the login page.
(The latter doesn't work anyway because Wagtail doesn't define LOGIN_URL...)
"""
def test(user):
return user.has_perm(permission_name)
# user_passes_test constructs a decorator function specific to the above test function
return user_passes_test(test)
def any_permission_required(*perms):
"""
Decorator that accepts a list of permission names, and allows the user
to pass if they have *any* of the permissions in the list
"""
# Construct and return a decorator function specific to the permission list
# that has been passed in
def decorator(view_func):
# decorator takes the view function, and returns the view wrapped in
# a permission check
def test(user):
for perm in perms:
if user.has_perm(perm):
return True
@wraps(view_func)
def wrapped_view_func(request, *args, **kwargs):
for perm in perms:
if request.user.has_perm(perm):
# permission check succeeds; run the view function as normal
return view_func(request, *args, **kwargs)
return False
# if we get here, none of the permission checks have passed
return permission_denied(request)
return wrapped_view_func
return decorator
return user_passes_test(test)
def send_mail(subject, message, recipient_list, from_email=None, **kwargs):