From 3387ec032bf0ed715236865996d2b7cd8edc7be6 Mon Sep 17 00:00:00 2001 From: David Kennedy Date: Wed, 14 Feb 2024 12:09:27 -0500 Subject: [PATCH 1/2] handle logout when no session is present --- src/djangooidc/tests/test_views.py | 20 ++++++++++++++++++++ src/djangooidc/views.py | 6 +++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/djangooidc/tests/test_views.py b/src/djangooidc/tests/test_views.py index 4cd2241e3..462917947 100644 --- a/src/djangooidc/tests/test_views.py +++ b/src/djangooidc/tests/test_views.py @@ -327,6 +327,26 @@ def test_logout_redirect_url(self, mock_client): self.assertEqual(response.status_code, 302) self.assertEqual(actual, expected) + def test_logout_redirect_url_with_no_session_state(self, mock_client): + """Test that logout redirects to the configured post_logout_redirect_uris.""" + with less_console_noise(): + # MOCK + mock_client.callback.side_effect = self.user_info + mock_client.registration_response = {"post_logout_redirect_uris": ["http://example.com/back"]} + mock_client.provider_info = {"end_session_endpoint": "http://example.com/log_me_out"} + mock_client.client_id = "TEST" + # TEST + with less_console_noise(): + response = self.client.get(reverse("logout")) + # ASSERTIONS + expected = ( + "http://example.com/log_me_out?client_id=TEST" + "&post_logout_redirect_uri=http%3A%2F%2Fexample.com%2Fback" + ) + actual = response.url + self.assertEqual(response.status_code, 302) + self.assertEqual(actual, expected) + @patch("djangooidc.views.auth_logout") def test_logout_always_logs_out(self, mock_logout, _): """Without additional mocking, logout will always fail. diff --git a/src/djangooidc/views.py b/src/djangooidc/views.py index 444b8b950..2d3c842d2 100644 --- a/src/djangooidc/views.py +++ b/src/djangooidc/views.py @@ -145,8 +145,12 @@ def logout(request, next_page=None): user = request.user request_args = { "client_id": CLIENT.client_id, - "state": request.session["state"], } + # if state is not in request session, still redirect to the identity + # provider's logout url, but don't include the state in the url; this + # will successfully log out of the identity provider + if "state" in request.session: + request_args["state"] = request.session["state"] if ( "post_logout_redirect_uris" in CLIENT.registration_response.keys() and len(CLIENT.registration_response["post_logout_redirect_uris"]) > 0 From f5a1348ccb51546dad370c3ab91c58eb4fba705c Mon Sep 17 00:00:00 2001 From: David Kennedy Date: Wed, 14 Feb 2024 17:11:55 -0500 Subject: [PATCH 2/2] updated comment --- src/djangooidc/tests/test_views.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/djangooidc/tests/test_views.py b/src/djangooidc/tests/test_views.py index 462917947..0f734b80d 100644 --- a/src/djangooidc/tests/test_views.py +++ b/src/djangooidc/tests/test_views.py @@ -339,6 +339,7 @@ def test_logout_redirect_url_with_no_session_state(self, mock_client): with less_console_noise(): response = self.client.get(reverse("logout")) # ASSERTIONS + # Assert redirect code and url are accurate expected = ( "http://example.com/log_me_out?client_id=TEST" "&post_logout_redirect_uri=http%3A%2F%2Fexample.com%2Fback"