Skip to content

Commit ab62b0d

Browse files
authored
Merge pull request #280 from guneskaan/get-last-assertion-issue-instant
Implement get_last_assertion_issue_instant()
2 parents 8a47e70 + 149a466 commit ab62b0d

File tree

4 files changed

+27
-1
lines changed

4 files changed

+27
-1
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -970,6 +970,7 @@ Main class of OneLogin Python Toolkit
970970
* ***get_last_message_id*** The ID of the last Response SAML message processed.
971971
* ***get_last_assertion_id*** The ID of the last assertion processed.
972972
* ***get_last_assertion_not_on_or_after*** The ``NotOnOrAfter`` value of the valid ``SubjectConfirmationData`` node (if any) of the last assertion processed (is only calculated with strict = true)
973+
* ***get_last_assertion_issue_instant*** The `IssueInstant` value of the last assertion processed.
973974

974975
#### OneLogin_Saml2_Auth - authn_request.py ####
975976

src/onelogin/saml2/auth.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ def __init__(self, request_data, old_settings=None, custom_base_path=None):
7171
self._last_request_id = None
7272
self._last_message_id = None
7373
self._last_assertion_id = None
74+
self._last_assertion_issue_instant = None
7475
self._last_authn_contexts = []
7576
self._last_request = None
7677
self._last_response = None
@@ -105,6 +106,7 @@ def store_valid_response(self, response):
105106
self._session_expiration = response.get_session_not_on_or_after()
106107
self._last_message_id = response.get_id()
107108
self._last_assertion_id = response.get_assertion_id()
109+
self._last_assertion_issue_instant = response.get_assertion_issue_instant()
108110
self._last_authn_contexts = response.get_authn_contexts()
109111
self._authenticated = True
110112
self._last_assertion_not_on_or_after = response.get_assertion_not_on_or_after()
@@ -373,6 +375,13 @@ def get_last_assertion_id(self):
373375
"""
374376
return self._last_assertion_id
375377

378+
def get_last_assertion_issue_instant(self):
379+
"""
380+
:returns: The IssueInstant of the last assertion processed.
381+
:rtype: unix/posix timestamp|None
382+
"""
383+
return self._last_assertion_issue_instant
384+
376385
def get_last_authn_contexts(self):
377386
"""
378387
:returns: The list of authentication contexts sent in the last SAML Response.

src/onelogin/saml2/response.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -917,3 +917,16 @@ def get_assertion_id(self):
917917
OneLogin_Saml2_ValidationError.WRONG_NUMBER_OF_ASSERTIONS
918918
)
919919
return self._query_assertion('')[0].get('ID', None)
920+
921+
def get_assertion_issue_instant(self):
922+
"""
923+
:returns: the IssueInstant of the assertion in the response
924+
:rtype: unix/posix timestamp|None
925+
"""
926+
if not self.validate_num_assertions():
927+
raise OneLogin_Saml2_ValidationError(
928+
'SAML Response must contain 1 assertion',
929+
OneLogin_Saml2_ValidationError.WRONG_NUMBER_OF_ASSERTIONS
930+
)
931+
issue_instant = self._query_assertion('')[0].get('IssueInstant', None)
932+
return OneLogin_Saml2_Utils.parse_SAML_to_time(issue_instant)

tests/src/OneLogin/saml2_tests/auth_test.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1415,7 +1415,7 @@ def testGetLastLogoutResponse(self):
14151415

14161416
def testGetInfoFromLastResponseReceived(self):
14171417
"""
1418-
Tests the get_last_message_id, get_last_assertion_id and get_last_assertion_not_on_or_after
1418+
Tests the get_last_message_id, get_last_assertion_id, get_last_assertion_not_on_or_after and get_last_assertion_issue_instant
14191419
of the OneLogin_Saml2_Auth class
14201420
"""
14211421
settings = self.loadSettingsJSON()
@@ -1431,6 +1431,7 @@ def testGetInfoFromLastResponseReceived(self):
14311431
self.assertEqual(auth.get_last_message_id(), 'pfx42be40bf-39c3-77f0-c6ae-8bf2e23a1a2e')
14321432
self.assertEqual(auth.get_last_assertion_id(), 'pfx57dfda60-b211-4cda-0f63-6d5deb69e5bb')
14331433
self.assertIsNone(auth.get_last_assertion_not_on_or_after())
1434+
self.assertEqual(auth.get_last_assertion_issue_instant(), 1392773821)
14341435

14351436
# NotOnOrAfter is only calculated with strict = true
14361437
# If invalid, response id and assertion id are not obtained
@@ -1442,6 +1443,7 @@ def testGetInfoFromLastResponseReceived(self):
14421443
self.assertIsNone(auth.get_last_message_id())
14431444
self.assertIsNone(auth.get_last_assertion_id())
14441445
self.assertIsNone(auth.get_last_assertion_not_on_or_after())
1446+
self.assertIsNone(auth.get_last_assertion_issue_instant())
14451447

14461448
request_data['https'] = 'on'
14471449
request_data['http_host'] = 'pitbulk.no-ip.org'
@@ -1452,6 +1454,7 @@ def testGetInfoFromLastResponseReceived(self):
14521454
self.assertEqual(auth.get_last_message_id(), 'pfx42be40bf-39c3-77f0-c6ae-8bf2e23a1a2e')
14531455
self.assertEqual(auth.get_last_assertion_id(), 'pfx57dfda60-b211-4cda-0f63-6d5deb69e5bb')
14541456
self.assertEqual(auth.get_last_assertion_not_on_or_after(), 2671081021)
1457+
self.assertEqual(auth.get_last_assertion_issue_instant(), 1392773821)
14551458

14561459
def testGetIdFromLogoutRequest(self):
14571460
"""

0 commit comments

Comments
 (0)