Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add egicheckin support #32

Open
wants to merge 25 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
5f277c0
Add first support for egi checkin
maricaantonacci Sep 21, 2021
126b5a0
handled egi userinfo
mperniola Sep 22, 2021
38f1b71
handled egi usergroups
mperniola Sep 27, 2021
9211448
fixed logout
mperniola Sep 28, 2021
38bf9e4
fixed user roles
mperniola Sep 28, 2021
2664d54
Add ports request in dep menu
maricaantonacci Oct 3, 2021
0b4cb81
fixed style
mperniola Oct 4, 2021
dcc960e
Add edit in deployment menu
maricaantonacci Oct 4, 2021
753b519
Fix ports field format check
maricaantonacci Oct 4, 2021
49bad8a
Fix invalid feedback message
maricaantonacci Oct 4, 2021
c8e0c9c
fixed style
mperniola Oct 6, 2021
bad24e4
Remove hard-coded info
maricaantonacci Oct 6, 2021
8c3fe1d
Fix css for login modal
maricaantonacci Oct 6, 2021
4c21c5b
Update PyYAML dependency
maricaantonacci Oct 6, 2021
73334b7
Merge upstream changes
maricaantonacci Oct 8, 2021
303f98b
Merge add_ports_request branch
maricaantonacci Oct 16, 2021
27b100b
Improve active group management for portfolio
maricaantonacci Oct 25, 2021
8d03b14
Update dependencies
maricaantonacci Sep 2, 2022
608ab0c
Implement support for new EGI Checkin - Keycloak based
maricaantonacci Sep 2, 2022
be9d427
Add check for invalid token
maricaantonacci Sep 2, 2022
56967ee
Implement workaround for cache bad effects on deployments view
maricaantonacci Sep 7, 2022
bb6feae
Fix metadata and parameters management
maricaantonacci Sep 14, 2022
2d4efb5
Merge improvements/fixes from main
maricaantonacci Sep 14, 2022
02c8d34
Add python_eval func
maricaantonacci Sep 14, 2022
1a0572b
Fix style.css
maricaantonacci Sep 14, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Register a client in IAM with the following properties:
- introspection endpoint enabled

Create the folder `instance` to put the application configuration files:
- (mandatory) `config.json` file (see the [example](app/config-sample.json))
- (mandatory) `config.json` file (see the [example](instance/config-sample.json))
- (optional) `vault-config.json` file (see the [example]() needed to enable the integration with Vault

````
Expand Down
122 changes: 100 additions & 22 deletions app/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,22 @@
import sys
import socket

from flask import Flask
from flask import Flask, session
from flask_alembic import Alembic
from sqlalchemy_utils import database_exists, create_database
from sqlalchemy import Table, Column, String, MetaData
from werkzeug.middleware.proxy_fix import ProxyFix
from flask_dance.consumer import OAuth2ConsumerBlueprint
from flask_mail import Mail
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate, upgrade
from flask_login import LoginManager
from app.lib.ToscaInfo import ToscaInfo
from app.lib.Vault import Vault

from flaat import Flaat
from flask_dance.consumer import oauth_authorized
import logging


# initialize SQLAlchemy
db: SQLAlchemy = SQLAlchemy()

Expand Down Expand Up @@ -57,6 +59,17 @@
if profile is not None and profile != 'default':
app.config.from_object('config.' + profile)

flaat = Flaat()
flaat.set_web_framework('flask')
flaat.set_trusted_OP_list([idp['iss'] for idp in app.config.get('TRUSTED_OIDC_IDP_LIST')])
flaat.set_timeout(20)
flaat.set_client_connect_timeout(20)
flaat.set_iss_config_timeout(20)

from app.lib import indigoiam, egicheckin
from app.lib import dbhelpers
from app.models.User import User


@app.context_processor
def inject_settings():
Expand All @@ -77,7 +90,9 @@ def inject_settings():
require_ssh_pubkey=app.config.get('FEATURE_REQUIRE_USER_SSH_PUBKEY') if app.config.get(
'FEATURE_REQUIRE_USER_SSH_PUBKEY') else "no",
hidden_deployment_columns=app.config.get('FEATURE_HIDDEN_DEPLOYMENT_COLUMNS') if app.config.get(
'FEATURE_HIDDEN_DEPLOYMENT_COLUMNS') else ""
'FEATURE_HIDDEN_DEPLOYMENT_COLUMNS') else "",
enable_ports_request=app.config.get('FEATURE_PORTS_REQUEST') if app.config.get(
'FEATURE_PORTS_REQUEST') else "no"
)


