Skip to content

Commit 0cd21ec

Browse files
committed
Add option to raise exceptions on SAML message validation
1 parent a092270 commit 0cd21ec

6 files changed

Lines changed: 59 additions & 5 deletions

File tree

src/onelogin/saml2/logout_request.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,12 +260,13 @@ def get_session_indexes(request):
260260
session_indexes.append(session_index_node.text)
261261
return session_indexes
262262

263-
def is_valid(self, request_data):
263+
def is_valid(self, request_data, raise_exceptions=False):
264264
"""
265265
Checks if the Logout Request received is valid
266266
:param request_data: Request Data
267267
:type request_data: dict
268-
268+
:param raise_exceptions: Whether to return false on failure or raise an exception
269+
:type raise_exceptions: Boolean
269270
:return: If the Logout Request is or not valid
270271
:rtype: boolean
271272
"""
@@ -348,6 +349,8 @@ def is_valid(self, request_data):
348349
debug = self.__settings.is_debug_active()
349350
if debug:
350351
print err.__str__()
352+
if raise_exceptions:
353+
raise err
351354
return False
352355

353356
def get_error(self):

src/onelogin/saml2/logout_response.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,13 @@ def get_status(self):
6868
status = entries[0].attrib['Value']
6969
return status
7070

71-
def is_valid(self, request_data, request_id=None):
71+
def is_valid(self, request_data, request_id=None, raise_exceptions=False):
7272
"""
7373
Determines if the SAML LogoutResponse is valid
7474
:param request_id: The ID of the LogoutRequest sent by this SP to the IdP
7575
:type request_id: string
76+
:param raise_exceptions: Whether to return false on failure or raise an exception
77+
:type raise_exceptions: Boolean
7678
:return: Returns if the SAML LogoutResponse is or not valid
7779
:rtype: boolean
7880
"""
@@ -89,7 +91,7 @@ def is_valid(self, request_data, request_id=None):
8991
if self.__settings.is_strict():
9092
res = OneLogin_Saml2_Utils.validate_xml(self.document, 'saml-schema-protocol-2.0.xsd', self.__settings.is_debug_active())
9193
if not isinstance(res, Document):
92-
raise Exception('Invalid SAML Logout Request. Not match the saml-schema-protocol-2.0.xsd')
94+
raise Exception('Invalid SAML Logout Response. Not match the saml-schema-protocol-2.0.xsd')
9395

9496
security = self.__settings.get_security_data()
9597

@@ -142,6 +144,8 @@ def is_valid(self, request_data, request_id=None):
142144
debug = self.__settings.is_debug_active()
143145
if debug:
144146
print err.__str__()
147+
if raise_exceptions:
148+
raise err
145149
return False
146150

147151
def __query(self, query):

src/onelogin/saml2/response.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ def __init__(self, settings, response):
5151
self.encrypted = True
5252
self.decrypted_document = self.__decrypt_assertion(decrypted_document)
5353

54-
def is_valid(self, request_data, request_id=None):
54+
def is_valid(self, request_data, request_id=None, raise_exceptions=False):
5555
"""
5656
Validates the response object.
5757
@@ -239,6 +239,8 @@ def is_valid(self, request_data, request_id=None):
239239
debug = self.__settings.is_debug_active()
240240
if debug:
241241
print err.__str__()
242+
if raise_exceptions:
243+
raise err
242244
return False
243245

244246
def check_status(self):

tests/src/OneLogin/saml2_tests/logout_request_test.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,22 @@ def testIsValid(self):
312312
logout_request5 = OneLogin_Saml2_Logout_Request(settings, b64encode(request))
313313
self.assertTrue(logout_request5.is_valid(request_data))
314314

315+
def testIsValidRaisesExceptionWhenRaisesArgumentIsTrue(self):
316+
request = OneLogin_Saml2_Utils.deflate_and_base64_encode('<xml>invalid</xml>')
317+
request_data = {
318+
'http_host': 'example.com',
319+
'script_name': 'index.html'
320+
}
321+
settings = OneLogin_Saml2_Settings(self.loadSettingsJSON())
322+
settings.set_strict(True)
323+
324+
logout_request = OneLogin_Saml2_Logout_Request(settings, request)
325+
326+
self.assertFalse(logout_request.is_valid(request_data))
327+
328+
with self.assertRaisesRegexp(Exception, "Invalid SAML Logout Request. Not match the saml-schema-protocol-2.0.xsd"):
329+
logout_request.is_valid(request_data, raise_exceptions=True)
330+
315331
def testIsValidSign(self):
316332
"""
317333
Tests the is_valid method of the OneLogin_Saml2_LogoutRequest

tests/src/OneLogin/saml2_tests/logout_response_test.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,23 @@ def testIsInValidDestination(self):
228228
response_4 = OneLogin_Saml2_Logout_Response(settings, message_4)
229229
self.assertTrue(response_4.is_valid(request_data))
230230

231+
def testIsValidRaisesExceptionWhenRaisesArgumentIsTrue(self):
232+
message = OneLogin_Saml2_Utils.deflate_and_base64_encode('<xml>invalid</xml>')
233+
request_data = {
234+
'http_host': 'example.com',
235+
'script_name': 'index.html',
236+
'get_data': {}
237+
}
238+
settings = OneLogin_Saml2_Settings(self.loadSettingsJSON())
239+
settings.set_strict(True)
240+
241+
response = OneLogin_Saml2_Logout_Response(settings, message)
242+
243+
self.assertFalse(response.is_valid(request_data))
244+
245+
with self.assertRaisesRegexp(Exception, "Invalid SAML Logout Response. Not match the saml-schema-protocol-2.0.xsd"):
246+
response.is_valid(request_data, raise_exceptions=True)
247+
231248
def testIsInValidSign(self):
232249
"""
233250
Tests the is_valid method of the OneLogin_Saml2_LogoutResponse

tests/src/OneLogin/saml2_tests/response_test.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1227,6 +1227,18 @@ def testIsValidEnc(self):
12271227
response_7.is_valid(request_data)
12281228
self.assertEqual('No Signature found. SAML Response rejected', response_7.get_error())
12291229

1230+
def testIsValidRaisesExceptionWhenRaisesArgumentIsTrue(self):
1231+
message = b64encode('<xml>invalid</xml>')
1232+
settings = OneLogin_Saml2_Settings(self.loadSettingsJSON())
1233+
settings.set_strict(True)
1234+
1235+
response = OneLogin_Saml2_Response(settings, message)
1236+
1237+
self.assertFalse(response.is_valid(self.get_request_data()))
1238+
1239+
with self.assertRaisesRegexp(Exception, "Unsupported SAML version"):
1240+
response.is_valid(self.get_request_data(), raise_exceptions=True)
1241+
12301242
def testIsValidSign(self):
12311243
"""
12321244
Tests the is_valid method of the OneLogin_Saml2_Response

0 commit comments

Comments
 (0)