Skip to content

Commit

Permalink
Merge pull request #13 from maricaantonacci/devel
Browse files Browse the repository at this point in the history
Updating dependencies for CVE-2019-14806
Handling token expiration
  • Loading branch information
maricaantonacci authored Sep 19, 2019
2 parents eb4830f + 28b261a commit 1d53a2d
Show file tree
Hide file tree
Showing 13 changed files with 204 additions and 157 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ git clone https://github.com/maricaantonacci/orchestrator-dashboard.git
cd orchestrator-dashboard
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
pip3 install -r requirements.txt
```

Start the dashboard app:
Expand Down
5 changes: 3 additions & 2 deletions app/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

app = Flask(__name__)
app.wsgi_app = ProxyFix(app.wsgi_app)
app.secret_key="this.is.my.secretkey"
app.secret_key="30bb7cf2-1fef-4d26-83f0-8096b6dcc7a3"
app.config.from_json('config.json')

iam_base_url=app.config['IAM_BASE_URL']
Expand All @@ -19,6 +19,7 @@
"iam", __name__,
client_id=app.config['IAM_CLIENT_ID'],
client_secret=app.config['IAM_CLIENT_SECRET'],
scope='openid email profile offline_access',
base_url=iam_base_url,
token_url=iam_token_url,
auto_refresh_url=iam_refresh_url,
Expand All @@ -27,7 +28,7 @@
)
app.register_blueprint(iam_blueprint, url_prefix="/login")

from app import routes
from app import routes, errors

if __name__ == "__main__":
app.run(host='0.0.0.0')
Expand Down
3 changes: 2 additions & 1 deletion app/config-sample.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@
"ORCHESTRATOR_URL": "https://indigo-paas.cloud.ba.infn.it/orchestrator",
"SLAM_URL": "https://indigo-slam.cloud.ba.infn.it:8443",
"CMDB_URL": "https://indigo-paas.cloud.ba.infn.it/cmdb",
"TOSCA_TEMPLATES_DIR": "/opt/tosca-templates"
"TOSCA_TEMPLATES_DIR": "/opt/tosca-templates",
"SUPPORT_EMAIL": "[email protected]"
}
13 changes: 13 additions & 0 deletions app/errors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from flask import render_template, request
from app import app

@app.errorhandler(404)
def page_not_found(error):
app.logger.error('Page not found: %s', (request.path))
return render_template('404.html'), 404


@app.errorhandler(500)
def internal_server_error(error):
app.logger.error('Server Error: %s', (error))
return render_template('500.html', support_email=app.config.get('SUPPORT_EMAIL')), 500
178 changes: 62 additions & 116 deletions app/routes.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
from app import app, iam_blueprint, iam_base_url
from app import app, iam_blueprint, iam_base_url, sla as sla
from flask import json, current_app, render_template, request, redirect, url_for, flash, session
import requests, json
import yaml
import io, os, sys
from fnmatch import fnmatch
from hashlib import md5
from functools import wraps


def to_pretty_json(value):
Expand All @@ -21,6 +22,7 @@ def avatar(email, size):

toscaDir = app.config.get('TOSCA_TEMPLATES_DIR') + "/"
tosca_pars_dir = app.config.get('TOSCA_PARAMETERS_DIR')
orchestratorUrl = app.config.get('ORCHESTRATOR_URL')

toscaTemplates = []
for path, subdirs, files in os.walk(toscaDir):
Expand All @@ -34,7 +36,7 @@ def avatar(email, size):
toscaInfo = {}
for tosca in toscaTemplates:
with io.open( toscaDir + tosca) as stream:
template = yaml.load(stream)
template = yaml.full_load(stream)

toscaInfo[tosca] = {
"valid": True,
Expand Down Expand Up @@ -78,83 +80,53 @@ def avatar(email, size):
tosca_pars_file = os.path.join(fpath, fname)
with io.open(tosca_pars_file) as pars_file:
toscaInfo[tosca]['enable_config_form'] = True
pars_data = yaml.load(pars_file)
pars_data = yaml.full_load(pars_file)
toscaInfo[tosca]['inputs'] = pars_data["inputs"]
if "tabs" in pars_data:
toscaInfo[tosca]['tabs'] = pars_data["tabs"]


app.logger.debug("Extracted TOSCA INFO: " + json.dumps(toscaInfo))

orchestratorUrl = app.config.get('ORCHESTRATOR_URL')
slamUrl = app.config.get('SLAM_URL')
cmdbUrl = app.config.get('CMDB_URL')
slam_cert = app.config.get('SLAM_CERT')

def authorized_with_valid_token(f):
@wraps(f)
def decorated_function(*args, **kwargs):


if not iam_blueprint.session.authorized or 'username' not in session:
return redirect(url_for('login'))

if iam_blueprint.session.token['expires_in'] < 20:
app.logger.debug("Force refresh token")
iam_blueprint.session.get('/userinfo')

return f(*args, **kwargs)

return decorated_function

@app.route('/settings')
@authorized_with_valid_token
def show_settings():
if not iam_blueprint.session.authorized:
return redirect(url_for('login'))
return render_template('settings.html', orchestrator_url=orchestratorUrl, iam_url=iam_base_url)

@app.route('/login')
def login():
session.clear()
return render_template('home.html')


def get_sla_extra_info(access_token, service_id):
headers = {'Authorization': 'bearer %s' % (access_token)}
url = cmdbUrl + "/service/id/" + service_id
response = requests.get(url, headers=headers, timeout=20)
response.raise_for_status()
app.logger.info(json.dumps(response.json()['data']['service_type']))

service_type=response.json()['data']['service_type']
sitename=response.json()['data']['sitename']
if 'properties' in response.json()['data']:
if 'gpu_support' in response.json()['data']['properties']:
service_type = service_type + " (gpu_support: " + str(response.json()['data']['properties']['gpu_support']) + ")"

return sitename, service_type

def get_slas(access_token):

headers = {'Authorization': 'bearer %s' % (access_token)}

url = slamUrl + "/rest/slam/preferences/" + session['organisation_name']
verify = True
if slam_cert:
verify = slam_cert
response = requests.get(url, headers=headers, timeout=20, verify=verify)
app.logger.info("SLA response status: " + str(response.status_code))

response.raise_for_status()
app.logger.info("SLA response: " + json.dumps(response.json()))
slas = response.json()['sla']

for i in range(len(slas)):
sitename, service_type = get_sla_extra_info(access_token,slas[i]['services'][0]['service_id'])
slas[i]['service_type']=service_type
slas[i]['sitename']=sitename

return slas

@app.route('/slas')
@authorized_with_valid_token
def getslas():

if not iam_blueprint.session.authorized:
return redirect(url_for('login'))

slas={}

try:
access_token = iam_blueprint.token['access_token']
slas = get_slas(access_token)
slas = sla.get_slas(access_token)

except Exception as e:
flash("Error retrieving SLAs list: \n" + str(e), 'warning')
return redirect(url_for('home'))

return render_template('sla.html', slas=slas)

Expand All @@ -163,29 +135,24 @@ def getslas():
def home():
if not iam_blueprint.session.authorized:
return redirect(url_for('login'))
try:
account_info = iam_blueprint.session.get("/userinfo")

account_info = iam_blueprint.session.get("/userinfo")

if account_info.ok:
account_info_json = account_info.json()
session['username'] = account_info_json['name']
session['gravatar'] = avatar(account_info_json['email'], 26)
session['organisation_name'] = account_info_json['organisation_name']
access_token = iam_blueprint.token['access_token']
if account_info.ok:
account_info_json = account_info.json()
session['username'] = account_info_json['name']
session['gravatar'] = avatar(account_info_json['email'], 26)
session['organisation_name'] = account_info_json['organisation_name']
access_token = iam_blueprint.token['access_token']

return render_template('portfolio.html', templates=toscaInfo)
return render_template('portfolio.html', templates=toscaInfo)

except Exception as e:
app.logger.error("Error: " + str(e))
return redirect(url_for('logout'))

@app.route('/deployments')
@authorized_with_valid_token
def showdeployments():

if not iam_blueprint.session.authorized:
return redirect(url_for('login'))
try:
access_token = iam_blueprint.token['access_token']
access_token = iam_blueprint.session.token['access_token']

headers = {'Authorization': 'bearer %s' % (access_token)}

Expand All @@ -199,17 +166,13 @@ def showdeployments():
deployments = response.json()["content"]
app.logger.debug("Deployments: " + str(deployments))
return render_template('deployments.html', deployments=deployments)
except Exception as e:
app.logger.error("Error: " + str(e))
return redirect(url_for('logout'))



@app.route('/template/<depid>')
@authorized_with_valid_token
def deptemplate(depid=None):

if not iam_blueprint.session.authorized:
return redirect(url_for('login'))

access_token = iam_blueprint.session.token['access_token']
headers = {'Authorization': 'bearer %s' % (access_token)}

Expand All @@ -224,11 +187,9 @@ def deptemplate(depid=None):
return render_template('deptemplate.html', template=template)
#
@app.route('/delete/<depid>')
@authorized_with_valid_token
def depdel(depid=None):

if not iam_blueprint.session.authorized:
return redirect(url_for('login'))

access_token = iam_blueprint.session.token['access_token']
headers = {'Authorization': 'bearer %s' % (access_token)}
url = orchestratorUrl + "/deployments/" + depid
Expand All @@ -241,22 +202,14 @@ def depdel(depid=None):


@app.route('/configure')
@authorized_with_valid_token
def configure():
if not iam_blueprint.session.authorized:
return redirect(url_for('login'))

access_token = iam_blueprint.session.token['access_token']



selected_tosca = request.args['selected_tosca']

try:
slas = get_slas(access_token)

except Exception as e:
flash("Error retrieving SLAs list: \n" + str(e), 'warning')
return redirect(url_for('home'))
slas = sla.get_slas(access_token)

return render_template('createdep.html',
template=toscaInfo[selected_tosca],
Expand All @@ -269,60 +222,53 @@ def add_sla_to_template(template, sla_id):

template['topology_template']['policies'] = [
{"deploy_on_specific_site": {"type": "tosca.policies.Placement", "properties": {"sla_id": sla_id}}}]
app.logger.info(yaml.dump(template, default_flow_style=False))
app.logger.debug(yaml.dump(template, default_flow_style=False))

return template
#
#
@app.route('/submit', methods=['POST'])
@authorized_with_valid_token
def createdep():

if not iam_blueprint.session.authorized:
return redirect(url_for('login'))

access_token = iam_blueprint.session.token['access_token']

app.logger.debug("Form data: " + json.dumps(request.form.to_dict()))

try:
with io.open( toscaDir + request.args.get('template')) as stream:
template = yaml.load(stream)
with io.open( toscaDir + request.args.get('template')) as stream:
template = yaml.full_load(stream)

form_data = request.form.to_dict()
params={}
if 'extra_opts.keepLastAttempt' in form_data:
params['keepLastAttempt'] = 'true'
else:
params['keepLastAttempt'] = 'false'
form_data = request.form.to_dict()

params={}
if 'extra_opts.keepLastAttempt' in form_data:
params['keepLastAttempt'] = 'true'
else:
params['keepLastAttempt'] = 'false'

if form_data['extra_opts.schedtype'] == "man":
template = add_sla_to_template(template, form_data['extra_opts.selectedSLA'])
if form_data['extra_opts.schedtype'] == "man":
template = add_sla_to_template(template, form_data['extra_opts.selectedSLA'])

inputs = { k:v for (k,v) in form_data.items() if not k.startswith("extra_opts.") }
inputs = { k:v for (k,v) in form_data.items() if not k.startswith("extra_opts.") }

app.logger.debug("Parameters: " + json.dumps(inputs))
app.logger.debug("Parameters: " + json.dumps(inputs))

payload = { "template" : yaml.dump(template,default_flow_style=False, sort_keys=False), "parameters": inputs }
payload = { "template" : yaml.dump(template,default_flow_style=False, sort_keys=False), "parameters": inputs }


url = orchestratorUrl + "/deployments/"
headers = {'Content-Type': 'application/json', 'Authorization': 'bearer %s' % (access_token)}
response = requests.post(url, json=payload, params=params, headers=headers)
url = orchestratorUrl + "/deployments/"
headers = {'Content-Type': 'application/json', 'Authorization': 'bearer %s' % (access_token)}
response = requests.post(url, json=payload, params=params, headers=headers)

if not response.ok:
flash("Error submitting deployment: \n" + response.text)
if not response.ok:
flash("Error submitting deployment: \n" + response.text)

return redirect(url_for('showdeployments'))
return redirect(url_for('showdeployments'))

except Exception as e:
flash("Error submitting deployment:" + str(e) + ". Please retry")
return redirect(url_for('home'))


@app.route('/logout')
def logout():
session.clear()
iam_blueprint.session.get("/logout")
# del iam_blueprint.session.token
return redirect(url_for('login'))
Loading

0 comments on commit 1d53a2d

Please sign in to comment.