diff --git a/django/views/decorators/debug.py b/django/views/decorators/debug.py index 42a6d326619..18900ffca82 100644 --- a/django/views/decorators/debug.py +++ b/django/views/decorators/debug.py @@ -26,6 +26,12 @@ def sensitive_variables(*variables): def my_function() ... """ + if len(variables) == 1 and callable(variables[0]): + raise TypeError( + 'sensitive_variables() must be called to use it as a decorator, ' + 'e.g., use @sensitive_variables(), not @sensitive_variables.' + ) + def decorator(func): @functools.wraps(func) def sensitive_variables_wrapper(*func_args, **func_kwargs): @@ -61,6 +67,13 @@ def sensitive_post_parameters(*parameters): def my_view(request) ... """ + if len(parameters) == 1 and callable(parameters[0]): + raise TypeError( + 'sensitive_post_parameters() must be called to use it as a ' + 'decorator, e.g., use @sensitive_post_parameters(), not ' + '@sensitive_post_parameters.' + ) + def decorator(view): @functools.wraps(view) def sensitive_post_parameters_wrapper(request, *args, **kwargs): diff --git a/tests/view_tests/tests/test_debug.py b/tests/view_tests/tests/test_debug.py index 80c92cf8c36..9b6f66e9899 100644 --- a/tests/view_tests/tests/test_debug.py +++ b/tests/view_tests/tests/test_debug.py @@ -26,6 +26,9 @@ from django.views.debug import ( Path as DebugPath, cleanse_setting, default_urlconf, technical_404_response, technical_500_response, ) +from django.views.decorators.debug import ( + sensitive_post_parameters, sensitive_variables, +) from ..views import ( custom_exception_reporter_filter_view, index_page, @@ -1272,3 +1275,26 @@ class HelperFunctionTests(SimpleTestCase): initial = {'login': 'cooper', 'password': 'secret'} expected = {'login': 'cooper', 'password': CLEANSED_SUBSTITUTE} self.assertEqual(cleanse_setting('SETTING_NAME', initial), expected) + + +class DecoratorsTests(SimpleTestCase): + def test_sensitive_variables_not_called(self): + msg = ( + 'sensitive_variables() must be called to use it as a decorator, ' + 'e.g., use @sensitive_variables(), not @sensitive_variables.' + ) + with self.assertRaisesMessage(TypeError, msg): + @sensitive_variables + def test_func(password): + pass + + def test_sensitive_post_parameters_not_called(self): + msg = ( + 'sensitive_post_parameters() must be called to use it as a ' + 'decorator, e.g., use @sensitive_post_parameters(), not ' + '@sensitive_post_parameters.' + ) + with self.assertRaisesMessage(TypeError, msg): + @sensitive_post_parameters + def test_func(request): + return index_page(request)