Skip to content

Commit 8d39876

Browse files
authored
Merge branch 'main' into render-panels-rework
2 parents dc3f80b + 085f8dd commit 8d39876

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+728
-385
lines changed

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,4 +216,4 @@ jobs:
216216
python -m pip install --upgrade tox
217217
218218
- name: Test with tox
219-
run: tox -e docs,style,readme
219+
run: tox -e docs,style,packaging

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
*.pyc
22
*.DS_Store
33
*~
4+
.idea
45
build
56
.coverage
67
dist

Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@ style: package-lock.json
88
flake8
99
npx eslint --ignore-path .gitignore --fix .
1010
npx prettier --ignore-path .gitignore --write $(PRETTIER_TARGETS)
11+
! grep -r '\(style=\|onclick=\|<script>\|<style\)' debug_toolbar/templates/
1112

1213
style_check: package-lock.json
1314
isort -c .
1415
black --target-version=py36 --check .
1516
flake8
1617
npx eslint --ignore-path .gitignore .
1718
npx prettier --ignore-path .gitignore --check $(PRETTIER_TARGETS)
19+
! grep -r '\(style=\|onclick=\|<script>\|<style\)' debug_toolbar/templates/
1820

1921
example:
2022
python example/manage.py migrate --noinput

README.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ Here's a screenshot of the toolbar in action:
3434
In addition to the built-in panels, a number of third-party panels are
3535
contributed by the community.
3636

37-
The current stable version of the Debug Toolbar is 3.2. It works on
37+
The current stable version of the Debug Toolbar is 3.2.1. It works on
3838
Django ≥ 2.2.
3939

4040
Documentation, including installation and configuration instructions, is

debug_toolbar/__init__.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1+
import django
2+
13
__all__ = ["VERSION"]
24

35

46
# Do not use pkg_resources to find the version but set it here directly!
57
# see issue #1446
6-
VERSION = "3.2"
8+
VERSION = "3.2.1"
79

810
# Code that discovers files or modules in INSTALLED_APPS imports this module.
911

1012
urls = "debug_toolbar.toolbar", "djdt"
1113

12-
default_app_config = "debug_toolbar.apps.DebugToolbarConfig"
14+
if django.VERSION < (3, 2):
15+
default_app_config = "debug_toolbar.apps.DebugToolbarConfig"

debug_toolbar/decorators.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import functools
22

3-
from django.http import Http404
3+
from django.http import Http404, HttpResponseBadRequest
44

55

66
def require_show_toolbar(view):
@@ -15,3 +15,21 @@ def inner(request, *args, **kwargs):
1515
return view(request, *args, **kwargs)
1616

1717
return inner
18+
19+
20+
def signed_data_view(view):
21+
"""Decorator that handles unpacking a signed data form"""
22+
23+
@functools.wraps(view)
24+
def inner(request, *args, **kwargs):
25+
from debug_toolbar.forms import SignedDataForm
26+
27+
data = request.GET if request.method == "GET" else request.POST
28+
signed_form = SignedDataForm(data)
29+
if signed_form.is_valid():
30+
return view(
31+
request, *args, verified_data=signed_form.verified_data(), **kwargs
32+
)
33+
return HttpResponseBadRequest("Invalid signature")
34+
35+
return inner

debug_toolbar/forms.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import json
2+
3+
from django import forms
4+
from django.core import signing
5+
from django.core.exceptions import ValidationError
6+
from django.utils.encoding import force_str
7+
8+
9+
class SignedDataForm(forms.Form):
10+
"""Helper form that wraps a form to validate its contents on post.
11+
12+
class PanelForm(forms.Form):
13+
# fields
14+
15+
On render:
16+
form = SignedDataForm(initial=PanelForm(initial=data).initial)
17+
18+
On POST:
19+
signed_form = SignedDataForm(request.POST)
20+
if signed_form.is_valid():
21+
panel_form = PanelForm(signed_form.verified_data)
22+
if panel_form.is_valid():
23+
# Success
24+
Or wrap the FBV with ``debug_toolbar.decorators.signed_data_view``
25+
"""
26+
27+
salt = "django_debug_toolbar"
28+
signed = forms.CharField(required=True, widget=forms.HiddenInput)
29+
30+
def __init__(self, *args, **kwargs):
31+
initial = kwargs.pop("initial", None)
32+
if initial:
33+
initial = {"signed": self.sign(initial)}
34+
super().__init__(*args, initial=initial, **kwargs)
35+
36+
def clean_signed(self):
37+
try:
38+
verified = json.loads(
39+
signing.Signer(salt=self.salt).unsign(self.cleaned_data["signed"])
40+
)
41+
return verified
42+
except signing.BadSignature:
43+
raise ValidationError("Bad signature")
44+
45+
def verified_data(self):
46+
return self.is_valid() and self.cleaned_data["signed"]
47+
48+
@classmethod
49+
def sign(cls, data):
50+
items = sorted(data.items(), key=lambda item: item[0])
51+
return signing.Signer(salt=cls.salt).sign(
52+
json.dumps({key: force_str(value) for key, value in items})
53+
)
606 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)