Expand All @@ -94,22 +109,87 @@ def inject_settings():
from app.errors.routes import errors_bp
app.register_blueprint(errors_bp)

iam_base_url = app.config['IAM_BASE_URL']
iam_token_url = iam_base_url + '/token'
iam_refresh_url = iam_base_url + '/token'
iam_authorization_url = iam_base_url + '/authorize'

iam_blueprint = OAuth2ConsumerBlueprint(
"iam", __name__,
client_id=app.config['IAM_CLIENT_ID'],
client_secret=app.config['IAM_CLIENT_SECRET'],
base_url=iam_base_url,
token_url=iam_token_url,
auto_refresh_url=iam_refresh_url,
authorization_url=iam_authorization_url,
redirect_to='home'
)
app.register_blueprint(iam_blueprint, url_prefix="/login")

def get_auth_blueprint(self):
if 'auth_blueprint' in session.keys():
bp = session['auth_blueprint']
if bp == 'iam':
return app.iam_blueprint
if bp == 'egi':
return app.egicheckin_blueprint
return None


app.get_auth_blueprint = get_auth_blueprint.__get__('')


def get_auth_userinfo(self):
if 'auth_blueprint' in session.keys():
bp = session['auth_blueprint']
if bp == 'iam':
return app.iam_blueprint.session.get("/userinfo")
if bp == 'egi':
return app.egicheckin_blueprint.session.get('/auth/realms/egi/protocol/openid-connect/userinfo')
return None


app.get_auth_userinfo = get_auth_userinfo.__get__('')


def get_user_oauth(self):
userid = session['userid']
if userid is not None:
user = dbhelpers.get_user(userid)
if user is not None and 'auth_blueprint' in session.keys():
bp = session['auth_blueprint']
if bp == 'iam':
return user.oauth['iam']
if bp == 'egi':
return user.oauth['egiaai']
return None


app.get_user_oauth = get_user_oauth.__get__('')


with app.app_context():
app.iam_blueprint = indigoiam.create_blueprint()
app.register_blueprint(app.iam_blueprint, url_prefix="/login")

# create/login local user on successful OAuth login
@oauth_authorized.connect_via(app.iam_blueprint)
def iam_logged_in(blueprint, token):
session['auth_blueprint'] = 'iam'
return indigoiam.auth_blueprint_login(blueprint, token)


if app.config.get('EGI_AAI_CLIENT_ID') and app.config.get('EGI_AAI_CLIENT_SECRET'):
app.egicheckin_blueprint = egicheckin.create_blueprint()
app.register_blueprint(app.egicheckin_blueprint, url_prefix="/login")

@oauth_authorized.connect_via(app.egicheckin_blueprint)
def egicheckin_logged_in(blueprint, token):
session['auth_blueprint'] = 'egi'
return egicheckin.auth_blueprint_login(blueprint, token)

# Inject the variable inject_egi_aai_enabled automatically into the context of templates
@app.context_processor
def inject_egi_aai_enabled():
return dict(is_egi_aai_enabled=True)


login_manager = LoginManager()
login_manager.login_message = None
login_manager.login_message_category = "info"
login_manager.login_view = "login"

login_manager.init_app(app)


@login_manager.user_loader
def load_user(user_id):
return dbhelpers.get_user(user_id)


from app.home.routes import home_bp
app.register_blueprint(home_bp, url_prefix="/home")
Expand Down Expand Up @@ -138,8 +218,6 @@ def inject_settings():

logging.basicConfig(level=numeric_level)

from app import models

# check if database exists
engine = db.get_engine(app)
if not database_exists(engine.url): # Checks for the first time
Expand Down
18 changes: 0 additions & 18 deletions app/config-sample.json

This file was deleted.

Loading