Skip to content

Commit 22596cb

Browse files
committed
Split the setting check methods. Now 1 method for IdP settings and other for SP settings. Related to #74.
1 parent 7991213 commit 22596cb

1 file changed

Lines changed: 145 additions & 105 deletions

File tree

src/onelogin/saml2/settings.py

Lines changed: 145 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -324,115 +324,155 @@ def check_settings(self, settings):
324324
errors = []
325325
if not isinstance(settings, dict) or len(settings) == 0:
326326
errors.append('invalid_syntax')
327-
return errors
327+
else:
328+
idp_erros = self.check_idp_settings(settings)
329+
sp_errors = self.check_sp_settings(settings)
330+
errors = idp_erros + sp_errors
331+
332+
return errors
333+
334+
def check_idp_settings(self, settings):
335+
"""
336+
Checks the IdP settings info.
328337
329-
if 'idp' not in settings or len(settings['idp']) == 0:
330-
errors.append('idp_not_found')
338+
:param settings: Dict with settings data
339+
:type settings: dict
340+
341+
:returns: Errors found on the IdP settings data
342+
:rtype: list
343+
"""
344+
assert isinstance(settings, dict)
345+
346+
errors = []
347+
if not isinstance(settings, dict) or len(settings) == 0:
348+
errors.append('invalid_syntax')
331349
else:
332-
idp = settings['idp']
333-
if 'entityId' not in idp or len(idp['entityId']) == 0:
334-
errors.append('idp_entityId_not_found')
335-
336-
if 'singleSignOnService' not in idp or \
337-
'url' not in idp['singleSignOnService'] or \
338-
len(idp['singleSignOnService']['url']) == 0:
339-
errors.append('idp_sso_not_found')
340-
elif not validate_url(idp['singleSignOnService']['url']):
341-
errors.append('idp_sso_url_invalid')
342-
343-
if 'singleLogoutService' in idp and \
344-
'url' in idp['singleLogoutService'] and \
345-
len(idp['singleLogoutService']['url']) > 0 and \
346-
not validate_url(idp['singleLogoutService']['url']):
347-
errors.append('idp_slo_url_invalid')
348-
349-
if 'sp' not in settings or len(settings['sp']) == 0:
350-
errors.append('sp_not_found')
350+
if 'idp' not in settings or len(settings['idp']) == 0:
351+
errors.append('idp_not_found')
352+
else:
353+
idp = settings['idp']
354+
if 'entityId' not in idp or len(idp['entityId']) == 0:
355+
errors.append('idp_entityId_not_found')
356+
357+
if 'singleSignOnService' not in idp or \
358+
'url' not in idp['singleSignOnService'] or \
359+
len(idp['singleSignOnService']['url']) == 0:
360+
errors.append('idp_sso_not_found')
361+
elif not validate_url(idp['singleSignOnService']['url']):
362+
errors.append('idp_sso_url_invalid')
363+
364+
if 'singleLogoutService' in idp and \
365+
'url' in idp['singleLogoutService'] and \
366+
len(idp['singleLogoutService']['url']) > 0 and \
367+
not validate_url(idp['singleLogoutService']['url']):
368+
errors.append('idp_slo_url_invalid')
369+
370+
if 'security' in settings:
371+
security = settings['security']
372+
373+
exists_x509 = ('x509cert' in idp and
374+
len(idp['x509cert']) > 0)
375+
exists_fingerprint = ('certFingerprint' in idp and
376+
len(idp['certFingerprint']) > 0)
377+
378+
want_assert_sign = 'wantAssertionsSigned' in security.keys() and security['wantAssertionsSigned']
379+
want_mes_signed = 'wantMessagesSigned' in security.keys() and security['wantMessagesSigned']
380+
nameid_enc = 'nameIdEncrypted' in security.keys() and security['nameIdEncrypted']
381+
382+
if (want_assert_sign or want_mes_signed) and \
383+
not(exists_x509 or exists_fingerprint):
384+
errors.append('idp_cert_or_fingerprint_not_found_and_required')
385+
if nameid_enc and not exists_x509:
386+
errors.append('idp_cert_not_found_and_required')
387+
388+
return errors
389+
390+
def check_sp_settings(self, settings):
391+
"""
392+
Checks the SP settings info.
393+
394+
:param settings: Dict with settings data
395+
:type settings: dict
396+
397+
:returns: Errors found on the SP settings data
398+
:rtype: list
399+
"""
400+
assert isinstance(settings, dict)
401+
402+
errors = []
403+
if not isinstance(settings, dict) or len(settings) == 0:
404+
errors.append('invalid_syntax')
351405
else:
352-
# check_sp_certs uses self.__sp so I add it
353-
old_sp = self.__sp
354-
self.__sp = settings['sp']
406+
if 'sp' not in settings or len(settings['sp']) == 0:
407+
errors.append('sp_not_found')
408+
else:
409+
# check_sp_certs uses self.__sp so I add it
410+
old_sp = self.__sp
411+
self.__sp = settings['sp']
412+
413+
sp = settings['sp']
414+
security = {}
415+
if 'security' in settings:
416+
security = settings['security']
417+
418+
if 'entityId' not in sp or len(sp['entityId']) == 0:
419+
errors.append('sp_entityId_not_found')
420+
421+
if 'assertionConsumerService' not in sp or \
422+
'url' not in sp['assertionConsumerService'] or \
423+
len(sp['assertionConsumerService']['url']) == 0:
424+
errors.append('sp_acs_not_found')
425+
elif not validate_url(sp['assertionConsumerService']['url']):
426+
errors.append('sp_acs_url_invalid')
427+
428+
if 'singleLogoutService' in sp and \
429+
'url' in sp['singleLogoutService'] and \
430+
len(sp['singleLogoutService']['url']) > 0 and \
431+
not validate_url(sp['singleLogoutService']['url']):
432+
errors.append('sp_sls_url_invalid')
433+
434+
if 'signMetadata' in security and isinstance(security['signMetadata'], dict):
435+
if 'keyFileName' not in security['signMetadata'] or \
436+
'certFileName' not in security['signMetadata']:
437+
errors.append('sp_signMetadata_invalid')
438+
439+
authn_sign = 'authnRequestsSigned' in security.keys() and security['authnRequestsSigned']
440+
logout_req_sign = 'logoutRequestSigned' in security.keys() and security['logoutRequestSigned']
441+
logout_res_sign = 'logoutResponseSigned' in security.keys() and security['logoutResponseSigned']
442+
want_assert_enc = 'wantAssertionsEncrypted' in security.keys() and security['wantAssertionsEncrypted']
443+
want_nameid_enc = 'wantNameIdEncrypted' in security.keys() and security['wantNameIdEncrypted']
444+
445+
if not self.check_sp_certs():
446+
if authn_sign or logout_req_sign or logout_res_sign or \
447+
want_assert_enc or want_nameid_enc:
448+
errors.append('sp_cert_not_found_and_required')
355449

