authentik.providers.saml.tests.test_tasks
Tests for SAML provider tasks
1"""Tests for SAML provider tasks""" 2 3from unittest.mock import MagicMock, patch 4 5from django.test import TestCase 6from requests.exceptions import ConnectionError, HTTPError 7 8from authentik.common.saml.constants import SAML_NAME_ID_FORMAT_EMAIL 9from authentik.core.tests.utils import create_test_cert, create_test_flow 10from authentik.providers.saml.models import SAMLProvider 11from authentik.providers.saml.tasks import ( 12 send_post_logout_request, 13 send_saml_logout_request, 14 send_saml_logout_response, 15) 16 17 18class TestSendSamlLogoutResponse(TestCase): 19 """Tests for send_saml_logout_response task""" 20 21 def setUp(self): 22 """Set up test fixtures""" 23 self.cert = create_test_cert() 24 self.flow = create_test_flow() 25 26 self.provider = SAMLProvider.objects.create( 27 name="test-provider", 28 authorization_flow=self.flow, 29 acs_url="https://sp.example.com/acs", 30 sls_url="https://sp.example.com/sls", 31 issuer_override="https://idp.example.com", 32 signing_kp=self.cert, 33 ) 34 35 @patch("authentik.providers.saml.tasks.requests.post") 36 def test_successful_logout_response(self, mock_post): 37 """Test successful POST to SP returns True""" 38 mock_response = MagicMock() 39 mock_response.status_code = 200 40 mock_response.raise_for_status = MagicMock() 41 mock_post.return_value = mock_response 42 43 result = send_saml_logout_response( 44 provider_pk=self.provider.pk, 45 sls_url=self.provider.sls_url, 46 logout_request_id="test-request-id", 47 relay_state="https://sp.example.com/return", 48 ) 49 50 self.assertTrue(result) 51 mock_post.assert_called_once() 52 53 # Verify the POST was made with correct data 54 call_kwargs = mock_post.call_args[1] 55 self.assertEqual(call_kwargs["timeout"], 10) 56 self.assertEqual( 57 call_kwargs["headers"]["Content-Type"], "application/x-www-form-urlencoded" 58 ) 59 60 # Verify form data contains SAMLResponse and RelayState 61 form_data = call_kwargs["data"] 62 self.assertIn("SAMLResponse", form_data) 63 self.assertIn("RelayState", form_data) 64 self.assertEqual(form_data["RelayState"], "https://sp.example.com/return") 65 66 @patch("authentik.providers.saml.tasks.requests.post") 67 def test_successful_logout_response_no_relay_state(self, mock_post): 68 """Test successful POST without relay_state""" 69 mock_response = MagicMock() 70 mock_response.status_code = 200 71 mock_response.raise_for_status = MagicMock() 72 mock_post.return_value = mock_response 73 74 result = send_saml_logout_response( 75 provider_pk=self.provider.pk, 76 sls_url=self.provider.sls_url, 77 logout_request_id="test-request-id", 78 relay_state=None, 79 ) 80 81 self.assertTrue(result) 82 83 # Verify form data does not contain RelayState 84 form_data = mock_post.call_args[1]["data"] 85 self.assertIn("SAMLResponse", form_data) 86 self.assertNotIn("RelayState", form_data) 87 88 def test_provider_not_found(self): 89 """Test returns False when provider doesn't exist""" 90 result = send_saml_logout_response( 91 provider_pk=99999, # Non-existent provider 92 sls_url="https://sp.example.com/sls", 93 logout_request_id="test-request-id", 94 relay_state=None, 95 ) 96 97 self.assertFalse(result) 98 99 @patch("authentik.providers.saml.tasks.Event") 100 @patch("authentik.providers.saml.tasks.requests.post") 101 def test_http_error_creates_event(self, mock_post, mock_event_class): 102 """Test HTTP error creates an error event""" 103 mock_response = MagicMock() 104 mock_response.status_code = 500 105 mock_response.raise_for_status.side_effect = HTTPError("500 Server Error") 106 mock_post.return_value = mock_response 107 108 mock_event = MagicMock() 109 mock_event_class.new.return_value = mock_event 110 111 result = send_saml_logout_response( 112 provider_pk=self.provider.pk, 113 sls_url=self.provider.sls_url, 114 logout_request_id="test-request-id", 115 relay_state=None, 116 ) 117 118 self.assertFalse(result) 119 120 # Verify error event was created 121 mock_event_class.new.assert_called_once() 122 call_kwargs = mock_event_class.new.call_args[1] 123 self.assertIn("Backchannel logout response failed", call_kwargs["message"]) 124 mock_event.save.assert_called_once() 125 126 127class TestSendSamlLogoutRequest(TestCase): 128 """Tests for send_saml_logout_request task""" 129 130 def setUp(self): 131 """Set up test fixtures""" 132 self.cert = create_test_cert() 133 self.flow = create_test_flow() 134 135 self.provider = SAMLProvider.objects.create( 136 name="test-provider", 137 authorization_flow=self.flow, 138 acs_url="https://sp.example.com/acs", 139 sls_url="https://sp.example.com/sls", 140 issuer_override="https://idp.example.com", 141 signing_kp=self.cert, 142 ) 143 144 @patch("authentik.providers.saml.tasks.requests.post") 145 def test_successful_logout_request(self, mock_post): 146 """Test successful POST logout request returns True""" 147 mock_response = MagicMock() 148 mock_response.status_code = 200 149 mock_response.raise_for_status = MagicMock() 150 mock_post.return_value = mock_response 151 152 result = send_saml_logout_request( 153 provider_pk=self.provider.pk, 154 sls_url=self.provider.sls_url, 155 name_id="test@example.com", 156 name_id_format=SAML_NAME_ID_FORMAT_EMAIL, 157 session_index="test-session-123", 158 issuer="https://idp.example.com", 159 ) 160 161 self.assertTrue(result) 162 mock_post.assert_called_once() 163 164 # Verify the POST was made with correct data 165 call_kwargs = mock_post.call_args[1] 166 self.assertEqual(call_kwargs["timeout"], 10) 167 self.assertEqual( 168 call_kwargs["headers"]["Content-Type"], "application/x-www-form-urlencoded" 169 ) 170 171 # Verify form data contains SAMLRequest 172 form_data = call_kwargs["data"] 173 self.assertIn("SAMLRequest", form_data) 174 175 def test_provider_not_found(self): 176 """Test returns False when provider doesn't exist""" 177 result = send_saml_logout_request( 178 provider_pk=99999, # Non-existent provider 179 sls_url="https://sp.example.com/sls", 180 name_id="test@example.com", 181 name_id_format=SAML_NAME_ID_FORMAT_EMAIL, 182 session_index="test-session-123", 183 issuer="https://idp.example.com", 184 ) 185 186 self.assertFalse(result) 187 188 @patch("authentik.providers.saml.tasks.requests.post") 189 def test_http_error_raises(self, mock_post): 190 """Test HTTP error raises exception (no try/catch in send_post_logout_request)""" 191 mock_response = MagicMock() 192 mock_response.status_code = 500 193 mock_response.raise_for_status.side_effect = HTTPError("500 Server Error") 194 mock_post.return_value = mock_response 195 196 with self.assertRaises(HTTPError): 197 send_saml_logout_request( 198 provider_pk=self.provider.pk, 199 sls_url=self.provider.sls_url, 200 name_id="test@example.com", 201 name_id_format=SAML_NAME_ID_FORMAT_EMAIL, 202 session_index="test-session-123", 203 issuer="https://idp.example.com", 204 ) 205 206 207class TestSendPostLogoutRequest(TestCase): 208 """Tests for send_post_logout_request function""" 209 210 def setUp(self): 211 """Set up test fixtures""" 212 self.cert = create_test_cert() 213 self.flow = create_test_flow() 214 215 self.provider = SAMLProvider.objects.create( 216 name="test-provider", 217 authorization_flow=self.flow, 218 acs_url="https://sp.example.com/acs", 219 sls_url="https://sp.example.com/sls", 220 issuer_override="https://idp.example.com", 221 signing_kp=self.cert, 222 ) 223 224 @patch("authentik.providers.saml.tasks.requests.post") 225 def test_successful_post(self, mock_post): 226 """Test successful POST returns True""" 227 from authentik.providers.saml.processors.logout_request import LogoutRequestProcessor 228 229 mock_response = MagicMock() 230 mock_response.status_code = 200 231 mock_response.raise_for_status = MagicMock() 232 mock_post.return_value = mock_response 233 234 processor = LogoutRequestProcessor( 235 provider=self.provider, 236 user=None, 237 destination=self.provider.sls_url, 238 name_id="test@example.com", 239 name_id_format=SAML_NAME_ID_FORMAT_EMAIL, 240 session_index="test-session-123", 241 ) 242 243 result = send_post_logout_request(self.provider, processor) 244 245 self.assertTrue(result) 246 mock_post.assert_called_once() 247 248 @patch("authentik.providers.saml.tasks.requests.post") 249 def test_with_relay_state(self, mock_post): 250 """Test POST includes RelayState when present""" 251 from authentik.providers.saml.processors.logout_request import LogoutRequestProcessor 252 253 mock_response = MagicMock() 254 mock_response.status_code = 200 255 mock_response.raise_for_status = MagicMock() 256 mock_post.return_value = mock_response 257 258 processor = LogoutRequestProcessor( 259 provider=self.provider, 260 user=None, 261 destination=self.provider.sls_url, 262 name_id="test@example.com", 263 name_id_format=SAML_NAME_ID_FORMAT_EMAIL, 264 session_index="test-session-123", 265 relay_state="https://sp.example.com/return", 266 ) 267 268 result = send_post_logout_request(self.provider, processor) 269 270 self.assertTrue(result) 271 272 # Verify RelayState is included 273 form_data = mock_post.call_args[1]["data"] 274 self.assertIn("RelayState", form_data) 275 self.assertEqual(form_data["RelayState"], "https://sp.example.com/return") 276 277 @patch("authentik.providers.saml.tasks.requests.post") 278 def test_connection_error_raises(self, mock_post): 279 """Test connection error raises exception""" 280 from authentik.providers.saml.processors.logout_request import LogoutRequestProcessor 281 282 mock_post.side_effect = ConnectionError("Connection refused") 283 284 processor = LogoutRequestProcessor( 285 provider=self.provider, 286 user=None, 287 destination=self.provider.sls_url, 288 name_id="test@example.com", 289 name_id_format=SAML_NAME_ID_FORMAT_EMAIL, 290 session_index="test-session-123", 291 ) 292 293 with self.assertRaises(ConnectionError): 294 send_post_logout_request(self.provider, processor)
class
TestSendSamlLogoutResponse(django.test.testcases.TestCase):
19class TestSendSamlLogoutResponse(TestCase): 20 """Tests for send_saml_logout_response task""" 21 22 def setUp(self): 23 """Set up test fixtures""" 24 self.cert = create_test_cert() 25 self.flow = create_test_flow() 26 27 self.provider = SAMLProvider.objects.create( 28 name="test-provider", 29 authorization_flow=self.flow, 30 acs_url="https://sp.example.com/acs", 31 sls_url="https://sp.example.com/sls", 32 issuer_override="https://idp.example.com", 33 signing_kp=self.cert, 34 ) 35 36 @patch("authentik.providers.saml.tasks.requests.post") 37 def test_successful_logout_response(self, mock_post): 38 """Test successful POST to SP returns True""" 39 mock_response = MagicMock() 40 mock_response.status_code = 200 41 mock_response.raise_for_status = MagicMock() 42 mock_post.return_value = mock_response 43 44 result = send_saml_logout_response( 45 provider_pk=self.provider.pk, 46 sls_url=self.provider.sls_url, 47 logout_request_id="test-request-id", 48 relay_state="https://sp.example.com/return", 49 ) 50 51 self.assertTrue(result) 52 mock_post.assert_called_once() 53 54 # Verify the POST was made with correct data 55 call_kwargs = mock_post.call_args[1] 56 self.assertEqual(call_kwargs["timeout"], 10) 57 self.assertEqual( 58 call_kwargs["headers"]["Content-Type"], "application/x-www-form-urlencoded" 59 ) 60 61 # Verify form data contains SAMLResponse and RelayState 62 form_data = call_kwargs["data"] 63 self.assertIn("SAMLResponse", form_data) 64 self.assertIn("RelayState", form_data) 65 self.assertEqual(form_data["RelayState"], "https://sp.example.com/return") 66 67 @patch("authentik.providers.saml.tasks.requests.post") 68 def test_successful_logout_response_no_relay_state(self, mock_post): 69 """Test successful POST without relay_state""" 70 mock_response = MagicMock() 71 mock_response.status_code = 200 72 mock_response.raise_for_status = MagicMock() 73 mock_post.return_value = mock_response 74 75 result = send_saml_logout_response( 76 provider_pk=self.provider.pk, 77 sls_url=self.provider.sls_url, 78 logout_request_id="test-request-id", 79 relay_state=None, 80 ) 81 82 self.assertTrue(result) 83 84 # Verify form data does not contain RelayState 85 form_data = mock_post.call_args[1]["data"] 86 self.assertIn("SAMLResponse", form_data) 87 self.assertNotIn("RelayState", form_data) 88 89 def test_provider_not_found(self): 90 """Test returns False when provider doesn't exist""" 91 result = send_saml_logout_response( 92 provider_pk=99999, # Non-existent provider 93 sls_url="https://sp.example.com/sls", 94 logout_request_id="test-request-id", 95 relay_state=None, 96 ) 97 98 self.assertFalse(result) 99 100 @patch("authentik.providers.saml.tasks.Event") 101 @patch("authentik.providers.saml.tasks.requests.post") 102 def test_http_error_creates_event(self, mock_post, mock_event_class): 103 """Test HTTP error creates an error event""" 104 mock_response = MagicMock() 105 mock_response.status_code = 500 106 mock_response.raise_for_status.side_effect = HTTPError("500 Server Error") 107 mock_post.return_value = mock_response 108 109 mock_event = MagicMock() 110 mock_event_class.new.return_value = mock_event 111 112 result = send_saml_logout_response( 113 provider_pk=self.provider.pk, 114 sls_url=self.provider.sls_url, 115 logout_request_id="test-request-id", 116 relay_state=None, 117 ) 118 119 self.assertFalse(result) 120 121 # Verify error event was created 122 mock_event_class.new.assert_called_once() 123 call_kwargs = mock_event_class.new.call_args[1] 124 self.assertIn("Backchannel logout response failed", call_kwargs["message"]) 125 mock_event.save.assert_called_once()
Tests for send_saml_logout_response task
def
setUp(self):
22 def setUp(self): 23 """Set up test fixtures""" 24 self.cert = create_test_cert() 25 self.flow = create_test_flow() 26 27 self.provider = SAMLProvider.objects.create( 28 name="test-provider", 29 authorization_flow=self.flow, 30 acs_url="https://sp.example.com/acs", 31 sls_url="https://sp.example.com/sls", 32 issuer_override="https://idp.example.com", 33 signing_kp=self.cert, 34 )
Set up test fixtures
@patch('authentik.providers.saml.tasks.requests.post')
def
test_successful_logout_response(self, mock_post):
36 @patch("authentik.providers.saml.tasks.requests.post") 37 def test_successful_logout_response(self, mock_post): 38 """Test successful POST to SP returns True""" 39 mock_response = MagicMock() 40 mock_response.status_code = 200 41 mock_response.raise_for_status = MagicMock() 42 mock_post.return_value = mock_response 43 44 result = send_saml_logout_response( 45 provider_pk=self.provider.pk, 46 sls_url=self.provider.sls_url, 47 logout_request_id="test-request-id", 48 relay_state="https://sp.example.com/return", 49 ) 50 51 self.assertTrue(result) 52 mock_post.assert_called_once() 53 54 # Verify the POST was made with correct data 55 call_kwargs = mock_post.call_args[1] 56 self.assertEqual(call_kwargs["timeout"], 10) 57 self.assertEqual( 58 call_kwargs["headers"]["Content-Type"], "application/x-www-form-urlencoded" 59 ) 60 61 # Verify form data contains SAMLResponse and RelayState 62 form_data = call_kwargs["data"] 63 self.assertIn("SAMLResponse", form_data) 64 self.assertIn("RelayState", form_data) 65 self.assertEqual(form_data["RelayState"], "https://sp.example.com/return")
Test successful POST to SP returns True
@patch('authentik.providers.saml.tasks.requests.post')
def
test_successful_logout_response_no_relay_state(self, mock_post):
67 @patch("authentik.providers.saml.tasks.requests.post") 68 def test_successful_logout_response_no_relay_state(self, mock_post): 69 """Test successful POST without relay_state""" 70 mock_response = MagicMock() 71 mock_response.status_code = 200 72 mock_response.raise_for_status = MagicMock() 73 mock_post.return_value = mock_response 74 75 result = send_saml_logout_response( 76 provider_pk=self.provider.pk, 77 sls_url=self.provider.sls_url, 78 logout_request_id="test-request-id", 79 relay_state=None, 80 ) 81 82 self.assertTrue(result) 83 84 # Verify form data does not contain RelayState 85 form_data = mock_post.call_args[1]["data"] 86 self.assertIn("SAMLResponse", form_data) 87 self.assertNotIn("RelayState", form_data)
Test successful POST without relay_state
def
test_provider_not_found(self):
89 def test_provider_not_found(self): 90 """Test returns False when provider doesn't exist""" 91 result = send_saml_logout_response( 92 provider_pk=99999, # Non-existent provider 93 sls_url="https://sp.example.com/sls", 94 logout_request_id="test-request-id", 95 relay_state=None, 96 ) 97 98 self.assertFalse(result)
Test returns False when provider doesn't exist
@patch('authentik.providers.saml.tasks.Event')
@patch('authentik.providers.saml.tasks.requests.post')
def
test_http_error_creates_event(self, mock_post, mock_event_class):
100 @patch("authentik.providers.saml.tasks.Event") 101 @patch("authentik.providers.saml.tasks.requests.post") 102 def test_http_error_creates_event(self, mock_post, mock_event_class): 103 """Test HTTP error creates an error event""" 104 mock_response = MagicMock() 105 mock_response.status_code = 500 106 mock_response.raise_for_status.side_effect = HTTPError("500 Server Error") 107 mock_post.return_value = mock_response 108 109 mock_event = MagicMock() 110 mock_event_class.new.return_value = mock_event 111 112 result = send_saml_logout_response( 113 provider_pk=self.provider.pk, 114 sls_url=self.provider.sls_url, 115 logout_request_id="test-request-id", 116 relay_state=None, 117 ) 118 119 self.assertFalse(result) 120 121 # Verify error event was created 122 mock_event_class.new.assert_called_once() 123 call_kwargs = mock_event_class.new.call_args[1] 124 self.assertIn("Backchannel logout response failed", call_kwargs["message"]) 125 mock_event.save.assert_called_once()
Test HTTP error creates an error event
class
TestSendSamlLogoutRequest(django.test.testcases.TestCase):
128class TestSendSamlLogoutRequest(TestCase): 129 """Tests for send_saml_logout_request task""" 130 131 def setUp(self): 132 """Set up test fixtures""" 133 self.cert = create_test_cert() 134 self.flow = create_test_flow() 135 136 self.provider = SAMLProvider.objects.create( 137 name="test-provider", 138 authorization_flow=self.flow, 139 acs_url="https://sp.example.com/acs", 140 sls_url="https://sp.example.com/sls", 141 issuer_override="https://idp.example.com", 142 signing_kp=self.cert, 143 ) 144 145 @patch("authentik.providers.saml.tasks.requests.post") 146 def test_successful_logout_request(self, mock_post): 147 """Test successful POST logout request returns True""" 148 mock_response = MagicMock() 149 mock_response.status_code = 200 150 mock_response.raise_for_status = MagicMock() 151 mock_post.return_value = mock_response 152 153 result = send_saml_logout_request( 154 provider_pk=self.provider.pk, 155 sls_url=self.provider.sls_url, 156 name_id="test@example.com", 157 name_id_format=SAML_NAME_ID_FORMAT_EMAIL, 158 session_index="test-session-123", 159 issuer="https://idp.example.com", 160 ) 161 162 self.assertTrue(result) 163 mock_post.assert_called_once() 164 165 # Verify the POST was made with correct data 166 call_kwargs = mock_post.call_args[1] 167 self.assertEqual(call_kwargs["timeout"], 10) 168 self.assertEqual( 169 call_kwargs["headers"]["Content-Type"], "application/x-www-form-urlencoded" 170 ) 171 172 # Verify form data contains SAMLRequest 173 form_data = call_kwargs["data"] 174 self.assertIn("SAMLRequest", form_data) 175 176 def test_provider_not_found(self): 177 """Test returns False when provider doesn't exist""" 178 result = send_saml_logout_request( 179 provider_pk=99999, # Non-existent provider 180 sls_url="https://sp.example.com/sls", 181 name_id="test@example.com", 182 name_id_format=SAML_NAME_ID_FORMAT_EMAIL, 183 session_index="test-session-123", 184 issuer="https://idp.example.com", 185 ) 186 187 self.assertFalse(result) 188 189 @patch("authentik.providers.saml.tasks.requests.post") 190 def test_http_error_raises(self, mock_post): 191 """Test HTTP error raises exception (no try/catch in send_post_logout_request)""" 192 mock_response = MagicMock() 193 mock_response.status_code = 500 194 mock_response.raise_for_status.side_effect = HTTPError("500 Server Error") 195 mock_post.return_value = mock_response 196 197 with self.assertRaises(HTTPError): 198 send_saml_logout_request( 199 provider_pk=self.provider.pk, 200 sls_url=self.provider.sls_url, 201 name_id="test@example.com", 202 name_id_format=SAML_NAME_ID_FORMAT_EMAIL, 203 session_index="test-session-123", 204 issuer="https://idp.example.com", 205 )
Tests for send_saml_logout_request task
def
setUp(self):
131 def setUp(self): 132 """Set up test fixtures""" 133 self.cert = create_test_cert() 134 self.flow = create_test_flow() 135 136 self.provider = SAMLProvider.objects.create( 137 name="test-provider", 138 authorization_flow=self.flow, 139 acs_url="https://sp.example.com/acs", 140 sls_url="https://sp.example.com/sls", 141 issuer_override="https://idp.example.com", 142 signing_kp=self.cert, 143 )
Set up test fixtures
@patch('authentik.providers.saml.tasks.requests.post')
def
test_successful_logout_request(self, mock_post):
145 @patch("authentik.providers.saml.tasks.requests.post") 146 def test_successful_logout_request(self, mock_post): 147 """Test successful POST logout request returns True""" 148 mock_response = MagicMock() 149 mock_response.status_code = 200 150 mock_response.raise_for_status = MagicMock() 151 mock_post.return_value = mock_response 152 153 result = send_saml_logout_request( 154 provider_pk=self.provider.pk, 155 sls_url=self.provider.sls_url, 156 name_id="test@example.com", 157 name_id_format=SAML_NAME_ID_FORMAT_EMAIL, 158 session_index="test-session-123", 159 issuer="https://idp.example.com", 160 ) 161 162 self.assertTrue(result) 163 mock_post.assert_called_once() 164 165 # Verify the POST was made with correct data 166 call_kwargs = mock_post.call_args[1] 167 self.assertEqual(call_kwargs["timeout"], 10) 168 self.assertEqual( 169 call_kwargs["headers"]["Content-Type"], "application/x-www-form-urlencoded" 170 ) 171 172 # Verify form data contains SAMLRequest 173 form_data = call_kwargs["data"] 174 self.assertIn("SAMLRequest", form_data)
Test successful POST logout request returns True
def
test_provider_not_found(self):
176 def test_provider_not_found(self): 177 """Test returns False when provider doesn't exist""" 178 result = send_saml_logout_request( 179 provider_pk=99999, # Non-existent provider 180 sls_url="https://sp.example.com/sls", 181 name_id="test@example.com", 182 name_id_format=SAML_NAME_ID_FORMAT_EMAIL, 183 session_index="test-session-123", 184 issuer="https://idp.example.com", 185 ) 186 187 self.assertFalse(result)
Test returns False when provider doesn't exist
@patch('authentik.providers.saml.tasks.requests.post')
def
test_http_error_raises(self, mock_post):
189 @patch("authentik.providers.saml.tasks.requests.post") 190 def test_http_error_raises(self, mock_post): 191 """Test HTTP error raises exception (no try/catch in send_post_logout_request)""" 192 mock_response = MagicMock() 193 mock_response.status_code = 500 194 mock_response.raise_for_status.side_effect = HTTPError("500 Server Error") 195 mock_post.return_value = mock_response 196 197 with self.assertRaises(HTTPError): 198 send_saml_logout_request( 199 provider_pk=self.provider.pk, 200 sls_url=self.provider.sls_url, 201 name_id="test@example.com", 202 name_id_format=SAML_NAME_ID_FORMAT_EMAIL, 203 session_index="test-session-123", 204 issuer="https://idp.example.com", 205 )
Test HTTP error raises exception (no try/catch in send_post_logout_request)
class
TestSendPostLogoutRequest(django.test.testcases.TestCase):
208class TestSendPostLogoutRequest(TestCase): 209 """Tests for send_post_logout_request function""" 210 211 def setUp(self): 212 """Set up test fixtures""" 213 self.cert = create_test_cert() 214 self.flow = create_test_flow() 215 216 self.provider = SAMLProvider.objects.create( 217 name="test-provider", 218 authorization_flow=self.flow, 219 acs_url="https://sp.example.com/acs", 220 sls_url="https://sp.example.com/sls", 221 issuer_override="https://idp.example.com", 222 signing_kp=self.cert, 223 ) 224 225 @patch("authentik.providers.saml.tasks.requests.post") 226 def test_successful_post(self, mock_post): 227 """Test successful POST returns True""" 228 from authentik.providers.saml.processors.logout_request import LogoutRequestProcessor 229 230 mock_response = MagicMock() 231 mock_response.status_code = 200 232 mock_response.raise_for_status = MagicMock() 233 mock_post.return_value = mock_response 234 235 processor = LogoutRequestProcessor( 236 provider=self.provider, 237 user=None, 238 destination=self.provider.sls_url, 239 name_id="test@example.com", 240 name_id_format=SAML_NAME_ID_FORMAT_EMAIL, 241 session_index="test-session-123", 242 ) 243 244 result = send_post_logout_request(self.provider, processor) 245 246 self.assertTrue(result) 247 mock_post.assert_called_once() 248 249 @patch("authentik.providers.saml.tasks.requests.post") 250 def test_with_relay_state(self, mock_post): 251 """Test POST includes RelayState when present""" 252 from authentik.providers.saml.processors.logout_request import LogoutRequestProcessor 253 254 mock_response = MagicMock() 255 mock_response.status_code = 200 256 mock_response.raise_for_status = MagicMock() 257 mock_post.return_value = mock_response 258 259 processor = LogoutRequestProcessor( 260 provider=self.provider, 261 user=None, 262 destination=self.provider.sls_url, 263 name_id="test@example.com", 264 name_id_format=SAML_NAME_ID_FORMAT_EMAIL, 265 session_index="test-session-123", 266 relay_state="https://sp.example.com/return", 267 ) 268 269 result = send_post_logout_request(self.provider, processor) 270 271 self.assertTrue(result) 272 273 # Verify RelayState is included 274 form_data = mock_post.call_args[1]["data"] 275 self.assertIn("RelayState", form_data) 276 self.assertEqual(form_data["RelayState"], "https://sp.example.com/return") 277 278 @patch("authentik.providers.saml.tasks.requests.post") 279 def test_connection_error_raises(self, mock_post): 280 """Test connection error raises exception""" 281 from authentik.providers.saml.processors.logout_request import LogoutRequestProcessor 282 283 mock_post.side_effect = ConnectionError("Connection refused") 284 285 processor = LogoutRequestProcessor( 286 provider=self.provider, 287 user=None, 288 destination=self.provider.sls_url, 289 name_id="test@example.com", 290 name_id_format=SAML_NAME_ID_FORMAT_EMAIL, 291 session_index="test-session-123", 292 ) 293 294 with self.assertRaises(ConnectionError): 295 send_post_logout_request(self.provider, processor)
Tests for send_post_logout_request function
def
setUp(self):
211 def setUp(self): 212 """Set up test fixtures""" 213 self.cert = create_test_cert() 214 self.flow = create_test_flow() 215 216 self.provider = SAMLProvider.objects.create( 217 name="test-provider", 218 authorization_flow=self.flow, 219 acs_url="https://sp.example.com/acs", 220 sls_url="https://sp.example.com/sls", 221 issuer_override="https://idp.example.com", 222 signing_kp=self.cert, 223 )
Set up test fixtures
@patch('authentik.providers.saml.tasks.requests.post')
def
test_successful_post(self, mock_post):
225 @patch("authentik.providers.saml.tasks.requests.post") 226 def test_successful_post(self, mock_post): 227 """Test successful POST returns True""" 228 from authentik.providers.saml.processors.logout_request import LogoutRequestProcessor 229 230 mock_response = MagicMock() 231 mock_response.status_code = 200 232 mock_response.raise_for_status = MagicMock() 233 mock_post.return_value = mock_response 234 235 processor = LogoutRequestProcessor( 236 provider=self.provider, 237 user=None, 238 destination=self.provider.sls_url, 239 name_id="test@example.com", 240 name_id_format=SAML_NAME_ID_FORMAT_EMAIL, 241 session_index="test-session-123", 242 ) 243 244 result = send_post_logout_request(self.provider, processor) 245 246 self.assertTrue(result) 247 mock_post.assert_called_once()
Test successful POST returns True
@patch('authentik.providers.saml.tasks.requests.post')
def
test_with_relay_state(self, mock_post):
249 @patch("authentik.providers.saml.tasks.requests.post") 250 def test_with_relay_state(self, mock_post): 251 """Test POST includes RelayState when present""" 252 from authentik.providers.saml.processors.logout_request import LogoutRequestProcessor 253 254 mock_response = MagicMock() 255 mock_response.status_code = 200 256 mock_response.raise_for_status = MagicMock() 257 mock_post.return_value = mock_response 258 259 processor = LogoutRequestProcessor( 260 provider=self.provider, 261 user=None, 262 destination=self.provider.sls_url, 263 name_id="test@example.com", 264 name_id_format=SAML_NAME_ID_FORMAT_EMAIL, 265 session_index="test-session-123", 266 relay_state="https://sp.example.com/return", 267 ) 268 269 result = send_post_logout_request(self.provider, processor) 270 271 self.assertTrue(result) 272 273 # Verify RelayState is included 274 form_data = mock_post.call_args[1]["data"] 275 self.assertIn("RelayState", form_data) 276 self.assertEqual(form_data["RelayState"], "https://sp.example.com/return")
Test POST includes RelayState when present
@patch('authentik.providers.saml.tasks.requests.post')
def
test_connection_error_raises(self, mock_post):
278 @patch("authentik.providers.saml.tasks.requests.post") 279 def test_connection_error_raises(self, mock_post): 280 """Test connection error raises exception""" 281 from authentik.providers.saml.processors.logout_request import LogoutRequestProcessor 282 283 mock_post.side_effect = ConnectionError("Connection refused") 284 285 processor = LogoutRequestProcessor( 286 provider=self.provider, 287 user=None, 288 destination=self.provider.sls_url, 289 name_id="test@example.com", 290 name_id_format=SAML_NAME_ID_FORMAT_EMAIL, 291 session_index="test-session-123", 292 ) 293 294 with self.assertRaises(ConnectionError): 295 send_post_logout_request(self.provider, processor)
Test connection error raises exception