diff --git a/wagtail/wagtailadmin/utils.py b/wagtail/wagtailadmin/utils.py index 0050e5b284..ae3a035ca9 100644 --- a/wagtail/wagtailadmin/utils.py +++ b/wagtail/wagtailadmin/utils.py @@ -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):