Skip to content

Commit 8047318

Browse files
committed
fix: validate current step before on submit
Inspired by jazzband#224 Thank you @jsma
1 parent a60dbd9 commit 8047318

3 files changed

Lines changed: 26 additions & 2 deletions

File tree

formtools/wizard/forms.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,21 @@
11
from django import forms
2+
from django.core.exceptions import ValidationError
23

34

45
class ManagementForm(forms.Form):
56
"""
67
``ManagementForm`` is used to keep track of the current wizard step.
78
"""
9+
810
template_name = "django/forms/p.html" # Remove when Django 5.0 is minimal version.
911
current_step = forms.CharField(widget=forms.HiddenInput)
12+
13+
def __init__(self, steps, **kwargs):
14+
self.steps = steps
15+
super().__init__(**kwargs)
16+
17+
def clean_current_step(self):
18+
value = self.cleaned_data["current_step"]
19+
if value not in self.steps:
20+
raise ValidationError("Invalid step name.")
21+
return value

formtools/wizard/views.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ def post(self, *args, **kwargs):
283283
return self.render_goto_step(wizard_goto_step)
284284

285285
# Check if form was refreshed
286-
management_form = ManagementForm(self.request.POST, prefix=self.prefix)
286+
management_form = ManagementForm(steps=self.steps.all, self.request.POST, prefix=self.prefix)
287287
if not management_form.is_valid():
288288
raise SuspiciousOperation(_('ManagementForm data is missing or has been tampered.'))
289289

@@ -582,7 +582,7 @@ def get_context_data(self, form, **kwargs):
582582
context['wizard'] = {
583583
'form': form,
584584
'steps': self.steps,
585-
'management_form': ManagementForm(prefix=self.prefix, initial={
585+
'management_form': ManagementForm(steps=self.steps.all, prefix=self.prefix, initial={
586586
'current_step': self.steps.current,
587587
}),
588588
}

tests/wizard/wizardtests/tests.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,18 @@ def test_form_post_mgmt_data_missing(self):
7373
# view should return HTTP 400 Bad Request
7474
self.assertEqual(response.status_code, 400)
7575

76+
def test_invalid_current_step_data(self):
77+
wizard_step_data = self.wizard_step_data[0].copy()
78+
79+
# Replace the current step with invalid data
80+
for key in list(wizard_step_data.keys()):
81+
if "current_step" in key:
82+
wizard_step_data[key] = "not-a-valid-step"
83+
84+
response = self.client.post(self.wizard_url, wizard_step_data)
85+
# view should return HTTP 400 Bad Request
86+
self.assertEqual(response.status_code, 400)
87+
7688
def test_form_post_success(self):
7789
response = self.client.post(self.wizard_url, self.wizard_step_data[0])
7890
wizard = response.context['wizard']

0 commit comments

Comments
 (0)