123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051 |
- import json
- from django import forms
- from django.core import signing
- from django.core.exceptions import ValidationError
- from django.utils.encoding import force_str
- class SignedDataForm(forms.Form):
- """Helper form that wraps a form to validate its contents on post.
- class PanelForm(forms.Form):
- # fields
- On render:
- form = SignedDataForm(initial=PanelForm(initial=data).initial)
- On POST:
- signed_form = SignedDataForm(request.POST)
- if signed_form.is_valid():
- panel_form = PanelForm(signed_form.verified_data)
- if panel_form.is_valid():
- # Success
- """
- salt = "django_debug_toolbar"
- signed = forms.CharField(required=True, widget=forms.HiddenInput)
- def __init__(self, *args, **kwargs):
- initial = kwargs.pop("initial", None)
- if initial:
- initial = {"signed": self.sign(initial)}
- super().__init__(*args, initial=initial, **kwargs)
- def clean_signed(self):
- try:
- verified = json.loads(
- signing.Signer(salt=self.salt).unsign(self.cleaned_data["signed"])
- )
- return verified
- except signing.BadSignature:
- raise ValidationError("Bad signature")
- def verified_data(self):
- return self.is_valid() and self.cleaned_data["signed"]
- @classmethod
- def sign(cls, data):
- return signing.Signer(salt=cls.salt).sign(
- json.dumps({key: force_str(value) for key, value in data.items()})
- )
|