Skip to content

Commit e706bad

Browse files
authored
Merge pull request #144 from doticatto/get_in_response_to
Added get_in_response_to method to Response and LogoutResponse classes
2 parents 08fdfdf + 754f635 commit e706bad

File tree

3 files changed

+37
-5
lines changed

3 files changed

+37
-5
lines changed

src/onelogin/saml2/logout_response.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ def is_valid(self, request_data, request_id=None, raise_exceptions=False):
9595
security = self.__settings.get_security_data()
9696

9797
# Check if the InResponseTo of the Logout Response matches the ID of the Logout Request (requestId) if provided
98-
in_response_to = self.document.get('InResponseTo', None)
98+
in_response_to = self.get_in_response_to()
9999
if request_id is not None and in_response_to and in_response_to != request_id:
100100
raise OneLogin_Saml2_ValidationError(
101101
'The InResponseTo of the Logout Response: %s, does not match the ID of the Logout request sent by the SP: %s' % (in_response_to, request_id),
@@ -175,6 +175,14 @@ def build(self, in_response_to):
175175

176176
self.__logout_response = logout_response
177177

178+
def get_in_response_to(self):
179+
"""
180+
Gets the ID of the LogoutRequest which this response is in response to
181+
:returns: ID of LogoutRequest this LogoutResponse is in response to or None if it is not present
182+
:rtype: str
183+
"""
184+
return self.document.get('InResponseTo')
185+
178186
def get_response(self, deflate=True):
179187
"""
180188
Returns a Logout Response object.

src/onelogin/saml2/response.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ def is_valid(self, request_data, request_id=None, raise_exceptions=False):
122122
current_url = OneLogin_Saml2_Utils.get_self_url_no_query(request_data)
123123

124124
# Check if the InResponseTo of the Response matchs the ID of the AuthNRequest (requestId) if provided
125-
in_response_to = self.document.get('InResponseTo', None)
125+
in_response_to = self.get_in_response_to()
126126
if in_response_to is not None and request_id is not None:
127127
if in_response_to != request_id:
128128
raise OneLogin_Saml2_ValidationError(
@@ -387,6 +387,14 @@ def get_authn_contexts(self):
387387
authn_context_nodes = self.__query_assertion('/saml:AuthnStatement/saml:AuthnContext/saml:AuthnContextClassRef')
388388
return [OneLogin_Saml2_XML.element_text(node) for node in authn_context_nodes]
389389

390+
def get_in_response_to(self):
391+
"""
392+
Gets the ID of the request which this response is in response to
393+
:returns: ID of AuthNRequest this Response is in response to or None if it is not present
394+
:rtype: str
395+
"""
396+
return self.document.get('InResponseTo')
397+
390398
def get_issuers(self):
391399
"""
392400
Gets the issuers (from message and from assertion)

tests/src/OneLogin/saml2_tests/response_test.py

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,8 @@ def testGetXMLDocument(self):
7575

7676
xml = self.file_contents(join(self.data_path, 'responses', 'signed_message_response.xml.base64'))
7777
response = OneLogin_Saml2_Response(settings, xml)
78-
prety_xml = self.file_contents(join(self.data_path, 'responses', 'pretty_signed_message_response.xml'))
79-
self.assertEqual(etree.tostring(response.get_xml_document(), encoding='unicode', pretty_print=True), prety_xml)
78+
pretty_xml = self.file_contents(join(self.data_path, 'responses', 'pretty_signed_message_response.xml'))
79+
self.assertEqual(etree.tostring(response.get_xml_document(), encoding='unicode', pretty_print=True), pretty_xml)
8080

8181
xml_2 = self.file_contents(join(self.data_path, 'responses', 'valid_encrypted_assertion.xml.base64'))
8282
response_2 = OneLogin_Saml2_Response(settings, xml_2)
@@ -407,7 +407,7 @@ def testGetNameIdData(self):
407407
settings = OneLogin_Saml2_Settings(json_settings)
408408
response_13 = OneLogin_Saml2_Response(settings, xml_6)
409409
nameid_data_13 = response_13.get_nameid_data()
410-
nameid_data_13 = self.assertEqual(expected_nameid_data_5, nameid_data_13)
410+
self.assertEqual(expected_nameid_data_5, nameid_data_13)
411411

412412
json_settings['strict'] = False
413413
json_settings['security']['wantNameId'] = False
@@ -685,6 +685,22 @@ def testGetSessionNotOnOrAfter(self):
685685
response_3 = OneLogin_Saml2_Response(settings, xml_3)
686686
self.assertEqual(2696012228, response_3.get_session_not_on_or_after())
687687

688+
def testGetInResponseTo(self):
689+
"""
690+
Tests the retrieval of the InResponseTo attribute
691+
"""
692+
693+
settings = OneLogin_Saml2_Settings(self.loadSettingsJSON())
694+
695+
# Response without an InResponseTo element should return None
696+
xml = self.file_contents(join(self.data_path, 'responses', 'response1.xml.base64'))
697+
response = OneLogin_Saml2_Response(settings, xml)
698+
self.assertIsNone(response.get_in_response_to())
699+
700+
xml_3 = self.file_contents(join(self.data_path, 'responses', 'valid_encrypted_assertion.xml.base64'))
701+
response_3 = OneLogin_Saml2_Response(settings, xml_3)
702+
self.assertEqual('ONELOGIN_be60b8caf8e9d19b7a3551b244f116c947ff247d', response_3.get_in_response_to())
703+
688704
def testIsInvalidXML(self):
689705
"""
690706
Tests the is_valid method of the OneLogin_Saml2_Response

0 commit comments

Comments
 (0)