#!/usr/bin/env python3 import logging import os from descope import REFRESH_SESSION_TOKEN_NAME, SESSION_TOKEN_NAME, AuthException, DeliveryMethod, DescopeClient from fastapi import Request from fastapi.responses import RedirectResponse from icecream import ic from starlette.middleware.base import BaseHTTPMiddleware import nicegui.globals from nicegui import Client, app, events, ui descope_id = os.environ.get('DESCOPE_ID', '') try: descope_client = DescopeClient(project_id=descope_id) except Exception as error: print("failed to initialize. Error:") print(error) def validate_session(): return # Fetch session token from HTTP Authorization Header session_token = "xxxx" try: jwt_response = descope_client.validate_session(session_token=session_token) print("Successfully validated user session:") print(jwt_response) except Exception: logging.exception("Could not validate user session.") class AuthMiddleware(BaseHTTPMiddleware): """This middleware restricts access to all NiceGUI pages. It redirects the user to the login page if they are not authenticated. """ async def dispatch(self, request: Request, call_next): if not app.storage.user.get('authenticated', False): if request.url.path in nicegui.globals.page_routes.values() and request.url.path not in unrestricted_page_routes: app.storage.user['referrer_path'] = request.url.path # remember where the user wanted to go return RedirectResponse('/login') return await call_next(request) app.add_middleware(AuthMiddleware) unrestricted_page_routes = {'/login'} def verify(token: str): ic() try: jwt_response = descope_client.validate_session(session_token=token) ic(jwt_response) return True except Exception: logging.exception("Could not validate user session.") ui.notify('Wrong username or password', type='negative') return False @ui.page('/login') async def login(client: Client): ui.add_head_html('') ui.add_body_html(''' ''') await client.connected() token = await ui.run_javascript(''' if (sessionToken && !sdk.isJwtExpired(sessionToken)) { return sessionToken; } else { return null; } ''') with ui.card().classes('w-96 mx-auto'): if token and verify(token): app.storage.user['authenticated'] = True ui.open('/') else: ui.add_head_html('') ui.element('descope-wc').props(f'project-id="{descope_id}" flow-id="sign-up-or-in"') \ .on('success', lambda: ui.open('/')) @ui.page('/') def home(): ui.add_body_html(''' ''') ui.label('Welcome!') ui.run(storage_secret='THIS_NEEDS_TO_BE_CHANGED')