diff --git a/api.py b/api.py index 75f5a53516c914480327142837160fe17140c2db..04405ce850d58e5ff0aeb4194c653df6f1e0776e 100755 --- a/api.py +++ b/api.py @@ -153,12 +153,12 @@ class EccsResults(Resource): # IdP-RegAuth; check[2] # IdP-tech-ctc-1,IdP-tech-ctc-2; check[3] # IdP-supp-ctc-1,IdP-supp-ctc-2; check[4] - # Status; check[5] - # SP-entityID-1; check[6] + # ECCS Status; check[5] + # SP-wayfless-url-1; check[6] # SP-check-time-1; check[7] # SP-status-code-1; check[8] # SP-status-1; check[9] - # SP-entityID-2; check[10] + # SP-wayfless-url-2; check[10] # SP-check-time-2; check[11] # SP-status-code-2 check[12] # SP-status-2 check[13] @@ -169,19 +169,19 @@ class EccsResults(Resource): idp_reg_auth = check[2] idp_tech_ctcs = check[3] idp_supp_ctcs = check[4] - idp_checks_status = check[5] - sp1_entity_id = check[6] + idp_eccs_status = check[5] + sp1_wayfless_url = check[6] sp1_check_time = check[7] sp1_status_code = check[8] sp1_check_status = check[9] - sp2_entity_id = check[10] + sp2_wayfless_url = check[10] sp2_check_time = check[11] sp2_status_code = check[12] sp2_check_status = check[13].rstrip("\n\r") if (idp and status): app.logger.info("eccsresults: check for 'idp':'%s' with 'status':'%s'" % (idp, status)) - if (idp == idp_entity_id and status == idp_checks_status): + if (idp == idp_entity_id and status == idp_eccs_status): result.append( { 'displayName' : idp_displayname, @@ -193,18 +193,18 @@ class EccsResults(Resource): }, 'date' : date, 'sp1' : { - 'entityID' : sp1_entity_id, + 'wayfless_url' : sp1_wayfless_url, 'checkTime' : sp1_check_time, 'statusCode' : sp1_status_code, 'status' : sp1_check_status }, 'sp2' : { - 'entityID' : sp2_entity_id, + 'wayflessUrl' : sp2_wayfless_url, 'checkTime' : sp2_check_time, 'statusCode' : sp2_status_code, 'status' : sp2_check_status }, - 'status' : idp_checks_status + 'status' : idp_eccs_status } ) elif (idp): #app.logger.info(re.search(".*."+idp+".*.", idp_entity_id, re.IGNORECASE)) @@ -222,22 +222,22 @@ class EccsResults(Resource): }, 'date' : date, 'sp1' : { - 'entityID' : sp1_entity_id, + 'wayflessUrl' : sp1_wayfless_url, 'checkTime' : sp1_check_time, 'statusCode' : sp1_status_code, 'status' : sp1_check_status }, 'sp2' : { - 'entityID' : sp2_entity_id, + 'wayflessUrl' : sp2_wayfless_url, 'checkTime' : sp2_check_time, 'statusCode' : sp2_status_code, 'status' : sp2_check_status }, - 'status' : idp_checks_status + 'status' : idp_eccs_status } ) elif (status): app.logger.info("eccsresults: Search for 'status':'%s'." % status) - if (status == idp_checks_status): + if (status == idp_eccs_status): result.append( { 'displayName' : idp_displayname, @@ -249,18 +249,18 @@ class EccsResults(Resource): }, 'date' : date, 'sp1' : { - 'entityID' : sp1_entity_id, + 'wayflessUrl' : sp1_wayfless_url, 'checkTime' : sp1_check_time, 'statusCode' : sp1_status_code, 'status' : sp1_check_status }, 'sp2' : { - 'entityID' : sp2_entity_id, + 'wayflessUrl' : sp2_wayfless_url, 'checkTime' : sp2_check_time, 'statusCode' : sp2_status_code, 'status' : sp2_check_status }, - 'status' : idp_checks_status + 'status' : idp_eccs_status } ) else: result.append( @@ -274,18 +274,18 @@ class EccsResults(Resource): }, 'date' : date, 'sp1' : { - 'entityID' : sp1_entity_id, + 'wayflessUrl' : sp1_wayfless_url, 'checkTime' : sp1_check_time, 'statusCode' : sp1_status_code, 'status' : sp1_check_status }, 'sp2' : { - 'entityID' : sp2_entity_id, + 'wayflessUrl' : sp2_wayfless_url, 'checkTime' : sp2_check_time, 'statusCode' : sp2_status_code, 'status' : sp2_check_status }, - 'status' : idp_checks_status + 'status' : idp_eccs_status } ) if (pretty): diff --git a/eccs2.py b/eccs2.py index 8836a6527616eee5f5ee5b120aeb29dbbf3eec16..8402bd62bee7a8686f6913ce437b458740ceed2f 100755 --- a/eccs2.py +++ b/eccs2.py @@ -25,6 +25,14 @@ The script has been written to simulate an user that inserts the IdP's entityID If the IdP Login page presente the fields for both selected SP the test is passed, otherwise it is failed. """ +# Returns the FQDN to use on the HTML page_source files +def getIDPfqdn(entityIDidp): + if entityIDidp.startswith('http'): + return parse_url(entityIDidp)[2] + else: + return entityIDidp.split(":")[-1] + + # The function check that the IdP recognized the SP by presenting its Login page. # If the IdP Login page contains "username" and "password" fields, than the test is passed. def checkIdP(sp,idp): @@ -45,32 +53,40 @@ def checkIdP(sp,idp): federation_blacklist = FEDS_BLACKLIST entities_blacklist = IDPS_BLACKLIST + fqdn_idp = getIDPfqdn(idp['entityID']) + fqdn_sp = parse_url(sp)[2] + wayfless_url = sp + idp['entityID'] + if (idp['registrationAuthority'] in federation_blacklist): check_time = datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S') + 'Z' - return (idp['entityID'],sp,check_time,"NULL","DISABLED") + + with open("%s/%s/%s---%s.html" % (ECCS2HTMLDIR,DAY,fqdn_idp,fqdn_sp),"w") as html: + html.write("Federation excluded from check") + return (idp['entityID'],wayfless_url,check_time,"NULL","DISABLED") if (idp['entityID'] in entities_blacklist): check_time = datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S') + 'Z' - return (idp['entityID'],sp,check_time,"NULL","DISABLED") + + with open("%s/%s/%s---%s.html" % (ECCS2HTMLDIR,DAY,fqdn_idp,fqdn_sp),"w") as html: + html.write("Identity Provider excluded from check") + return (idp['entityID'],wayfless_url,check_time,"NULL","DISABLED") # Open SP, select the IDP from the EDS and press 'Enter' to reach the IdP login page to check try: check_time = datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S') + 'Z' - driver.get(sp) - element = WebDriverWait(driver, 50).until(EC.presence_of_element_located((By.ID,"idpSelectInput"))) - element.send_keys(idp['entityID'] + Keys.ENTER) + driver.get(wayfless_url) page_source = driver.page_source samlrequest_url = driver.current_url - # Put the page_source into its HTML file - Path("%s/%s" % (ECCS2HTMLDIR,DAY)).mkdir(parents=True, exist_ok=True) - fqdn_idp = parse_url(idp['entityID'])[2] - fqdn_sp = parse_url(sp)[2] + # Put the page_source into an appropriate HTML file with open("%s/%s/%s---%s.html" % (ECCS2HTMLDIR,DAY,fqdn_idp,fqdn_sp),"w") as html: html.write(page_source) except TimeoutException as e: - return (idp['entityID'],sp,check_time,"(failed)","Timeout") + # Put an empty string into the page_source file + with open("%s/%s/%s---%s.html" % (ECCS2HTMLDIR,DAY,fqdn_idp,fqdn_sp),"w") as html: + html.write("") + return (idp['entityID'],wayfless_url,check_time,"(failed)","Timeout") except NoSuchElementException as e: # The input of the bootstrap tables are provided by "eccs2" and "eccs2checks" log. @@ -142,13 +158,14 @@ def checkIdP(sp,idp): status_code = "555" if(metadata_not_found): - return (idp['entityID'],sp,check_time,status_code,"No-eduGAIN-Metadata") + return (idp['entityID'],wayfless_url,check_time,status_code,"No-eduGAIN-Metadata") elif not username_found or not password_found: - return (idp['entityID'],sp,check_time,status_code,"Invalid-Form") + return (idp['entityID'],wayfless_url,check_time,status_code,"Invalid-Form") else: - return (idp['entityID'],sp,check_time,status_code,"OK") + return (idp['entityID'],wayfless_url,check_time,status_code,"OK") +# Extract IdP DisplayName by fixing input string def getDisplayName(display_name): display_name_equal_splitted = display_name.split('==') for elem in display_name_equal_splitted: @@ -170,7 +187,7 @@ def storeECCS2result(idp,check_results,idp_status): str_technical_contacts = ','.join(list_technical_contacts) str_support_contacts = ','.join(list_support_contacts) - # IdP-DisplayName;IdP-entityID;IdP-RegAuth;IdP-tech-ctc-1,IdP-tech-ctc-2;IdP-supp-ctc-1,IdP-supp-ctc-2;Status;SP-entityID-1;SP-check-time-1;SP-status-code-1;SP-result-1;SP-entityID-2;SP-check-time-2;SP-status-code-2;SP-result-2 + # IdP-DisplayName;IdP-entityID;IdP-RegAuth;IdP-tech-ctc-1,IdP-tech-ctc-2;IdP-supp-ctc-1,IdP-supp-ctc-2;Status;SP-wayfless-url-1;SP-check-time-1;SP-status-code-1;SP-result-1;SP-wayfless-url-2;SP-check-time-2;SP-status-code-2;SP-result-2 with open("%s/%s" % (ECCS2OUTPUTDIR,ECCS2RESULTSLOG), 'a') as f: f.write("%s;%s;%s;%s;%s;%s;%s;%s;%s;%s;%s;%s;%s;%s\n" % ( getDisplayName(idp['displayname']), # IdP-DisplayName @@ -179,11 +196,11 @@ def storeECCS2result(idp,check_results,idp_status): str_technical_contacts, # IdP-TechCtcsList str_support_contacts, # IdP-SuppCtcsList idp_status, # IdP-ECCS-Status - check_results[0][1], # SP-entityID-1 + check_results[0][1], # SP-wayfless-url-1 check_results[0][2], # SP-check-time-1 check_results[0][3], # SP-status-code-1 check_results[0][4], # SP-result-1 - check_results[1][1], # SP-entityID-2 + check_results[1][1], # SP-wayfless-url-2 check_results[1][2], # SP-check-time-2 check_results[1][3], # SP-status-code-2 check_results[1][4])) # SP-result-2 @@ -194,8 +211,6 @@ def check(idp,sps): check_results = [] for sp in sps: result = checkIdP(sp,idp) - # Se il checkIdP ha successo, aggiungo alla lista dei check - # altrimenti no. if result is not None: check_results.append(result) @@ -228,4 +243,6 @@ if __name__=="__main__": idp = json.loads(args.idpJson[0]) + Path("%s/%s" % (ECCS2HTMLDIR,DAY)).mkdir(parents=True, exist_ok=True) # Create dir needed to page_source content + check(idp,sps) diff --git a/eccs2properties.py b/eccs2properties.py index 416cb8cdc0eb5b248455a27e79292f7a94607bb8..066a38812a15e009a1c44ae726c738c87b366d18 100644 --- a/eccs2properties.py +++ b/eccs2properties.py @@ -32,10 +32,10 @@ ECCS2STDERR = "%s/stderr_%s.log" % (ECCS2LOGSDIR,DAY) ECCS2FAILEDCMD = "%s/failed-cmd.sh" % ECCS2LOGSDIR # Number of processes to run in parallel -ECCS2NUMPROCESSES = 20 +ECCS2NUMPROCESSES = 25 # The 2 SPs that will be used to test each IdP -ECCS2SPS = ["https://sp24-test.garr.it/secure", "https://attribute-viewer.aai.switch.ch/eds/"] +ECCS2SPS = ["https://sp24-test.garr.it/Shibboleth.sso/Login?entityID=", "https://attribute-viewer.aai.switch.ch/Shibboleth.sso/Login?entityID="] # Registration Authority of Federations to exclude from the check FEDS_BLACKLIST = [ @@ -46,21 +46,24 @@ FEDS_BLACKLIST = [ # EntityID of IDPs to exclude from the check IDPS_BLACKLIST = [ - 'https://iif.iucc.ac.il/idp/saml2/idp/metadata.php', + 'https://idp.eie.gr/idp/shibboleth', + 'https://edugain-proxy.igtf.net/simplesaml/saml2/idp/metadata.php', + 'https://gn-vho.grnet.gr/idp/shibboleth', + 'https://wtc.tu-chemnitz.de/shibboleth', + 'https://idp.utorauth.utoronto.ca/shibboleth', 'https://login.lstonline.ac.uk/idp/pingfederate', - 'https://idp.pearsoncollege.com/openathens', 'https://idp.cambria.ac.uk/openathens', - 'https://idp.wnsc.ac.uk/idp/shibboleth', 'https://indiid.net/idp/shibboleth', 'https://idp.nulc.ac.uk/openathens', 'https://lc-idp.lincolncollege.ac.uk/shibboleth', - 'https://oa-idp.wlv.ac.uk/oala/metadata', - 'https://idp.uel.ac.uk/shibboleth', + 'https://boleth.chi.ac.uk/idp/shibboleth', + 'https://idp.wnsc.ac.uk/idp/shibboleth', + 'https://idp.strodes.ac.uk/shibboleth', 'https://idp.ucreative.ac.uk/shibboleth', 'https://idp.llandrillo.ac.uk/shibboleth', + 'https://idp.uel.ac.uk/shibboleth', 'https://idp-dev.cardiff.ac.uk/idp/shibboleth', - 'https://idp.kingston.ac.uk/shibboleth', # iframe to load - 'https://shibboleth.aber.ac.uk/shibboleth', - 'https://sso.vu.lt/SSO/saml2/idp/metadata.php', # no standard login page - 'urn:mace:federation.org.au:testfed:uq.edu.au' + 'https://sso.vu.lt/SSO/saml2/idp/metadata.php', + #'https://ssl.education.lu/saml/saml2/idp/metadata.php', + 'https://iif.iucc.ac.il/idp/saml2/idp/metadata.php' ] diff --git a/web/script.js b/web/script.js index 8460a7223efc5282f19234ae061f678e785fc2cb..817f2b9767a24e37df8d6fe573b9bce6e4ee036e 100644 --- a/web/script.js +++ b/web/script.js @@ -1,7 +1,12 @@ // use URL constructor and return hostname function getHostname(url) { const urlNew = new URL(url); - return urlNew.hostname; + if (urlNew.hostname){ + return urlNew.hostname; + } + else { + return url.replace(/.+:/g, ''); + } } /* Formatting function for row details - modify as you need */ @@ -20,25 +25,28 @@ function format ( d ) { '<td>Support Contacts:</td>'+ '<td>'+d.contacts.support+'</td>'+ '<td>Check Time</td>'+ - '<td>Status Code</td>'+ '<td>Result Check</td>'+ + '<td>Status Code</td>'+ '<td>Page Source</td>'+ + '<td>Retry Check</td>'+ '</tr>'+ '<tr>'+ '<td>SP1:</td>'+ - '<td>'+d.sp1.entityID+'</td>'+ + '<td>https://'+getHostname(d.sp1.wayflessUrl)+'</td>'+ '<td>'+d.sp1.checkTime+'</td>'+ - '<td>'+d.sp1.statusCode+'</td>'+ '<td>'+d.sp1.status+'</td>'+ - '<td><a href="/eccs2html/'+d.date+'/'+getHostname(d.entityID)+'---'+getHostname(d.sp1.entityID)+'.html" target="_blank">Click to open</a></td>'+ + '<td>'+d.sp1.statusCode+'</td>'+ + '<td><a href="/eccs2html/'+d.date+'/'+getHostname(d.entityID)+'---'+getHostname(d.sp1.wayflessUrl)+'.html" target="_blank">Click to open</a></td>'+ + '<td><a href="'+d.sp1.wayflessUrl+'" target="_blank">Click to retry</a></td>'+ '</tr>'+ '<tr>'+ '<td>SP2:</td>'+ - '<td>'+d.sp2.entityID+'</td>'+ + '<td>https://'+getHostname(d.sp2.wayflessUrl)+'</td>'+ '<td>'+d.sp2.checkTime+'</td>'+ - '<td>'+d.sp2.statusCode+'</td>'+ '<td>'+d.sp2.status+'</td>'+ - '<td><a href="/eccs2html/'+d.date+'/'+getHostname(d.entityID)+'---'+getHostname(d.sp2.entityID)+'.html" target="_blank">Click to open</a></td>'+ + '<td>'+d.sp2.statusCode+'</td>'+ + '<td><a href="/eccs2html/'+d.date+'/'+getHostname(d.entityID)+'---'+getHostname(d.sp2.wayflessUrl)+'.html" target="_blank">Click to open</a></td>'+ + '<td><a href="'+d.sp2.wayflessUrl+'" target="_blank">Click to retry</a></td>'+ '</tr>'+ '</table>'; }