diff --git a/README.md b/README.md index 9bb01b16..2e6842ee 100644 --- a/README.md +++ b/README.md @@ -801,11 +801,17 @@ target_url = 'https://example.com' auth.logout(return_to=target_url) ``` -Also there are 2 optional parameters that can be set: +Also there are 4 optional parameters that can be set: * name_id. That will be used to build the LogoutRequest. If not name_id parameter is set and the auth object processed a SAML Response with a NameId, then this NameId will be used. * session_index. SessionIndex that identifies the session of the user. +* nq. IDP Name Qualifier +* name_id_format. The NameID Format that will be set in the LogoutRequest + +If no name_id is provided, the LogoutRequest will contain a NameID with the entity Format. +If name_id is provided and no name_id_format is provided, the NameIDFormat of the settings will be used. +If nq is provided, the SPNameQualifier will be also attached to the NameId. If a match on the LogoutResponse ID and the LogoutRequest ID to be sent is required, that LogoutRequest ID must to be extracted and stored for future validation, we can get that ID by diff --git a/src/onelogin/saml2/logout_request.py b/src/onelogin/saml2/logout_request.py index 99c97198..6e6a1903 100644 --- a/src/onelogin/saml2/logout_request.py +++ b/src/onelogin/saml2/logout_request.py @@ -80,10 +80,15 @@ def __init__(self, settings, request=None, name_id=None, session_index=None, nq= nameIdFormat = name_id_format else: nameIdFormat = sp_data['NameIDFormat'] - spNameQualifier = None else: - name_id = idp_data['entityId'] nameIdFormat = OneLogin_Saml2_Constants.NAMEID_ENTITY + + spNameQualifier = None + if nameIdFormat == OneLogin_Saml2_Constants.NAMEID_ENTITY: + name_id = idp_data['entityId'] + nq = None + elif nq is not None: + # We only gonna include SPNameQualifier if NameQualifier is provided spNameQualifier = sp_data['entityId'] name_id_obj = OneLogin_Saml2_Utils.generate_name_id( diff --git a/tests/src/OneLogin/saml2_tests/auth_test.py b/tests/src/OneLogin/saml2_tests/auth_test.py index 9c42c0bc..f80d26e1 100644 --- a/tests/src/OneLogin/saml2_tests/auth_test.py +++ b/tests/src/OneLogin/saml2_tests/auth_test.py @@ -1047,7 +1047,7 @@ def testGetLastLogoutRequest(self): expectedFragment = ( ' Destination="http://idp.example.com/SingleLogoutService.php">\n' ' http://stuff.com/endpoints/metadata.php\n' - ' http://idp.example.com/\n' + ' http://idp.example.com/\n' ' \n ' ) self.assertIn(expectedFragment, auth.get_last_request_xml()) diff --git a/tests/src/OneLogin/saml2_tests/logout_request_test.py b/tests/src/OneLogin/saml2_tests/logout_request_test.py index b0bfdf92..d1eab57e 100644 --- a/tests/src/OneLogin/saml2_tests/logout_request_test.py +++ b/tests/src/OneLogin/saml2_tests/logout_request_test.py @@ -154,9 +154,11 @@ def testGetNameIdData(self): OneLogin_Saml2_Logout_Request.get_nameid_data(dom_2.toxml(), key) idp_data = settings.get_idp_data() + sp_data = settings.get_sp_data() expected_name_id_data = { 'Format': 'urn:oasis:names:tc:SAML:2.0:nameid-format:emailAddress', 'NameQualifier': idp_data['entityId'], + 'SPNameQualifier': sp_data['entityId'], 'Value': 'ONELOGIN_9c86c4542ab9d6fce07f2f7fd335287b9b3cdf69' } @@ -169,6 +171,24 @@ def testGetNameIdData(self): name_id_data_3 = OneLogin_Saml2_Logout_Request.get_nameid_data(dom) self.assertEqual(expected_name_id_data, name_id_data_3) + expected_name_id_data = { + 'Format': 'urn:oasis:names:tc:SAML:2.0:nameid-format:emailAddress', + 'Value': 'ONELOGIN_9c86c4542ab9d6fce07f2f7fd335287b9b3cdf69' + } + logout_request = OneLogin_Saml2_Logout_Request(settings, None, expected_name_id_data['Value'], None, None, expected_name_id_data['Format']) + dom = parseString(logout_request.get_xml()) + name_id_data_4 = OneLogin_Saml2_Logout_Request.get_nameid_data(dom) + self.assertEqual(expected_name_id_data, name_id_data_4) + + expected_name_id_data = { + 'Format': 'urn:oasis:names:tc:SAML:2.0:nameid-format:entity', + 'Value': 'http://idp.example.com/' + } + logout_request = OneLogin_Saml2_Logout_Request(settings) + dom = parseString(logout_request.get_xml()) + name_id_data_5 = OneLogin_Saml2_Logout_Request.get_nameid_data(dom) + self.assertEqual(expected_name_id_data, name_id_data_5) + def testGetNameId(self): """ Tests the get_nameid of the OneLogin_Saml2_LogoutRequest @@ -478,7 +498,7 @@ def testGetXML(self): expectedFragment = ( 'Destination="http://idp.example.com/SingleLogoutService.php">\n' ' http://stuff.com/endpoints/metadata.php\n' - ' http://idp.example.com/\n' + ' http://idp.example.com/\n' ' \n ' ) self.assertIn(expectedFragment, logout_request_generated.get_xml())