356-
sp = settings['sp']
357-
security = {}
358-
if 'security' in settings:
359-
security = settings['security']
360-
361-
if 'entityId' not in sp or len(sp['entityId']) == 0:
362-
errors.append('sp_entityId_not_found')
363-
364-
if 'assertionConsumerService' not in sp or \
365-
'url' not in sp['assertionConsumerService'] or \
366-
len(sp['assertionConsumerService']['url']) == 0:
367-
errors.append('sp_acs_not_found')
368-
elif not validate_url(sp['assertionConsumerService']['url']):
369-
errors.append('sp_acs_url_invalid')
370-
371-
if 'singleLogoutService' in sp and \
372-
'url' in sp['singleLogoutService'] and \
373-
len(sp['singleLogoutService']['url']) > 0 and \
374-
not validate_url(sp['singleLogoutService']['url']):
375-
errors.append('sp_sls_url_invalid')
376-
377-
if 'signMetadata' in security and isinstance(security['signMetadata'], dict):
378-
if 'keyFileName' not in security['signMetadata'] or \
379-
'certFileName' not in security['signMetadata']:
380-
errors.append('sp_signMetadata_invalid')
381-
382-
authn_sign = 'authnRequestsSigned' in security.keys() and security['authnRequestsSigned']
383-
logout_req_sign = 'logoutRequestSigned' in security.keys() and security['logoutRequestSigned']
384-
logout_res_sign = 'logoutResponseSigned' in security.keys() and security['logoutResponseSigned']
385-
want_assert_enc = 'wantAssertionsEncrypted' in security.keys() and security['wantAssertionsEncrypted']
386-
want_nameid_enc = 'wantNameIdEncrypted' in security.keys() and security['wantNameIdEncrypted']
387-
388-
if not self.check_sp_certs():
389-
if authn_sign or logout_req_sign or logout_res_sign or \
390-
want_assert_enc or want_nameid_enc:
391-
errors.append('sp_cert_not_found_and_required')
392-
393-
exists_x509 = ('idp' in settings and
394-
'x509cert' in settings['idp'] and
395-
len(settings['idp']['x509cert']) > 0)
396-
exists_fingerprint = ('idp' in settings and
397-
'certFingerprint' in settings['idp'] and
398-
len(settings['idp']['certFingerprint']) > 0)
399-
400-
want_assert_sign = 'wantAssertionsSigned' in security.keys() and security['wantAssertionsSigned']
401-
want_mes_signed = 'wantMessagesSigned' in security.keys() and security['wantMessagesSigned']
402-
nameid_enc = 'nameIdEncrypted' in security.keys() and security['nameIdEncrypted']
403-
404-
if (want_assert_sign or want_mes_signed) and \
405-
not(exists_x509 or exists_fingerprint):
406-
errors.append('idp_cert_or_fingerprint_not_found_and_required')
407-
if nameid_enc and not exists_x509:
408-
errors.append('idp_cert_not_found_and_required')
409-
410-
if 'contactPerson' in settings:
411-
types = settings['contactPerson'].keys()
412-
valid_types = ['technical', 'support', 'administrative', 'billing', 'other']
413-
for c_type in types:
414-
if c_type not in valid_types:
415-
errors.append('contact_type_invalid')
416-
break
417-
418-
for c_type in settings['contactPerson']:
419-
contact = settings['contactPerson'][c_type]
420-
if ('givenName' not in contact or len(contact['givenName']) == 0) or \
421-
('emailAddress' not in contact or len(contact['emailAddress']) == 0):
422-
errors.append('contact_not_enought_data')
423-
break
424-
425-
if 'organization' in settings:
426-
for org in settings['organization']:
427-
organization = settings['organization'][org]
428-
if ('name' not in organization or len(organization['name']) == 0) or \
429-
('displayname' not in organization or len(organization['displayname']) == 0) or \
430-
('url' not in organization or len(organization['url']) == 0):
431-
errors.append('organization_not_enought_data')
432-
break
433-
# Restores the value that had the self.__sp
434-
if 'old_sp' in locals():
435-
self.__sp = old_sp
450+
if 'contactPerson' in settings:
451+
types = settings['contactPerson'].keys()
452+
valid_types = ['technical', 'support', 'administrative', 'billing', 'other']
453+
for c_type in types:
454+
if c_type not in valid_types:
455+
errors.append('contact_type_invalid')
456+
break
457+
458+
for c_type in settings['contactPerson']:
459+
contact = settings['contactPerson'][c_type]
460+
if ('givenName' not in contact or len(contact['givenName']) == 0) or \
461+
('emailAddress' not in contact or len(contact['emailAddress']) == 0):
462+
errors.append('contact_not_enought_data')
463+
break
464+
465+
if 'organization' in settings:
466+
for org in settings['organization']:
467+
organization = settings['organization'][org]
468+
if ('name' not in organization or len(organization['name']) == 0) or \
469+
('displayname' not in organization or len(organization['displayname']) == 0) or \
470+
('url' not in organization or len(organization['url']) == 0):
471+
errors.append('organization_not_enought_data')
472+
break
473+
# Restores the value that had the self.__sp
474+
if 'old_sp' in locals():
475+
self.__sp = old_sp
436476

437477
return errors
438478

0 commit comments

Comments
 (0)