|
21 | 21 |
|
22 | 22 | from satosa.backends.saml2 import SAMLBackend
|
23 | 23 | from satosa.context import Context
|
| 24 | +from satosa.exception import SATOSAAuthenticationError |
| 25 | +from satosa.exception import SATOSAMissingStateError |
24 | 26 | from satosa.internal import InternalData
|
25 | 27 | from tests.users import USERS
|
26 | 28 | from tests.util import FakeIdP, create_metadata_from_config_dict, FakeSP
|
@@ -132,7 +134,7 @@ def test_full_flow(self, context, idp_conf, sp_conf):
|
132 | 134 | disco_resp = parse_qs(urlparse(resp.message).query)
|
133 | 135 | info = parse_qs(urlparse(disco_resp["return"][0]).query)
|
134 | 136 | info["entityID"] = idp_conf["entityid"]
|
135 |
| - request_context = context |
| 137 | + request_context = Context() |
136 | 138 | request_context.request = info
|
137 | 139 | request_context.state = context.state
|
138 | 140 |
|
@@ -241,43 +243,72 @@ def test_unknown_or_no_hostname_selects_first_acs(
|
241 | 243 |
|
242 | 244 | def test_authn_response(self, context, idp_conf, sp_conf):
|
243 | 245 | response_binding = BINDING_HTTP_REDIRECT
|
244 |
| - fakesp = FakeSP(SPConfig().load(sp_conf)) |
245 |
| - fakeidp = FakeIdP(USERS, config=IdPConfig().load(idp_conf)) |
246 |
| - destination, request_params = fakesp.make_auth_req(idp_conf["entityid"]) |
247 |
| - url, auth_resp = fakeidp.handle_auth_req(request_params["SAMLRequest"], request_params["RelayState"], |
248 |
| - BINDING_HTTP_REDIRECT, |
249 |
| - "testuser1", response_binding=response_binding) |
250 |
| - |
| 246 | + request_params, auth_resp = self._perform_request_response( |
| 247 | + idp_conf, sp_conf, response_binding |
| 248 | + ) |
251 | 249 | context.request = auth_resp
|
252 | 250 | context.state[self.samlbackend.name] = {"relay_state": request_params["RelayState"]}
|
253 | 251 | self.samlbackend.authn_response(context, response_binding)
|
254 | 252 |
|
255 | 253 | context, internal_resp = self.samlbackend.auth_callback_func.call_args[0]
|
256 | 254 | assert_authn_response(internal_resp)
|
257 | 255 |
|
258 |
| - @pytest.mark.skipif( |
259 |
| - saml2.__version__ < '4.6.1', |
260 |
| - reason="Optional NameID needs pysaml2 v4.6.1 or higher") |
261 |
| - def test_authn_response_no_name_id(self, context, idp_conf, sp_conf): |
| 256 | + def _perform_request_response( |
| 257 | + self, idp_conf, sp_conf, response_binding, receive_nameid=True |
| 258 | + ): |
| 259 | + fakesp = FakeSP(SPConfig().load(sp_conf)) |
| 260 | + fakeidp = FakeIdP(USERS, config=IdPConfig().load(idp_conf)) |
| 261 | + destination, request_params = fakesp.make_auth_req(idp_conf["entityid"]) |
| 262 | + auth_resp_func = ( |
| 263 | + fakeidp.handle_auth_req |
| 264 | + if receive_nameid |
| 265 | + else fakeidp.handle_auth_req_no_name_id |
| 266 | + ) |
| 267 | + url, auth_resp = auth_resp_func( |
| 268 | + request_params["SAMLRequest"], |
| 269 | + request_params["RelayState"], |
| 270 | + BINDING_HTTP_REDIRECT, |
| 271 | + "testuser1", |
| 272 | + response_binding=response_binding, |
| 273 | + ) |
| 274 | + |
| 275 | + return request_params, auth_resp |
| 276 | + |
| 277 | + def test_no_state_raises_error(self, context, idp_conf, sp_conf): |
262 | 278 | response_binding = BINDING_HTTP_REDIRECT
|
| 279 | + request_params, auth_resp = self._perform_request_response( |
| 280 | + idp_conf, sp_conf, response_binding |
| 281 | + ) |
| 282 | + context.request = auth_resp |
| 283 | + # not setting context.state[self.samlbackend.name] |
| 284 | + # to simulate a request with lost state |
263 | 285 |
|
264 |
| - fakesp_conf = SPConfig().load(sp_conf) |
265 |
| - fakesp = FakeSP(fakesp_conf) |
| 286 | + with pytest.raises(SATOSAMissingStateError): |
| 287 | + self.samlbackend.authn_response(context, response_binding) |
266 | 288 |
|
267 |
| - fakeidp_conf = IdPConfig().load(idp_conf) |
268 |
| - fakeidp = FakeIdP(USERS, config=fakeidp_conf) |
| 289 | + def test_no_relay_state_raises_error(self, context, idp_conf, sp_conf): |
| 290 | + response_binding = BINDING_HTTP_REDIRECT |
| 291 | + request_params, auth_resp = self._perform_request_response( |
| 292 | + idp_conf, sp_conf, response_binding |
| 293 | + ) |
| 294 | + context.request = auth_resp |
| 295 | + # not setting context.state[self.samlbackend.name]["relay_state"] |
| 296 | + # to simulate a request without a relay state |
| 297 | + context.state[self.samlbackend.name] = {} |
269 | 298 |
|
270 |
| - destination, request_params = fakesp.make_auth_req( |
271 |
| - idp_conf["entityid"]) |
| 299 | + with pytest.raises(SATOSAAuthenticationError): |
| 300 | + self.samlbackend.authn_response(context, response_binding) |
272 | 301 |
|
273 |
| - # Use the fake IdP to mock up an authentication request that has no |
274 |
| - # <NameID> element. |
275 |
| - url, auth_resp = fakeidp.handle_auth_req_no_name_id( |
276 |
| - request_params["SAMLRequest"], |
277 |
| - request_params["RelayState"], |
278 |
| - BINDING_HTTP_REDIRECT, |
279 |
| - "testuser1", |
280 |
| - response_binding=response_binding) |
| 302 | + @pytest.mark.skipif( |
| 303 | + saml2.__version__ < '4.6.1', |
| 304 | + reason="Optional NameID needs pysaml2 v4.6.1 or higher" |
| 305 | + ) |
| 306 | + def test_authn_response_no_name_id(self, context, idp_conf, sp_conf): |
| 307 | + response_binding = BINDING_HTTP_REDIRECT |
| 308 | + |
| 309 | + request_params, auth_resp = self._perform_request_response( |
| 310 | + idp_conf, sp_conf, response_binding, receive_nameid=False |
| 311 | + ) |
281 | 312 |
|
282 | 313 | backend = self.samlbackend
|
283 | 314 |
|
|
0 commit comments