Add support for web app unprivileged view

This commit is contained in:
Edward Betts 2024-02-25 09:10:55 +00:00
parent 0ea62afd1f
commit ad38ed9136

View file

@ -2,6 +2,8 @@
import json import json
import typing import typing
import urllib
from dataclasses import dataclass
from datetime import datetime, timedelta from datetime import datetime, timedelta
import flask import flask
@ -9,9 +11,24 @@ import itsdangerous
import werkzeug import werkzeug
from itsdangerous.url_safe import URLSafeTimedSerializer from itsdangerous.url_safe import URLSafeTimedSerializer
import UniAuth
max_age = 60 * 60 * 24 * 90 max_age = 60 * 60 * 24 * 90
@dataclass
class User:
"""User."""
is_authenticated: bool
def get_current_user() -> User:
token = flask.request.cookies.get("auth_token")
is_authenticated = bool(token and verify_auth_token(token))
return UniAuth.auth.User(is_authenticated=is_authenticated)
def generate_secure_token(data: str, salt: str) -> str: def generate_secure_token(data: str, salt: str) -> str:
"""Generate a secure token for the given data.""" """Generate a secure token for the given data."""
serializer = URLSafeTimedSerializer(flask.current_app.config["SECRET_KEY"]) serializer = URLSafeTimedSerializer(flask.current_app.config["SECRET_KEY"])
@ -57,10 +74,15 @@ def require_authentication() -> werkzeug.Response | None:
if flask.request.endpoint == "auth_callback": if flask.request.endpoint == "auth_callback":
return None return None
token = flask.request.cookies.get("auth_token") auth_token = flask.request.cookies.get("auth_token")
if token and verify_auth_token(token): if auth_token and verify_auth_token(auth_token):
return None return None
else:
return redirect_to_login(flask.request.url)
def redirect_to_login(original_url: str) -> werkzeug.Response:
"""Redirect from web app to UniAuth login page."""
callback_url = flask.url_for("auth_callback", _external=True) callback_url = flask.url_for("auth_callback", _external=True)
token_payload = {"original_url": flask.request.url, "callback_url": callback_url} token_payload = {"original_url": flask.request.url, "callback_url": callback_url}
@ -72,6 +94,16 @@ def require_authentication() -> werkzeug.Response | None:
return flask.redirect(redirect_to_uniauth) return flask.redirect(redirect_to_uniauth)
def redirect_to_logout(next_url: str) -> werkzeug.Response:
"""Redirect from web app to UniAuth logout page."""
# Construct the redirect URL with the original URL as a parameter
redirect_url = flask.current_app.config["UNIAUTH_URL"] + "/logout"
redirect_to_uniauth = redirect_url + "?next=" + urllib.parse.quote(next_url)
response = flask.redirect(redirect_to_uniauth)
response.set_cookie("auth_token", "", httponly=True, secure=True)
return response
def auth_callback() -> tuple[str, int] | werkzeug.Response: def auth_callback() -> tuple[str, int] | werkzeug.Response:
"""Process the authentication callback.""" """Process the authentication callback."""
auth_token = flask.request.args.get("auth_token") auth_token = flask.request.args.get("auth_token")