Skip to content
Snippets Groups Projects
Commit 0cecf43b authored by Marco Malavolti's avatar Marco Malavolti
Browse files

Fixed encoding and Web GUI

parent 7bc48f56
No related branches found
No related tags found
No related merge requests found
# HOWTO Install and Configure ECCS-2
* `sudo apt install python3 python3-pip chromium chromium-l10n git`
* `sudo apt install python3 python3-pip chromium chromium-l10n git libapache2-mod-wsgi python3-dev`
* `python3 -m pip install --user --upgrade pip virtualenv`
* `python3 -m venv eccs2venv`
* `source eccs2venv/bin/activate` (`deactivate` di exit Virtualenv)
......@@ -11,7 +11,7 @@
# API
* `/eccs/test` (Trivial Test)
* `/eccs/checks` (Should return the results of the last checks)
* `/eccs/checks` (Return the results of the last checks)
* `/eccs/checks?<parameter>=<value>`:
* `date=2020-02-20` (select date)
* `idp=Any%20words%20do%20you%20like%20url%20encoded`
......@@ -21,7 +21,10 @@
* 'No-eduGAIN-Metadata'
* 'Form-Invalid'
* 'Excluded'
* /eccs/eccsresults (Return the results of the last check ready for ECCS Gui)
# API Development Server
* `sudo apt install libapache2-mod-wsgi-py3 python3-dev`
* `sudo a2enmod wsgi`
* `cd ~/eccs2 ; ./api.py`
......@@ -88,7 +88,7 @@ class Checks(Resource):
idp = request.args['idp']
app.logger.info(idp)
fo = open(file_path, "r")
fo = open(file_path,"r",encoding="utf-8")
result = []
lines = fo.readlines()
......@@ -138,12 +138,180 @@ class Checks(Resource):
return jsonify(pp_json)
else:
return jsonify(result)
# Build Email Addresses Link for ECCS2 Web Gui
def buildEmailAddress(listContacts):
listCtcs = listContacts.split(",")
hrefList = []
for email in listCtcs:
hrefList.append("<a href='%s'>%s</a>" % (email,email.replace('mailto:', '')))
return hrefList
class EccsResults(Resource):
def get(self):
app.logger.info("Request 'EccsResults'")
file_path = "logs/eccs2_2020-03-01.log"
date = PurePath(file_path).parts[-1].split('_')[1].split('.')[0]
pretty = 0
status = None
idp = None
if 'date' in request.args:
app.logger.info("'date' parameter inserted")
file_path = "logs/eccs2_"+request.args['date']+".log"
date = request.args['date']
if 'pretty' in request.args:
app.logger.info("'pretty' parameter inserted")
pretty = request.args['pretty']
if 'status' in request.args:
app.logger.info("'status' parameter inserted")
status = request.args['status']
if 'idp' in request.args:
app.logger.info("'idp' parameter inserted")
idp = request.args['idp']
app.logger.info(idp)
fo = open(file_path,"r",encoding="utf-8")
result = []
lines = fo.readlines()
for line in lines:
# Line:
# IdP-DisplayName; check[0]
# IdP-entityID; check[1]
# 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]
# SP-status-1; check[7]
# SP-entityID-2; check[8]
# SP-status-2 check[9]
check = line.split(";")
idp_displayname = check[0].rstrip("\n\r")
idp_entity_id = check[1].rstrip("\n\r")
idp_reg_auth = check[2].rstrip("\n\r")
idp_tech_ctcs = check[3].rstrip("\n\r")
idp_supp_ctcs = check[4].rstrip("\n\r")
idp_checks_status = check[5].rstrip("\n\r")
sp1_entity_id = check[6].rstrip("\n\r")
sp1_check_status = check[7].rstrip("\n\r")
sp2_entity_id = check[8].rstrip("\n\r")
sp2_check_status = check[9].rstrip("\n\r")
if (idp and status):
app.logger.info("Results for the idp '%s' with status '%s'" % (idp, status))
if (idp == idp_entity_id and status == idp_checks_status):
result.append(
{
'displayName' : idp_displayname,
'entityID' : idp_entity_id,
'registrationAuthority' : idp_reg_auth,
'contacts' : {
'technical' : buildEmailAddress(idp_tech_ctcs),
'support' : buildEmailAddress(idp_supp_ctcs),
},
'date' : date,
'sp1' : {
'entityID' : sp1_entity_id,
'status' : sp1_check_status
},
'sp2' : {
'entityID' : sp2_entity_id,
'status' : sp2_check_status
},
'status' : idp_checks_status
} )
elif (idp):
#app.logger.info(re.search(".*."+idp+".*.", idp_entity_id, re.IGNORECASE))
#app.logger.info(idp_entity_id))
app.logger.info("Results for IdP '%s'." % idp)
if (re.search(".*."+idp+".*.", idp_entity_id, re.IGNORECASE)):
result.append(
{
'displayName' : idp_displayname,
'entityID' : idp_entity_id,
'registrationAuthority' : idp_reg_auth,
'contacts' : {
'technical' : buildEmailAddress(idp_tech_ctcs),
'support' : buildEmailAddress(idp_supp_ctcs),
},
'date' : date,
'sp1' : {
'entityID' : sp1_entity_id,
'status' : sp1_check_status
},
'sp2' : {
'entityID' : sp2_entity_id,
'status' : sp2_check_status
},
'status' : idp_checks_status
} )
elif (status):
app.logger.info("Results for status '%s'." % status)
if (status == idp_checks_status):
result.append(
{
'displayName' : idp_displayname,
'entityID' : idp_entity_id,
'registrationAuthority' : idp_reg_auth,
'contacts' : {
'technical' : buildEmailAddress(idp_tech_ctcs),
'support' : buildEmailAddress(idp_supp_ctcs),
},
'date' : date,
'sp1' : {
'entityID' : sp1_entity_id,
'status' : sp1_check_status
},
'sp2' : {
'entityID' : sp2_entity_id,
'status' : sp2_check_status
},
'status' : idp_checks_status
} )
else:
app.logger.info("All checks.")
result.append(
{
'displayName' : idp_displayname,
'entityID' : idp_entity_id,
'registrationAuthority' : idp_reg_auth,
'contacts' : {
'technical' : buildEmailAddress(idp_tech_ctcs),
'support' : buildEmailAddress(idp_supp_ctcs),
},
'date' : date,
'sp1' : {
'entityID' : sp1_entity_id,
'status' : sp1_check_status
},
'sp2' : {
'entityID' : sp2_entity_id,
'status' : sp2_check_status
},
'status' : idp_checks_status
} )
if (pretty):
pp_json = dumps(result, indent=4, sort_keys=True)
return jsonify(pp_json)
else:
return jsonify(result)
api.add_resource(Test, '/eccs/test') # Route_1
api.add_resource(Checks, '/eccs/checks') # Route_2
api.add_resource(EccsResults, '/eccs/eccsresults') # Route_3
if __name__ == '__main__':
app.config['JSON_AS_ASCII'] = False
app.logger = getLogger("logs/eccs2api.log","INFO")
app.run(port='5002')
......@@ -11,15 +11,6 @@ import logging
Questo script funziona SOLO con SP aventi Embedded Discovery Service come DS.
"""
def logFile(idp,content):
path = idp+".txt"
f = open(path,'w')
f.write(content)
f.close()
def getIdpListFromUrl():
import certifi
import urllib3
......@@ -40,7 +31,7 @@ def getIdpListFromUrl():
def getIdpListFromFile():
import json
with open('list_eccs_idps-idem.txt') as f:
with open('list_eccs_idps-idem.txt','r',encoding='utf-8') as f:
json_data = json.loads(f.read())
return json_data
......@@ -71,15 +62,15 @@ def checkIdP(sp,idp,logger):
entities_blacklist = ['https://idp.eie.gr/idp/shibboleth','https://gn-vho.grnet.gr/idp/shibboleth','https://wtc.tu-chemnitz.de/shibboleth','https://wtc.tu-chemnitz.de/shibboleth','https://idp.fraunhofer.de/idp/shibboleth','https://login.hs-owl.de/nidp/saml2/metadata','https://idp.dfn-cert.de/idp/shibboleth']
if (idp['entityID'] in entities_blacklist):
logger.info("%s;%s;IdP excluded from checks")
logger.info("%s;%s;IdP excluded from checks" % (idp['entityID'],sp))
driver.close()
driver.quit()
return "Disabled"
return "DISABLED"
if (idp['registrationAuthority'] in federation_blacklist):
logger.info("%s;%s;Federation excluded from checks")
logger.info("%s;%s;Federation excluded from checks" % (idp['entityID'],sp))
driver.close()
driver.quit()
return "Disabled"
return "DISABLED"
# Open SP, select the IDP from the EDS and press 'Enter' to reach the IdP login page to check
try:
......@@ -151,11 +142,25 @@ def getLogger(filename,log_level="DEBUG",path="./"):
return logger
# Return a list of email address for a specific type of contact
def getIdPContacts(idp,contactType):
ctcList = []
for ctcType in idp['contacts']:
if (ctcType == contactType):
for ctc in idp['contacts'][contactType]:
ctcList.append(ctc['emailOrPhone']['EmailAddress'][0])
return ctcList
# MAIN
if __name__=="__main__":
eccs2log = getLogger("logs/eccs2_"+date.today().isoformat()+".log","INFO")
eccs2checksLog = getLogger("logs/eccs2checks_"+date.today().isoformat()+".log","INFO")
day = date.today().isoformat()
eccs2log = getLogger("logs/eccs2_"+day+".log","INFO")
eccs2checksLog = getLogger("logs/eccs2checks_"+day+".log","INFO")
sps = ["https://sp24-test.garr.it/secure", "https://attribute-viewer.aai.switch.ch/eds/"]
......@@ -167,11 +172,47 @@ if __name__=="__main__":
for sp in sps:
result.append(checkIdP(sp,idp,eccs2checksLog))
listTechContacts = getIdPContacts(idp,'technical')
listSuppContacts = getIdPContacts(idp,'support')
strTechContacts = ','.join(listTechContacts)
strSuppContacts = ','.join(listSuppContacts)
# If all checks are 'OK', than the IdP consuming correctly eduGAIN Metadata.
if (result[0] == result[1] == "OK"):
eccs2log.info("IdP '%s' results: OK" % (idp['entityID']))
# 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-status-1;SP-entityID-2;SP-status-2
eccs2log.info("%s;%s;%s;%s;%s;%s;%s;%s;%s;%s" % (
idp['displayname'].split(';')[1].split('==')[0],
idp['entityID'],
idp['registrationAuthority'],
strTechContacts,
strSuppContacts,
'OK',
sps[0],
result[0],
sps[1],
result[1]))
elif (result[0] == result[1] == "DISABLED"):
eccs2log.info("IdP '%s' results: DISABLED" % (idp['entityID']))
eccs2log.info("%s;%s;%s;%s;%s;%s;%s;%s;%s;%s" % (
idp['displayname'].split(';')[1].split('==')[0],
idp['entityID'],
idp['registrationAuthority'],
strTechContacts,
strSuppContacts,
'DISABLE',
sps[0],
result[0],
sps[1],
result[1]))
else:
eccs2log.info("IdP '%s' results: ERROR" % (idp['entityID']))
eccs2log.info("%s;%s;%s;%s;%s;%s;%s;%s;%s;%s" % (
idp['displayname'].split(';')[1].split('==')[0],
idp['entityID'],
idp['registrationAuthority'],
strTechContacts,
strSuppContacts,
'ERROR',
sps[0],
result[0],
sps[1],
result[1]))
This diff is collapsed.
web/details_close.png

686 B

web/details_open.png

709 B

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/1.10.20/js/jquery.dataTables.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.20/css/jquery.dataTables.min.css"/>
<script type="text/javascript" src="script.js"></script>
<link href="style.css" rel="stylesheet" type="text/css" />
<meta charset=utf-8 />
<title>eduGAIN Connectivity Check Service 2</title>
</head>
<body>
<div class="container">
<table id="example" class="display" style="width:100%">
<thead>
<tr>
<th></th>
<th>DisplayName</th>
<th>EntityID</th>
<th>Registration Authority</th>
<th>Technical Contacts</th>
<th>Support Contacts</th>
<th>Date</th>
<th>Status</th>
</tr>
</thead>
</table>
</div>
</body>
</html>
/* Formatting function for row details - modify as you need */
function format ( d ) {
// `d` is the original data object for the row
return '<table cellpadding="5" cellspacing="0" border="0" style="padding-left:50px;">'+
'<tr>'+
'<td>IdP DisplayName:</td>'+
'<td>'+d.displayName+'</td>'+
'<td></td>'+
'</tr>'+
'<tr>'+
'<td>Technical Contacts:</td>'+
'<td>'+d.contacts.technical+'</td>'+
'<td></td>'+
'</tr>'+
'<tr>'+
'<td>SP1:</td>'+
'<td>'+d.sp1.entityID+'</td>'+
'<td>'+d.sp1.status+'</td>'+
'</tr>'+
'<tr>'+
'<td>SP2:</td>'+
'<td>'+d.sp2.entityID+'</td>'+
'<td>'+d.sp2.status+'</td>'+
'</tr>'+
'</table>';
}
$(document).ready(function() {
var table = $('#example').DataTable( {
"ajax": {
"url": "data.json",
"dataSrc": ""
},
"columns": [
{
"className": 'details-control',
"orderable": false,
"data": null,
"defaultContent": ''
},
{
"data": "displayName",
"defaultContent": ''
},
{ "data": "entityID" },
{ "data": "registrationAuthority" },
{
"data": "contacts.technical",
"defaultContent": ''
},
{
"data": "contacts.support",
"defaultContent": ''
},
{ "data": "date" },
{ "data": "status" }
],
"rowCallback": function( row, data, index ) {
if (data.status == "ERROR") {
$('td', row).css('background-color', 'Red');
}
if (data.status == "DISABLE") {
$('td', row).css('background-color', 'Grey');
}
if (data.status == "OK") {
$('td', row).css('background-color', 'Green');
}
},
"order": [[1, 'asc']]
} );
// Add event listener for opening and closing details
$('#example tbody').on('click', 'td.details-control', function () {
var tr = $(this).closest('tr');
var row = table.row( tr );
if ( row.child.isShown() ) {
// This row is already open - close it
row.child.hide();
tr.removeClass('shown');
}
else {
// Open this row
row.child( format(row.data()) ).show();
tr.addClass('shown');
}
} );
} );
td.details-control {
background: url('./details_open.png') no-repeat center center;
cursor: pointer;
}
tr.shown td.details-control {
background: url('./details_close.png') no-repeat center center;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment