diff --git a/kitsune/questions/forms.py b/kitsune/questions/forms.py index b53e36c49ed..ca919db60f8 100644 --- a/kitsune/questions/forms.py +++ b/kitsune/questions/forms.py @@ -186,6 +186,24 @@ def clean_content(self): raise forms.ValidationError(_("Question content cannot be empty.")) return content + def clean_troubleshooting(self): + troubleshooting = self.cleaned_data.get("troubleshooting", "") + if not troubleshooting: + return troubleshooting + + try: + parsed = json.loads(troubleshooting) + except ValueError: + parsed = None + + if not isinstance(parsed, dict): + # L10n: An error shown when troubleshooting information isn't a JSON object. + raise forms.ValidationError( + _("Troubleshooting information must be a valid JSON object.") + ) + + return troubleshooting + @property def metadata_field_keys(self): """Returns the keys of the metadata fields for the current @@ -214,7 +232,7 @@ def cleaned_metadata(self): except ValueError: parsed = None - if parsed: + if isinstance(parsed, dict): # Clean out unwanted garbage preferences. if "modifiedPreferences" in parsed and isinstance( parsed["modifiedPreferences"], dict diff --git a/kitsune/questions/tests/test_forms.py b/kitsune/questions/tests/test_forms.py index c4935066949..a09fa30247a 100644 --- a/kitsune/questions/tests/test_forms.py +++ b/kitsune/questions/tests/test_forms.py @@ -123,6 +123,29 @@ def test_cleaned_metadata(self): actual = form.cleaned_metadata self.assertDictEqual(actual, expected) + def test_invalid_troubleshooting_json(self): + """Troubleshooting information must be a valid JSON object.""" + topic = TopicFactory(slug="cookies", products=[self.product], in_aaq=True) + base_data = { + "title": "Test question", + "content": "Test question content", + "email": "t@t.com", + "category": topic.id, + } + + for troubleshooting in ("[1,2,3]", "123", "true", '"hello"', "not json"): + with self.subTest(troubleshooting=troubleshooting): + form = NewQuestionForm( + product=self.product, + data={**base_data, "troubleshooting": troubleshooting}, + ) + + self.assertFalse(form.is_valid()) + self.assertEqual( + "Troubleshooting information must be a valid JSON object.", + form.errors["troubleshooting"][0], + ) + def test_clean_content_with_html_entities(self): """Test that content with only HTML entities is rejected.""" topic = TopicFactory(slug="cookies", products=[self.product], in_aaq=True)