Compare commits

...

7 Commits

@ -1,3 +1,5 @@
peewee
quart
quart_session_openid
Quart-Keycloak
uvicorn
redis

@ -1,32 +1,33 @@
import re
import peewee
from quart import session, redirect, url_for
from yellow.factory import openid
from quart import session, redirect, url_for, current_app
from quart_keycloak import Keycloak, KeycloakAuthToken, KeycloakLogoutRequest
from yellow.factory import keycloak
from yellow.models import User
@openid.after_token()
async def handle_user_login(resp: dict):
access_token = resp["access_token"]
openid.verify_token(access_token)
user = await openid.user_info(access_token)
username = user['preferred_username']
uid = user['sub']
@keycloak.after_login()
async def handle_user_login(auth_token: KeycloakAuthToken):
username = auth_token.username
uid = auth_token.sub
if not re.match(r"^[a-zA-Z0-9_\.-]+$", username):
raise Exception("bad username")
try:
user = User.select().where(User.id == uid).get()
except peewee.DoesNotExist:
user = User.select().where(User.username == username).get()
except Exception as ex:
user = None
if not user:
# create new user if it does not exist yet
user = User.create(id=uid, username=username)
current_app.logger.info(f'User {username} not found, creating')
try:
user = User.create(id=uid, username=username)
except Exception as ex:
current_app.logger.debug(f'User {username}, creation error')
raise
# user is now logged in
session['user'] = user.to_json()

@ -4,15 +4,16 @@ from datetime import datetime
import asyncio
from quart import Quart, url_for, jsonify, render_template, session
from quart_session_openid import OpenID
from quart_session import Session
from quart_keycloak import Keycloak, KeycloakAuthToken, KeycloakLogoutRequest
from uvicorn.middleware.proxy_headers import ProxyHeadersMiddleware
import settings
app: Quart = None
peewee = None
cache = None
openid: OpenID = None
keycloak = None
async def _setup_database(app: Quart):
@ -24,8 +25,8 @@ async def _setup_database(app: Quart):
async def _setup_openid(app: Quart):
global openid
openid = OpenID(app, **settings.OPENID_CFG)
global keycloak
keycloak = Keycloak(app, **settings.OPENID_CFG)
from yellow.auth import handle_user_login
@ -53,19 +54,20 @@ async def _setup_error_handlers(app: Quart):
def create_app():
global app
app = Quart(__name__)
if settings.X_FORWARDED:
app.asgi_app = ProxyHeadersMiddleware(app.asgi_app, trusted_hosts=["127.0.0.1", "10.1.0.1"])
app.logger.setLevel(logging.INFO)
app.secret_key = settings.APP_SECRET
@app.context_processor
def template_variables():
global openid
from yellow.models import User
current_user = session.get('user')
if current_user:
current_user = User(**current_user)
now = datetime.now()
return dict(user=current_user, url_login=openid.endpoint_name_login, year=now.year)
return dict(user=current_user, url_login=keycloak.endpoint_name_login, year=now.year)
@app.before_serving
async def startup():

@ -2,7 +2,6 @@ from quart import render_template, request, redirect, url_for, jsonify, Blueprin
import re
from yellow import login_required
from yellow.factory import openid
from yellow.models import User
bp_routes = Blueprint('bp_routes', __name__)
@ -15,7 +14,8 @@ async def root():
@bp_routes.route("/login")
async def login():
return redirect(url_for(openid.endpoint_name_login))
from yellow.factory import keycloak
return redirect(url_for(keycloak.endpoint_name_login))
@bp_routes.route("/logout")

@ -4,7 +4,6 @@
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="refresh" content="3; URL={{url}}">
<title>Such {{code}} error :(</title>
<link rel="stylesheet" href="https://unpkg.com/@picocss/pico@latest/css/pico.min.css">
<link rel="stylesheet" href="../../static/colors.css">

Loading…
Cancel
Save