summaryrefslogtreecommitdiff
path: root/django/views/debug.py
diff options
context:
space:
mode:
authorJon Janzen <jon@jonjanzen.com>2023-05-06 20:20:00 -0700
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2023-06-23 13:29:40 +0200
commit38e391e95fe5258bc6d2467332dc9cd44ce6ba52 (patch)
tree68f0c84d7968703f213ea3492cdc985ccc993e48 /django/views/debug.py
parentf8092ee9adafaa052172712349a32bd5889b5ccb (diff)
Refs #31949 -- Made @sensitive_variables/sensitive_post_parameters decorators to work with async functions.
Co-authored-by: Mariusz Felisiak <felisiak.mariusz@gmail.com>
Diffstat (limited to 'django/views/debug.py')
-rw-r--r--django/views/debug.py46
1 files changed, 32 insertions, 14 deletions
diff --git a/django/views/debug.py b/django/views/debug.py
index 53b4125716..c1265bfe6b 100644
--- a/django/views/debug.py
+++ b/django/views/debug.py
@@ -1,4 +1,5 @@
import functools
+import inspect
import itertools
import re
import sys
@@ -17,6 +18,7 @@ from django.utils.encoding import force_str
from django.utils.module_loading import import_string
from django.utils.regex_helper import _lazy_re_compile
from django.utils.version import PY311, get_docs_version
+from django.views.decorators.debug import coroutine_functions_to_sensitive_variables
# Minimal Django templates engine to render the error templates
# regardless of the project's TEMPLATES setting. Templates are
@@ -239,21 +241,37 @@ class SafeExceptionReporterFilter:
Replace the values of variables marked as sensitive with
stars (*********).
"""
- # Loop through the frame's callers to see if the sensitive_variables
- # decorator was used.
- current_frame = tb_frame.f_back
sensitive_variables = None
- while current_frame is not None:
- if (
- current_frame.f_code.co_name == "sensitive_variables_wrapper"
- and "sensitive_variables_wrapper" in current_frame.f_locals
- ):
- # The sensitive_variables decorator was used, so we take note
- # of the sensitive variables' names.
- wrapper = current_frame.f_locals["sensitive_variables_wrapper"]
- sensitive_variables = getattr(wrapper, "sensitive_variables", None)
- break
- current_frame = current_frame.f_back
+
+ # Coroutines don't have a proper `f_back` so they need to be inspected
+ # separately. Handle this by stashing the registered sensitive
+ # variables in a global dict indexed by `hash(file_path:line_number)`.
+ if (
+ tb_frame.f_code.co_flags & inspect.CO_COROUTINE != 0
+ and tb_frame.f_code.co_name != "sensitive_variables_wrapper"
+ ):
+ key = hash(
+ f"{tb_frame.f_code.co_filename}:{tb_frame.f_code.co_firstlineno}"
+ )
+ sensitive_variables = coroutine_functions_to_sensitive_variables.get(
+ key, None
+ )
+
+ if sensitive_variables is None:
+ # Loop through the frame's callers to see if the
+ # sensitive_variables decorator was used.
+ current_frame = tb_frame
+ while current_frame is not None:
+ if (
+ current_frame.f_code.co_name == "sensitive_variables_wrapper"
+ and "sensitive_variables_wrapper" in current_frame.f_locals
+ ):
+ # The sensitive_variables decorator was used, so take note
+ # of the sensitive variables' names.
+ wrapper = current_frame.f_locals["sensitive_variables_wrapper"]
+ sensitive_variables = getattr(wrapper, "sensitive_variables", None)
+ break
+ current_frame = current_frame.f_back
cleansed = {}
if self.is_active(request) and sensitive_variables: