raise validation error on bad lang request values (#20438)
* escape (incorrect) lang request values in the response * raise validation error for a bad locale code * different test for flat translation reponses * return bad lang value without escaping * Update overview.rst
This commit is contained in:
Родитель
11d492f881
Коммит
906739fd38
|
@ -193,6 +193,11 @@ For example, for a request ``?lang=de``:
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
.. warning::
|
||||
``lang`` must only contains alphanumeric characters (plus ``-`` and ``_``).
|
||||
|
||||
|
||||
For ``POST``, ``PATCH`` and ``PUT`` requests you submit an object containing
|
||||
translations for any languages needing to be updated/saved. Any language not
|
||||
in the object is not updated, but is not removed.
|
||||
|
@ -452,7 +457,7 @@ These are `v5` specific changes - `v4` changes apply also.
|
|||
* 2023-03-02: added specific HTTP 409 status code for add-on/version submissions that already exist
|
||||
* 2023-03-02: added support for calling the version detail endpoint using a version number instead of an ``id``.
|
||||
* 2023-03-09: added ``is_disabled`` to version detail and update endpoints, for authenticated developers and revieweers. https://github.com/mozilla/addons-server/issues/20142
|
||||
|
||||
* 2023-03-08: restricted ``lang`` parameter to only alphanumeric, ``_``, ``-``. https://github.com/mozilla/addons-server/issues/20452
|
||||
|
||||
.. _`#11380`: https://github.com/mozilla/addons-server/issues/11380/
|
||||
.. _`#11379`: https://github.com/mozilla/addons-server/issues/11379/
|
||||
|
|
|
@ -16,6 +16,9 @@ from olympia.translations.models import Translation
|
|||
from olympia.translations.utils import default_locale
|
||||
|
||||
|
||||
LANGUAGE_CODE_REGEX = r'[\w-]+'
|
||||
|
||||
|
||||
class ReverseChoiceField(fields.ChoiceField):
|
||||
"""
|
||||
A ChoiceField that exposes the "human-readable" values of its choices,
|
||||
|
@ -108,8 +111,10 @@ class TranslationSerializerField(fields.CharField):
|
|||
|
||||
def get_requested_language(self):
|
||||
request = self.context.get('request', None)
|
||||
if request and request.method == 'GET' and 'lang' in request.GET:
|
||||
return request.GET['lang']
|
||||
if request and request.method == 'GET' and (lang := request.GET.get('lang')):
|
||||
if not self.flat and not re.fullmatch(LANGUAGE_CODE_REGEX, lang):
|
||||
self.fail('unknown_locale', lang_code=lang)
|
||||
return lang
|
||||
else:
|
||||
return None
|
||||
|
||||
|
|
|
@ -341,6 +341,16 @@ class TestTranslationSerializerField(TestCase):
|
|||
result = field.to_representation(field.get_attribute(self.addon))
|
||||
assert result is None
|
||||
|
||||
def test_invalid_lang_value_raises_valiation_error(self):
|
||||
bad_lang = 'en-US<foo>;'
|
||||
request = Request(self.factory.get('/', {'lang': bad_lang}))
|
||||
mock_serializer = serializers.Serializer(context={'request': request})
|
||||
field = self.field_class()
|
||||
field.bind('name', mock_serializer)
|
||||
with self.assertRaises(serializers.ValidationError) as exc:
|
||||
field.to_representation(field.get_attribute(self.addon))
|
||||
assert exc.exception.detail == [f'The language code "{bad_lang}" is invalid.']
|
||||
|
||||
|
||||
@override_settings(DRF_API_GATES={None: ('l10n_flat_input_output',)})
|
||||
class TestTranslationSerializerFieldFlat(TestTranslationSerializerField):
|
||||
|
@ -366,6 +376,17 @@ class TestTranslationSerializerFieldFlat(TestTranslationSerializerField):
|
|||
result = field.run_validation(data['fr'])
|
||||
assert result == data['fr']
|
||||
|
||||
def test_invalid_lang_value_raises_valiation_error(self):
|
||||
# The flat API response doesn't return the lang value at all, so doesn't raise
|
||||
request = Request(
|
||||
self.factory.get('/', {'lang': 'en-USf<script>alert(1)</script>'})
|
||||
)
|
||||
mock_serializer = serializers.Serializer(context={'request': request})
|
||||
field = self.field_class()
|
||||
field.bind('name', mock_serializer)
|
||||
result = field.to_representation(field.get_attribute(self.addon))
|
||||
assert 'script' not in result
|
||||
|
||||
|
||||
class TestESTranslationSerializerField(TestTranslationSerializerField):
|
||||
field_class = ESTranslationSerializerField
|
||||
|
|
Загрузка…
Ссылка в новой задаче