Skip to content

Commit fec59a0

Browse files
committed
Adding get_idp_sso_url, get_idp_slo_url and get_idp_slo_response_url methods to the Settings class and use it in the toolkit
1 parent 60c8cec commit fec59a0

File tree

7 files changed

+108
-16
lines changed

7 files changed

+108
-16
lines changed

README.md

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -282,11 +282,13 @@ This is the ``settings.json`` file:
282282
}
283283
]
284284
},
285-
// Specifies info about where and how the <Logout Response> message MUST be
286-
// returned to the requester, in this case our SP.
285+
// Specifies info about where and how the <Logout Request/Response> message MUST be sent.
287286
"singleLogoutService": {
288-
// URL Location where the <Response> from the IdP will be returned
287+
// URL Location where the <LogoutRequest> from the IdP will be sent (IdP-initiated logout)
289288
"url": "https://<sp_domain>/?sls",
289+
// URL Location where the <LogoutResponse> from the IdP will sent (SP-initiated logout, reply)
290+
// OPTIONAL: only specify if different from url parameter
291+
//"responseUrl": "https://<sp_domain>/?sls",
290292
// SAML protocol binding to be used when returning the <Response>
291293
// message. OneLogin Toolkit supports the HTTP-Redirect binding
292294
// only for this endpoint.
@@ -327,8 +329,11 @@ This is the ``settings.json`` file:
327329
},
328330
// SLO endpoint info of the IdP.
329331
"singleLogoutService": {
330-
// URL Location of the IdP where SLO Request will be sent.
332+
// URL Location where the <LogoutRequest> from the IdP will be sent (IdP-initiated logout)
331333
"url": "https://app.onelogin.com/trust/saml2/http-redirect/slo/<onelogin_connector_id>",
334+
// URL Location where the <LogoutResponse> from the IdP will sent (SP-initiated logout, reply)
335+
// OPTIONAL: only specify if different from url parameter
336+
"responseUrl": "https://app.onelogin.com/trust/saml2/http-redirect/slo_return/<onelogin_connector_id>",
332337
// SAML protocol binding to be used when returning the <Response>
333338
// message. OneLogin Toolkit supports the HTTP-Redirect binding
334339
// only for this endpoint.

src/onelogin/saml2/auth.py

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -446,26 +446,30 @@ def logout(self, return_to=None, name_id=None, session_index=None, nq=None, name
446446

447447
def get_sso_url(self):
448448
"""
449-
Gets the SSO URL.
449+
Gets the IdP SSO URL.
450450
451451
:returns: An URL, the SSO endpoint of the IdP
452452
:rtype: string
453453
"""
454-
idp_data = self.__settings.get_idp_data()
455-
return idp_data['singleSignOnService']['url']
454+
return self.__settings.get_idp_sso_url()
456455

457456
def get_slo_url(self):
458457
"""
459-
Gets the SLO URL.
458+
Gets the IdP SLO URL.
460459
461460
:returns: An URL, the SLO endpoint of the IdP
462461
:rtype: string
463462
"""
464-
url = None
465-
idp_data = self.__settings.get_idp_data()
466-
if 'singleLogoutService' in idp_data.keys() and 'url' in idp_data['singleLogoutService']:
467-
url = idp_data['singleLogoutService']['url']
468-
return url
463+
return self.__settings.get_idp_slo_url()
464+
465+
def get_slo_response_url(self):
466+
"""
467+
Gets the SLO return URL for IdP-initiated logout.
468+
469+
:returns: an URL, the SLO return endpoint of the IdP
470+
:rtype: string
471+
"""
472+
return self.__settings.get_idp_slo_response_url()
469473

470474
def build_request_signature(self, saml_request, relay_state, sign_algorithm=OneLogin_Saml2_Constants.RSA_SHA1):
471475
"""

src/onelogin/saml2/logout_request.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ def __init__(self, settings, request=None, name_id=None, session_index=None, nq=
125125
{
126126
'id': uid,
127127
'issue_instant': issue_instant,
128-
'single_logout_url': idp_data['singleLogoutService']['url'],
128+
'single_logout_url': self.__settings.get_idp_slo_url(),
129129
'entity_id': sp_data['entityId'],
130130
'name_id': name_id_obj,
131131
'session_index': session_index_str,

src/onelogin/saml2/logout_response.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,6 @@ def build(self, in_response_to):
208208
:type in_response_to: string
209209
"""
210210
sp_data = self.__settings.get_sp_data()
211-
idp_data = self.__settings.get_idp_data()
212211

213212
uid = OneLogin_Saml2_Utils.generate_unique_id()
214213
issue_instant = OneLogin_Saml2_Utils.parse_time_to_SAML(OneLogin_Saml2_Utils.now())
@@ -229,7 +228,7 @@ def build(self, in_response_to):
229228
{
230229
'id': uid,
231230
'issue_instant': issue_instant,
232-
'destination': idp_data['singleLogoutService']['url'],
231+
'destination': self.__settings.get_idp_slo_response_url(),
233232
'in_response_to': in_response_to,
234233
'entity_id': sp_data['entityId'],
235234
}

src/onelogin/saml2/settings.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,8 @@ def __add_default_values(self):
259259
self.__sp.setdefault('singleLogoutService', {})
260260
self.__sp['singleLogoutService'].setdefault('binding', OneLogin_Saml2_Constants.BINDING_HTTP_REDIRECT)
261261

262+
self.__idp.setdefault('singleLogoutService', {})
263+
262264
# Related to nameID
263265
self.__sp.setdefault('NameIDFormat', OneLogin_Saml2_Constants.NAMEID_UNSPECIFIED)
264266
self.__security.setdefault('nameIdEncrypted', False)
@@ -506,6 +508,38 @@ def check_sp_certs(self):
506508
cert = self.get_sp_cert()
507509
return key is not None and cert is not None
508510

511+
def get_idp_sso_url(self):
512+
"""
513+
Gets the IdP SSO URL.
514+
515+
:returns: An URL, the SSO endpoint of the IdP
516+
:rtype: string
517+
"""
518+
idp_data = self.get_idp_data()
519+
return idp_data['singleSignOnService']['url']
520+
521+
def get_idp_slo_url(self):
522+
"""
523+
Gets the IdP SLO URL.
524+
525+
:returns: An URL, the SLO endpoint of the IdP
526+
:rtype: string
527+
"""
528+
idp_data = self.get_idp_data()
529+
if 'url' in idp_data['singleLogoutService']:
530+
return idp_data['singleLogoutService']['url']
531+
532+
def get_idp_slo_response_url(self):
533+
"""
534+
Gets the IdP SLO return URL for IdP-initiated logout.
535+
536+
:returns: an URL, the SLO return endpoint of the IdP
537+
:rtype: string
538+
"""
539+
idp_data = self.get_idp_data()
540+
if 'url' in idp_data['singleLogoutService']:
541+
return idp_data['singleLogoutService'].get('responseUrl', self.get_idp_slo_url())
542+
509543
def get_sp_key(self):
510544
"""
511545
Returns the x509 private key of the SP.

tests/src/OneLogin/saml2_tests/auth_test.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,21 @@ def testGetSLOurl(self):
7878
slo_url = settings_info['idp']['singleLogoutService']['url']
7979
self.assertEqual(auth.get_slo_url(), slo_url)
8080

81+
def testGetSLOresponseUrl(self):
82+
"""
83+
Tests the get_slo_response_url method of the OneLogin_Saml2_Auth class
84+
"""
85+
settings_info = self.loadSettingsJSON()
86+
settings_info['idp']['singleLogoutService']['responseUrl'] = "http://idp.example.com/SingleLogoutReturn.php"
87+
auth = OneLogin_Saml2_Auth(self.get_request(), old_settings=settings_info)
88+
slo_url = settings_info['idp']['singleLogoutService']['responseUrl']
89+
self.assertEqual(auth.get_slo_response_url(), slo_url)
90+
# test that the function falls back to the url setting if responseUrl is not set
91+
settings_info['idp']['singleLogoutService'].pop('responseUrl')
92+
auth = OneLogin_Saml2_Auth(self.get_request(), old_settings=settings_info)
93+
slo_url = settings_info['idp']['singleLogoutService']['url']
94+
self.assertEqual(auth.get_slo_response_url(), slo_url)
95+
8196
def testGetSessionIndex(self):
8297
"""
8398
Tests the get_session_index method of the OneLogin_Saml2_Auth class

tests/src/OneLogin/saml2_tests/settings_test.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,41 @@ def testGetSchemasPath(self):
142142
base = settings.get_base_path()
143143
self.assertEqual(join(base, 'lib', 'schemas') + sep, settings.get_schemas_path())
144144

145+
def testGetIdPSSOurl(self):
146+
"""
147+
Tests the get_idp_sso_url method of the OneLogin_Saml2_Settings class
148+
"""
149+
settings_info = self.loadSettingsJSON()
150+
settings = OneLogin_Saml2_Settings(settings_info)
151+
152+
sso_url = settings_info['idp']['singleSignOnService']['url']
153+
self.assertEqual(settings.get_idp_sso_url(), sso_url)
154+
155+
def testGetIdPSLOurl(self):
156+
"""
157+
Tests the get_idp_slo_url method of the OneLogin_Saml2_Settings class
158+
"""
159+
settings_info = self.loadSettingsJSON()
160+
settings = OneLogin_Saml2_Settings(settings_info)
161+
162+
slo_url = settings_info['idp']['singleLogoutService']['url']
163+
self.assertEqual(settings.get_idp_slo_url(), slo_url)
164+
165+
def testGetIdPSLOresponseUrl(self):
166+
"""
167+
Tests the get_idp_slo_response_url method of the OneLogin_Saml2_Settings class
168+
"""
169+
settings_info = self.loadSettingsJSON()
170+
settings_info['idp']['singleLogoutService']['responseUrl'] = "http://idp.example.com/SingleLogoutReturn.php"
171+
settings = OneLogin_Saml2_Settings(settings_info)
172+
slo_url = settings_info['idp']['singleLogoutService']['responseUrl']
173+
self.assertEqual(settings.get_idp_slo_response_url(), slo_url)
174+
# test that the function falls back to the url setting if responseUrl is not set
175+
settings_info['idp']['singleLogoutService'].pop('responseUrl')
176+
settings = OneLogin_Saml2_Settings(settings_info)
177+
slo_url = settings_info['idp']['singleLogoutService']['url']
178+
self.assertEqual(settings.get_idp_slo_response_url(), slo_url)
179+
145180
def testGetSPCert(self):
146181
"""
147182
Tests the get_sp_cert method of the OneLogin_Saml2_Settings

0 commit comments

Comments
 (0)