From f2e8c84cdcbc0709cbfa4efe41c668d3bb99539c Mon Sep 17 00:00:00 2001 From: Ali Hassan Date: Fri, 10 Mar 2023 14:59:27 +0500 Subject: [PATCH 1/4] Refactor questionnaire API URLs --- iogt/middleware.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/iogt/middleware.py b/iogt/middleware.py index c2593a4ae..60194136c 100644 --- a/iogt/middleware.py +++ b/iogt/middleware.py @@ -3,7 +3,7 @@ from django.conf import settings from django.conf.urls.i18n import is_language_prefix_patterns_used from django.core.cache import cache -from django.http.response import HttpResponsePermanentRedirect +from django.http.response import HttpResponsePermanentRedirect, HttpResponseNotFound from django.middleware.locale import LocaleMiddleware as DjangoLocaleMiddleware from django.utils import translation from django.utils.deprecation import MiddlewareMixin @@ -87,14 +87,19 @@ def process_response(self, request, response): This custom middleware is written to mitigate broken links from IOGT v1. See https://github.com/unicef/iogt/issues/850 for more details. """ + return_value = super().process_response(request, response) # If the page is not found by wagtail RedirectMiddleware, look for the page in V1PageURLToV2PageMap. # If you find the page, redirect the user to the new page. if return_value.status_code == 404: url = unquote(request.get_full_path()) - page = V1PageURLToV2PageMap.get_page_or_none(url) + if url.startswith('/en/api/'): + return HttpResponseNotFound( + f"Sorry, the requested resource was not found. Please refer to the API documentation." + ) + page = V1PageURLToV2PageMap.get_page_or_none(url) if page: return HttpResponsePermanentRedirect(page.url) From 65f455cec74af22342e70260262412a1dc395684 Mon Sep 17 00:00:00 2001 From: Ali Hassan Date: Mon, 13 Mar 2023 12:07:13 +0500 Subject: [PATCH 2/4] refactor locale middleware --- iogt/middleware.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/iogt/middleware.py b/iogt/middleware.py index 60194136c..8be254fab 100644 --- a/iogt/middleware.py +++ b/iogt/middleware.py @@ -72,6 +72,12 @@ def process_request(self, request): translation.activate(language) request.LANGUAGE_CODE = translation.get_language() + def process_response(self, request, response): + if request.path.startswith('/api/'): + return response + + return super(LocaleMiddleware, self).process_response(request, response) + class AdminLocaleMiddleware(MiddlewareMixin): """Ensures that the admin locale doesn't change with user selection""" @@ -94,7 +100,7 @@ def process_response(self, request, response): # If you find the page, redirect the user to the new page. if return_value.status_code == 404: url = unquote(request.get_full_path()) - if url.startswith('/en/api/'): + if url.startswith('/api/'): return HttpResponseNotFound( f"Sorry, the requested resource was not found. Please refer to the API documentation." ) From 3bd48476cdac66191d724b4dc8b54cdaf5366ad2 Mon Sep 17 00:00:00 2001 From: Ali Hassan Date: Mon, 13 Mar 2023 12:31:20 +0500 Subject: [PATCH 3/4] Update unit test --- questionnaires/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/questionnaires/tests.py b/questionnaires/tests.py index 46054eea8..58051a16d 100644 --- a/questionnaires/tests.py +++ b/questionnaires/tests.py @@ -404,7 +404,7 @@ def test_questionnaires_detail_page_permission(self): poll_question = PollFormFieldFactory(page=poll, field_type='checkboxes', choices='c1|c2|c3', default_value='c2') response = self.client.get(reverse(self.url, kwargs={'pk': poll.id})) - self.assertEqual(response.status_code, status.HTTP_302_FOUND) + self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) class QuestionnaireSubmissionsAPIViewTests(TestCase): From 0324dd40947f04da37f053d6ad103a7cae4c815b Mon Sep 17 00:00:00 2001 From: Ali Hassan Date: Mon, 13 Mar 2023 15:35:10 +0500 Subject: [PATCH 4/4] adds comments --- iogt/middleware.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/iogt/middleware.py b/iogt/middleware.py index 8be254fab..7c6984bdf 100644 --- a/iogt/middleware.py +++ b/iogt/middleware.py @@ -73,10 +73,15 @@ def process_request(self, request): request.LANGUAGE_CODE = translation.get_language() def process_response(self, request, response): - if request.path.startswith('/api/'): + """ + The purpose of this condition is to prevent the middleware from interfering with API endpoints (/api) that + return a 404 error. This can happen if the middleware tries to set the language for a request to an API endpoint + (/api) that does not have a translated version, which can result in unexpected behavior or errors. + """ + if request.path.startswith('/api') and response.status_code == 404: return response - return super(LocaleMiddleware, self).process_response(request, response) + return super().process_response(request, response) class AdminLocaleMiddleware(MiddlewareMixin): @@ -100,7 +105,12 @@ def process_response(self, request, response): # If you find the page, redirect the user to the new page. if return_value.status_code == 404: url = unquote(request.get_full_path()) - if url.startswith('/api/'): + """ + This is used as a safeguard to prevent broken links from causing problems in the API. If a user tries to + access a URL that starts with '/api' and the page is not found, the middleware will return a custom message + with a link to the API documentation instead of raising an exception or showing a default 404 error page. + """ + if url.startswith('/api'): return HttpResponseNotFound( f"Sorry, the requested resource was not found. Please refer to the API documentation." )