94 lines
2.8 KiB
Python
94 lines
2.8 KiB
Python
# Copyright (c) 2019. Tobias Kurze
|
||
"""
|
||
OIDC login auth module
|
||
"""
|
||
from datetime import datetime
|
||
|
||
import flask
|
||
from flask import jsonify, redirect, url_for
|
||
from flask_login import login_user
|
||
from flask_pyoidc.flask_pyoidc import OIDCAuthentication
|
||
from flask_pyoidc.user_session import UserSession
|
||
|
||
from backend import app, db
|
||
from backend.models.user_model import User
|
||
from . import auth_bp
|
||
from .oidc_config import PROVIDER_NAME, OIDC_PROVIDERS
|
||
|
||
OIDCAuthentication.oidc_auth_orig = OIDCAuthentication.oidc_auth
|
||
OIDCAuthentication.oidc_logout_orig = OIDCAuthentication.oidc_logout
|
||
|
||
'''
|
||
def oidc_auth_default_provider(self):
|
||
"""monkey patch oidc_auth"""
|
||
return self.oidc_auth_orig(PROVIDER_NAME)
|
||
|
||
|
||
def oidc_logout_default_provider(self):
|
||
"""monkey patch oidc_logout"""
|
||
return self.oidc_logout_orig(PROVIDER_NAME)
|
||
|
||
|
||
OIDCAuthentication.oidc_auth = oidc_auth_default_provider
|
||
OIDCAuthentication.oidc_logout = oidc_logout_default_provider
|
||
'''
|
||
|
||
oidc_auth = OIDCAuthentication(OIDC_PROVIDERS)
|
||
|
||
|
||
def create_or_retrieve_user_from_userinfo(userinfo):
|
||
"""Updates and returns ar creates a user from userinfo (part of OIDC token)."""
|
||
try:
|
||
email = userinfo["email"]
|
||
except KeyError:
|
||
app.logger.error("email is missing in OIDC userinfo! Can't create user!")
|
||
return None
|
||
user = User.get_by_identifier(email)
|
||
|
||
if user is not None:
|
||
app.logger.info("user found")
|
||
app.logger.debug(f"user found: {email}")
|
||
user.last_seen = datetime.utcnow()
|
||
# TODO: update user!
|
||
db.session.commit()
|
||
return user
|
||
|
||
user = User(email=email, first_name=userinfo.get("given_name", ""),
|
||
last_name=userinfo.get("family_name", ""))
|
||
|
||
app.logger.info(f"creating new user: {email}")
|
||
|
||
db.session.add(user)
|
||
db.session.commit()
|
||
return user
|
||
|
||
|
||
@auth_bp.route('/oidc', methods=['GET'])
|
||
@oidc_auth.oidc_auth(provider_name=PROVIDER_NAME)
|
||
def oidc():
|
||
user_session = UserSession(flask.session)
|
||
app.logger.info(user_session.userinfo)
|
||
user = create_or_retrieve_user_from_userinfo(user_session.userinfo)
|
||
if user is None:
|
||
return ''
|
||
login_user(user)
|
||
app.logger.info(f"logged in user: {str(user)}")
|
||
app.logger.debug(f"id token: {str(user_session.id_token)}")
|
||
return jsonify(id_token=user_session.id_token,
|
||
access_token=flask.session['access_token'],
|
||
userinfo=user_session.userinfo)
|
||
|
||
|
||
@auth_bp.route('/oidc_logout', methods=['GET'])
|
||
@oidc_auth.oidc_logout
|
||
def oidc_logout():
|
||
# oidc_auth.oidc_logout()
|
||
app.logger.debug("Logging out current user!")
|
||
return redirect('/')
|
||
|
||
|
||
@oidc_auth.error_view
|
||
def error(error=None, error_description=None):
|
||
app.logger.error(f"Something wwent wrong with OIDC auth – error: {error}, message: {error_description}")
|
||
return jsonify({'error': error, 'message': error_description})
|