From e1378ccd17b10739f66da4c676cdcb27782559ff Mon Sep 17 00:00:00 2001 From: Max Kolyubyakin Date: Fri, 26 Jun 2020 11:11:30 +0300 Subject: [PATCH] LITE-14144 Compatibility Backends are now less error-prone. All manual parsing errors will be caught by try/except block. --- dj_rql/drf/compat.py | 14 ++++++++++---- tests/test_drf/test_django_filters_backend.py | 14 ++++++++++++++ 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/dj_rql/drf/compat.py b/dj_rql/drf/compat.py index 033beff..c998d97 100644 --- a/dj_rql/drf/compat.py +++ b/dj_rql/drf/compat.py @@ -29,12 +29,18 @@ class CompatibilityRQLFilterBackend(RQLFilterBackend): """ @classmethod def get_query(cls, filter_instance, request, view): - query_string = cls.modify_initial_query(filter_instance, request, get_query(request)) + try: + query_string = cls.modify_initial_query(filter_instance, request, get_query(request)) - if not cls.is_old_syntax(filter_instance, request, query_string): - return query_string + if not cls.is_old_syntax(filter_instance, request, query_string): + return query_string - return cls.get_rql_query(filter_instance, request, query_string) + else: + return cls.get_rql_query(filter_instance, request, query_string) + except Exception: + raise RQLFilterParsingError(details={ + 'error': 'Bad filter query.', + }) @classmethod def modify_initial_query(cls, filter_instance, request, query_string): diff --git a/tests/test_drf/test_django_filters_backend.py b/tests/test_drf/test_django_filters_backend.py index 0851a3e..a285b42 100644 --- a/tests/test_drf/test_django_filters_backend.py +++ b/tests/test_drf/test_django_filters_backend.py @@ -76,6 +76,20 @@ def test_old_syntax_filters(mocker): assert filter_instance.old_syntax_filters == {'t__in'} +def test_bad_syntax_query(mocker): + query = 'limit=10&offset=0&in=(prop,(val1,val2))&in(prop.prop,(val))' \ + '&ge=(created,2020-06-01T04:00:00Z)&le=(created,2020-06-24T03:59:59Z)' + request = mocker.MagicMock( + query_params=QueryDict(query), + _request=mocker.MagicMock(META={'QUERY_STRING': query}), + ) + filter_instance = BooksFilterClass(Book.objects.none()) + mocker.patch('dj_rql.drf.compat.DjangoFiltersRQLFilterBackend.is_old_syntax', return_value=True) + + with pytest.raises(RQLFilterParsingError): + assert DjangoFiltersRQLFilterBackend.get_query(filter_instance, request, None) + + @pytest.mark.parametrize('query', ( 'select(books)&k__in=v,v', 'k__in=v,v&select(books)', ))