Skip to content

Commit

Permalink
[#2648] handle legacy case detail URLs with redirect
Browse files Browse the repository at this point in the history
The case detail URL now contains a reference to the
ZGW api group to be used to fetch the case. It is quite
likely there are various hard-coded URLs in the wild
(especially in notification emails) that point to the
old case detail URLs. This commit adds a redirect
handler for the now-deprecated case detail URL and
tries to handle the request gracefully, depending on
the case.
  • Loading branch information
swrichards committed Aug 5, 2024
1 parent 1edaef7 commit af0030c
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 1 deletion.
11 changes: 11 additions & 0 deletions src/open_inwoner/cms/cases/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
CaseDocumentUploadFormView,
InnerCaseDetailView,
InnerCaseListView,
LegacyCaseDetailHandler,
OuterCaseDetailView,
OuterCaseListView,
)
Expand Down Expand Up @@ -61,4 +62,14 @@
),
path("content/", InnerCaseListView.as_view(), name="cases_content"),
path("", OuterCaseListView.as_view(), name="index"),
# Legacy redirects for hard-coded case detail urls lacking a ZGW api group reference
# in the url (e.g. from old notification mails). This redirects those URLs
# to the new case detail URL with a reference to the only ZGW api group (if 1),
# or the case list page with an expiration notice (because we can't be sure which
# api group to use).
path(
"<str:object_id>/status/",
LegacyCaseDetailHandler.as_view(),
name="legacy_case_detail",
),
]
2 changes: 2 additions & 0 deletions src/open_inwoner/cms/cases/views/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
CaseDocumentDownloadView,
CaseDocumentUploadFormView,
InnerCaseDetailView,
LegacyCaseDetailHandler,
OuterCaseDetailView,
)

Expand All @@ -14,5 +15,6 @@
"CaseDocumentDownloadView",
"CaseDocumentUploadFormView",
"InnerCaseDetailView",
"LegacyCaseDetailHandler",
"OuterCaseDetailView",
]
46 changes: 45 additions & 1 deletion src/open_inwoner/cms/cases/views/status.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from django.conf import settings
from django.contrib import messages
from django.core.exceptions import ObjectDoesNotExist, PermissionDenied
from django.http import Http404, StreamingHttpResponse
from django.http import Http404, HttpResponseRedirect, StreamingHttpResponse
from django.urls import reverse
from django.utils.functional import cached_property
from django.utils.translation import gettext_lazy as _
Expand Down Expand Up @@ -1029,3 +1029,47 @@ def get_context_data(self, **kwargs):
"cases:case_detail_contact_form", kwargs=self.kwargs
)
return context


class LegacyCaseDetailHandler(View):
"""Redirect the legacy case detail to the current version with ZGW API group ref."""

def get(
self,
request,
object_id: str,
):
redirect_url = None
match ZGWApiGroupConfig.objects.count():
case 1:
target_api_group = ZGWApiGroupConfig.objects.get()
redirect_url = reverse(
"cases:case_detail",
kwargs={
"api_group_id": target_api_group.id,
"object_id": object_id,
},
)
case count if count > 1:
# Note that this is the tricky branch: we generally assume that
# legacy URLs will point to the oldest (=lowest pk) API group and
# redirect to that, but we have no guarantees (e.g. if groups were
# added and removed).
messages.add_message(
request,
messages.ERROR,
_(
"The link you've used has expired. Please find the case you are looking for below."
),
)
logger.warning(
"Multiple API groups configured, redirecting to first option"
)
redirect_url = reverse("cases:index")
case 0:
logger.error(
"Legacy redirect invoked without any configured API groups"
)
raise Http404

return HttpResponseRedirect(redirect_url)
73 changes: 73 additions & 0 deletions src/open_inwoner/openzaak/tests/test_case_detail_redirects.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
from django.contrib.messages import get_messages
from django.test import TestCase, override_settings
from django.urls import reverse

from open_inwoner.openzaak.models import ZGWApiGroupConfig
from open_inwoner.openzaak.tests.factories import ZGWApiGroupConfigFactory


@override_settings(
ROOT_URLCONF="open_inwoner.cms.tests.urls",
)
class LegacyCaseDetailUrlRedirectTest(TestCase):
def setUp(self):
self.url_patterns = [
"case_detail",
]

def test_legacy_url_redirects_to_only_api_group_prefix(self):
first = ZGWApiGroupConfigFactory()

object_id = "test_object_id"
legacy_handler_url = reverse(
"cases:legacy_case_detail",
kwargs={"object_id": object_id},
)
target_url = reverse(
"cases:case_detail",
kwargs={"api_group_id": first.id, "object_id": object_id},
)

response = self.client.get(legacy_handler_url)
self.assertEqual(ZGWApiGroupConfig.objects.count(), 1)
self.assertEqual(response.status_code, 302)
self.assertEqual(response["Location"], target_url)

def test_legacy_url_redirects_to_case_list_if_multiple_api_groups(self):
ZGWApiGroupConfigFactory(), ZGWApiGroupConfigFactory()

object_id = "test_object_id"
legacy_handler_url = reverse(
"cases:legacy_case_detail",
kwargs={"object_id": object_id},
)
target_url = reverse("cases:index")

response = self.client.get(legacy_handler_url)
messages = [str(m) for m in get_messages(response.wsgi_request)]

self.assertEqual(ZGWApiGroupConfig.objects.count(), 2)
self.assertEqual(response.status_code, 302)
self.assertEqual(response["Location"], reverse("cases:index"))
self.assertEqual(
messages,
[
"The link you've used has expired. Please find the case you are looking for below."
],
)

def test_legacy_url_redirect_returns_404_on_missing_api_groups(self):
object_id = "test_object_id"
legacy_handler_url = reverse(
"cases:legacy_case_detail",
kwargs={"object_id": object_id},
)

legacy_handler_url = reverse(
"cases:legacy_case_detail",
kwargs={"object_id": object_id},
)

response = self.client.get(legacy_handler_url)
self.assertEqual(ZGWApiGroupConfig.objects.count(), 0)
self.assertEqual(response.status_code, 404)

0 comments on commit af0030c

Please sign in to comment.