Commit d958a2af authored by Marco Malavolti's avatar Marco Malavolti
Browse files

Enriched API and fixed eccs2 selenium

parent 0171f5bd
# HOWTO Install and Configure ECCS-2
* `sudo apt install mysql-server python3-pip`
* `pip3 install mysql-connector certifi selenium urllib3`
* `sudo apt install python3-pip chromium chromium-l10n git`
* `pip3 install certifi selenium urllib3 flask flask-jsonpify flask-restful`
* `cd /opt ; git clone https://github.com/malavolti/eccs2.git`
* `cd /opt/eccs2 ; ./eccs2.py`
# Create and configure the ECCS-2 database
# Create and configure the ECCS-2 database (not used now)
* `sudo mysql`
* `CREATE DATABASE eccs2db;`
* `CREATE USER 'eccs2user'@'localhost' IDENTIFIED BY '<password>';`
......@@ -11,3 +13,20 @@
* `SHOW GRANTS FOR 'eccs2user'@'localhost';`
* `FLUSH PRIVILEGES;`
# API
* `/eccs/test` (Trivial Test)
* `/eccs/checks` (Should 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`
* `status=`
* 'OK'
* 'TIMEOUT'
* 'No-eduGAIN-Metadata'
* 'Form-Invalid'
* 'Excluded'
# API Development Server
* `cd /opt/eccs2 ; ./api.py`
......@@ -2,11 +2,12 @@
from flask import Flask, request
from flask_restful import Resource, Api
from json import dumps
from json import dumps, loads
from flask import jsonify
from pathlib import PurePath
import logging
from logging.handlers import RotatingFileHandler
import re
app = Flask(__name__)
api = Api(app)
......@@ -43,56 +44,81 @@ class Test(Resource):
app.logger.info("Test Superato!")
return {'test':'It Works!'}
class AllChecks(Resource):
class Checks(Resource):
def get(self):
app.logger.info("Richiesta 'AllChecks'")
app.logger.info("Richiesta 'Checks'")
file_path = "logs/eccs2checks_2020-02-19.log"
fo = open(file_path, "r")
result = []
date = PurePath(file_path).parts[-1].split('_')[1].split('.')[0]
lines = fo.readlines()
pretty = 0
status = None
idp = None
if 'date' in request.args:
app.logger.info("Parametro 'date' inserito")
file_path = "logs/eccs2checks_"+request.args['date']+".log"
date = request.args['date']
if 'pretty' in request.args:
app.logger.info("Parametro 'pretty' inserito")
pretty = request.args['pretty']
if 'status' in request.args:
app.logger.info("Parametro 'status' inserito")
status = request.args['status']
if 'idp' in request.args:
app.logger.info("Parametro 'idp' inserito")
idp = request.args['idp']
app.logger.info(idp)
for line in lines:
check = line.split(";")
idp = check[0]
sp = check[1]
check_result = check[2]
result.append( { 'sp' : sp,
'idp' : idp,
'check_result' : check_result.rstrip("\n\r"),
'date': date
} )
return jsonify(result)
class ChecksByStatus(Resource):
def get(self,status):
file_path = "logs/eccs2checks_2020-02-19.log"
fo = open(file_path, "r")
result = []
date = PurePath(file_path).parts[-1].split('_')[1].split('.')[0]
lines = fo.readlines()
for line in lines:
check_status = line.split(';')[2].rstrip("\n\r")
if (status == check_status):
check = line.split(";")
idp = check[0]
sp = check[1]
check_result = check[2]
result.append( { 'sp' : sp,
'idp' : idp,
'check_result' : check_result.rstrip("\n\r"),
check = line.split(";")
check_idp = check[0]
check_sp = check[1]
check_status = check[2].rstrip("\n\r")
if (idp and status):
if (idp == check_idp and status == check_status):
result.append( { 'sp' : check_sp,
'idp' : check_idp,
'status' : check_status,
'date': date
} )
elif (idp):
#app.logger.info(re.search(".*."+idp+".*.", check_idp, re.IGNORECASE))
#app.logger.info(check_idp))
if (re.search(".*."+idp+".*.", check_idp, re.IGNORECASE)):
result.append( { 'sp' : check_sp,
'idp' : check_idp,
'status' : check_status,
'date': date
} )
elif (status):
if (status == check_status):
result.append( { 'sp' : check_sp,
'idp' : check_idp,
'status' : check_status,
'date': date
} )
else:
result.append( { 'sp' : check_sp,
'idp' : check_idp,
'status' : check_status,
'date': date
} )
return jsonify(result)
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(AllChecks, '/eccs/checks/all') # Route_2
api.add_resource(ChecksByStatus, '/eccs/checks/<status>') # Route_3
api.add_resource(Checks, '/eccs/checks') # Route_2
if __name__ == '__main__':
......
......@@ -43,15 +43,17 @@ def getIdPs():
idp_list = []
for idp in idp_dict:
idp_list.append(idp['entityID'])
idp_list.append(idp['displayname'].split(';')[1].split('==')[0])
return idp_list
def checkIdP(driver,sp,idp,logger):
def checkIdP(sp,idp,logger):
import re
# Apro la URL contenente il Discovery Service, inserisco l'idp e vado alla pagina di login
driver = setup()
# Open SP, select the IDP from the EDS and press 'Enter' to reach the IdP login page to check
try:
driver.get(sp)
driver.find_element_by_id("idpSelectInput").send_keys(idp + Keys.ENTER)
......@@ -63,6 +65,7 @@ def checkIdP(driver,sp,idp,logger):
pass
except TimeoutException as e:
logger.info("%s;%s;TIMEOUT" % (idp,sp))
driver.close()
return "TIMEOUT"
pattern_metadata = "Unable.to.locate(\sissuer.in|).metadata(\sfor|)|no.metadata.found|profile.is.not.configured.for.relying.party|Cannot.locate.entity|fail.to.load.unknown.provider|does.not.recognise.the.service|unable.to.load.provider|Nous.n'avons.pas.pu.(charg|charger).le.fournisseur.de service|Metadata.not.found|application.you.have.accessed.is.not.registered.for.use.with.this.service|Message.did.not.meet.security.requirements"
......@@ -76,29 +79,34 @@ def checkIdP(driver,sp,idp,logger):
if(metadata_not_found):
logger.info("%s;%s;No-eduGAIN-Metadata" % (idp,sp))
driver.close()
return "No-eduGAIN-Metadata"
elif not username_found and not password_found:
logger.info("%s;%s;Invalid-Form" % (idp,sp))
driver.close()
return "Invalid Form"
else:
logger.info("%s;%s;OK" % (idp,sp))
driver.close()
return "OK"
# Setup Chromium Webdriver
def setup():
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--no-sandbox')
driver = webdriver.Chrome('chromedriver', chrome_options=chrome_options, service_args=['--verbose', '--log-path=./selenium_chromedriver.log'])
# driver = webdriver.Chrome('chromedriver', chrome_options=chrome_options, service_args=['--verbose', '--log-path=./selenium_chromedriver.log'])
driver = webdriver.Chrome('chromedriver', chrome_options=chrome_options)
# Configuro i timeout
# Configure timeouts
driver.set_page_load_timeout(45)
driver.set_script_timeout(45)
return driver
# Use logger to produce files consumed by ECCS-2
# Use logger to produce files consumed by ECCS-2 API
def getLogger(filename,log_level="DEBUG",path="./"):
logger = logging.getLogger(filename)
......@@ -126,35 +134,37 @@ def getLogger(filename,log_level="DEBUG",path="./"):
return logger
# MAIN
if __name__=="__main__":
eccs2log = getLogger("logs/eccs2_"+date.today().isoformat()+".log","INFO")
eccs2checksLog = getLogger("logs/eccs2checks_"+date.today().isoformat()+".log","INFO")
driver = setup()
sps = ["https://sp24-test.garr.it/secure", "https://attribute-viewer.aai.switch.ch/eds/"]
listIdPs = [
'https://garr-idp-prod.irccs.garr.it',
'https://idp.hec.gov.pk/idp/shibboleth',
'https://login.itsak.gr/idp/shibboleth',
'https://idp.eastdurham.ac.uk/openathens',
'https://idp-lib.nwafu.edu.cn/idp/shibboleth',
]
#listIdPs = getIdPs()
# listIdPsTest = [
# 'University of Utah',
# 'Nanjing Agriculture University',
# 'Fujian Normal University',
# 'SUIBE',
# 'Zuyd Hogeschool',
# 'Sur University College',
# 'https://idp.hec.gov.pk/idp/shibboleth',
# 'https://login.itsak.gr/idp/shibboleth',
# 'https://idp.eastdurham.ac.uk/openathens',
# 'https://idp-lib.nwafu.edu.cn/idp/shibboleth',
# ]
listIdPs = getIdPs()
for idp in listIdPs:
result = []
for sp in sps:
result.append(checkIdP(driver,sp,idp,eccs2checksLog))
result.append(checkIdP(sp,idp,eccs2checksLog))
# se tutti e 2 i check sono andati bene, allora l'IdP è OK, altrimenti no.
# If all checks are 'OK', than the IdP consuming correctly eduGAIN Metadata.
if (result[0] == result[1] == "OK"):
eccs2log.info("IdP '%s' results into: OK" % (idp))
else:
eccs2log.info("IdP '%s' results into: NOT OK" % (idp))
driver.close()
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment