diff --git a/config/settings/base.py b/config/settings/base.py index 9aac46d0..b918b019 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -102,6 +102,7 @@ "django.contrib.messages.middleware.MessageMiddleware", "django.middleware.clickjacking.XFrameOptionsMiddleware", "lacommunaute.utils.middleware.ParkingPageMiddleware", + "lacommunaute.openid_connect.middleware.ProConnectLoginMiddleware", ] THIRD_PARTIES_MIDDLEWARE = [ diff --git a/lacommunaute/openid_connect/middleware.py b/lacommunaute/openid_connect/middleware.py new file mode 100644 index 00000000..16187344 --- /dev/null +++ b/lacommunaute/openid_connect/middleware.py @@ -0,0 +1,23 @@ +from django.http import HttpResponseRedirect +from django.urls import reverse +from django.utils.deprecation import MiddlewareMixin +from django.utils.http import urlencode + + +class ProConnectLoginMiddleware(MiddlewareMixin): + def process_request(self, request): + if "proconnect_login" not in request.GET: + return + + query_params = request.GET.copy() + query_params.pop("proconnect_login") + new_url = ( + f"{request.path}?{urlencode({k: v for k, v in query_params.items() if v})}" + if query_params + else request.path + ) + + if not request.user.is_authenticated: + return HttpResponseRedirect(reverse("openid_connect:authorize") + f"?next={new_url}") + + return HttpResponseRedirect(new_url) diff --git a/lacommunaute/openid_connect/tests/test_middleware.py b/lacommunaute/openid_connect/tests/test_middleware.py new file mode 100644 index 00000000..082ccf4f --- /dev/null +++ b/lacommunaute/openid_connect/tests/test_middleware.py @@ -0,0 +1,50 @@ +import pytest +from django.urls import reverse +from pytest_django.asserts import assertRedirects, assertTemplateUsed + +from lacommunaute.users.factories import UserFactory + + +@pytest.mark.parametrize( + "params,expected", + [ + ("?proconnect_login=true", ""), + ("?proconnect_login=true¶m=1", "?param=1"), + ("?param=1&proconnect_login=true", "?param=1"), + ], +) +def test_redirect_for_authenticated_user(client, db, params, expected): + client.force_login(UserFactory()) + response = client.get(f"/{params}") + assertRedirects(response, f"/{expected}") + + +@pytest.mark.parametrize( + "params,expected", + [ + ("?proconnect_login=true", "/"), + ("?proconnect_login=true¶m=1", "/?param=1"), + ("?param=1&proconnect_login=true", "/?param=1"), + ], +) +def test_redirect_for_anonymous_user(client, db, params, expected): + response = client.get(f"/{params}") + assertRedirects(response, f"{reverse('openid_connect:authorize')}?next={expected}", fetch_redirect_response=False) + + +@pytest.mark.parametrize( + "params, logged", + [ + ("", True), + ("?param=1", True), + ("?param=1&key=2", True), + ("", False), + ("?param=1", False), + ("?param=1&key=2", False), + ], +) +def test_wo_proconnect_login_param(client, db, logged, params): + if logged: + client.force_login(UserFactory()) + response = client.get(f"/{params}") + assertTemplateUsed(response, "pages/home.html")